Set Up OpenConnect VPN Server (ocserv) on Ubuntu 20.04 with Let’s Encrypt

This tutorial is going to show you how to run your own VPN server by installing OpenConnect VPN server on Ubuntu 20.04. OpenConnect VPN server, aka ocserv, is an open-source implementation of Cisco AnyConnnect VPN protocol, which is widely used in businesses and universities. AnyConnect is an SSL-based VPN protocol that allows individual users to connect to a remote network.

Note: This tutorial also works on Ubuntu 20.10 and Ubuntu 21.04.

Why Set Up Your Own VPN Server?

  • Maybe you are a VPN service provider or a system administrator, which behooves you to set up our own VPN server.
  • You don’t trust the no-logging policy of VPN service providers, so you go the self-host route.
  • You can use VPN to implement network security policy. For example, if you run your own email server, you can require users to log in only from the IP address of the VPN server by creating an IP address whitelist in the firewall. Thus, your email server is hardened to prevent hacking activities.
  • Perhaps you are just curious to know how VPN server works.

Features of OpenConnect VPN Server

  • Lightweight and fast. In my test, I can watch YouTube 4K videos with OpenConnect VPN. YouTube is blocked in my country (China).
  • Runs on Linux and most BSD servers.
  • Compatible with Cisco AnyConnect client
  • There are OpenConnect client software for Linux, MacOS, Windows and OpenWRT. For Android and iOS, you can use the Cisco AnyConnect Client.
  • Supports password authentication and certificate authentication
  • Supports RADIUS accounting.
  • Supports virtual hosting (multiple domains).
  • Easy to set up
  • Resistant to deep packet inspection (DPI)

I particularly like the fact that compared to other VPN technologies, it is very easy and convenient for the end-user to use OpenConnect VPN. Whenever I install a Linux distro on my computer and want to quickly unblock websites or hide my IP address, I install OpenConnect client and connect to the server with just two lines of commands:

sudo apt install openconnect
 
 sudo openconnect -b vpn.mydomain.com

There is also OpenConnect VPN client for Fedora, RHEL, CentOS, Arch Linux and OpenSUSE. You can easily install it with your package manager.

sudo dnf install openconnect
 sudo yum install openconnect
 sudo pacman -S openconnect

Requirements

To follow this tutorial, you will need a VPS (Virtual Private Server) that can access blocked websites freely (Outside of your country or Internet filtering system). I recommend Kamatera VPS, which features:

  • 30 days free trial.
  • Starts at $4/month (1GB RAM)
  • High-performance KVM-based VPS
  • 9 data centers around the world, including United States, Canada, UK, Germany, The Netherlands, Hong Kong, and Isreal.

Follow the tutorial linked below to create your Linux VPS server at Kamatera.

Once you have a VPS running Ubuntu 20.04, follow the instructions below.

You also need a domain name to enable HTTPS for OpenConnect VPN. I registered my domain name from NameCheap because the price is low and they give whois privacy protection free for life.

Step 1: Install OpenConnect VPN Server on Ubuntu 20.04

Log into your Ubuntu 20.04 server. Then use apt to install the ocserv package from the default Ubuntu repository.

sudo apt update
 sudo apt install ocserv

Once installed, the OpenConnect VPN server is automatically started. You can check its status with:

systemctl status ocserv

Sample output:

 ocserv.service - OpenConnect SSL VPN server
 Loaded: loaded (/lib/systemd/system/ocserv.service; enabled; vendor preset: enabled)
 Active: active (running) since Sun 2020-04-12 19:57:08 HKT; 12s ago
 Docs: man:ocserv(8)
 Main PID: 216409 (ocserv-main)
 Tasks: 2 (limit: 9451)
 Memory: 1.6M
 CGroup: /system.slice/ocserv.service
 ├─216409 ocserv-main
 └─216429 ocserv-sm
 

Hint: If the above command doesn’t quit immediately, you can press the Q key to gain back control of the terminal.

If it’s not running, then you can start it with:

sudo systemctl start ocserv

By default OpenConnect VPN server listens on TCP and UDP port 443. If it’s being used by web server, then the VPN server would probably fail to start. We will see how to change the port in OpenConnect VPN configuration file later.

If there’s a firewall running on your server, then you will need to open port 80 and 443. For example, if you use UFW, then run the following command.

sudo ufw allow 80,443/tcp

Step 2: Install Let’s Encrypt Client (Certbot) on Ubuntu 20.04 Server

The gnutls-bin package installed along with ocserv provides tools to create your own CA and server certificate, but we will obtain and install Let’s Encrypt certificate. The advantage of using Let’s Encrypt certificate is that it’s free, easier to set up and trusted by VPN client software.

Run the following commands to install Let’s Encrypt client (certbot) from the default Ubuntu repository.

sudo apt install certbot

To check the version number, run

certbot --version

Sample output:

certbot 0.40.0

Step 3: Obtain a Trusted TLS Certificate from Let’s Encrypt

I recommend using the standalone or webroot plugin to obtain TLS certificate for ocserv.

Standalone Plugin

If there’s no web server running on your Ubuntu 20.04 server and you want OpenConnect VPN server to use port 443, then you can use the standalone plugin to obtain TLS certificate from Let’s Encrypt. Run the following command. Don’t forget to set A record for your domain name.

sudo certbot certonly --standalone --preferred-challenges http --agree-tos --email [email protected] -d vpn.example.com

Where:

  • certonly: Obtain a certificate but don’t install it.
  • --standalone: Use the standalone plugin to obtain a certificate
  • --preferred-challenges http: Perform http-01 challenge to validate our domain, which will use port 80.
  • --agree-tos: Agree to Let’s Encrypt terms of service.
  • --email: Email address is used for account registration and recovery.
  • -d: Specify your domain name.

As you can see the from the following screenshot, I successfully obtained the certificate.

Using webroot Plugin

If your Ubuntu 20.04 server has a web server listening on port 80 and 443, then it’s a good idea to use the webroot plugin to obtain a certificate because the webroot plugin works with pretty much every web server and we don’t need to install the certificate in the web server.

First, you need to create a virtual host for vpn.example.com.

Apache

If you are using Apache, then

sudo nano /etc/apache2/sites-available/vpn.example.com.conf

And paste the following lines into the file.

<VirtualHost *:80> 
 ServerName vpn.example.com
 
 DocumentRoot /var/www/ocserv
 </VirtualHost>
 

Save and close the file. Then create the web root directory.

sudo mkdir /var/www/ocserv

Set www-data (Apache user) as the owner of the web root.

sudo chown www-data:www-data /var/www/ocserv -R

Enable this virtual host.

sudo a2ensite vpn.example.com

Reload Apache for the changes to take effect.

sudo systemctl reload apache2

Once virtual host is created and enabled, run the following command to obtain Let’s Encrypt certificate using webroot plugin.

sudo certbot certonly --webroot --agree-tos --email [email protected] -d vpn.example.com -w /var/www/ocserv

Nginx

If you are using Nginx, then

sudo nano /etc/nginx/conf.d/vpn.example.com.conf

Paste the following lines into the file.

server {
 listen 80;
 server_name vpn.example.com;
 
 root /var/www/ocserv/;
 
 location ~ /.well-known/acme-challenge {
 allow all;
 }
 }

Save and close the file. Then create the web root directory.

sudo mkdir -p /var/www/ocserv

Set www-data (Nginx user) as the owner of the web root.

sudo chown www-data:www-data /var/www/ocserv -R

Reload Nginx for the changes to take effect.

sudo systemctl reload nginx

Once virtual host is created and enabled, run the following command to obtain Let’s Encrypt certificate using webroot plugin.

sudo certbot certonly --webroot --agree-tos --email [email protected] -d vpn.example.com -w /var/www/ocserv

Step 4: Edit OpenConnect VPN Server Configuration File

Edit ocserv main configuration file.

sudo nano /etc/ocserv/ocserv.conf

First, we need to configure password authentication. By default, password authentication through PAM (Pluggable Authentication Modules) is enabled, which allows you to use Ubuntu system accounts to login from VPN clients. This behavior can be disabled by commenting out the following line.

auth ="pam[gid-min=1000]"

If we want users to use separate VPN accounts instead of system accounts to login, we need to add the following line to enable password authentication with a password file.

auth ="plain[passwd=/etc/ocserv/ocpasswd]"

After finishing editing this config file, we will see how to use ocpasswd tool to generate the /etc/ocserv/ocpasswd file, which contains a list of usernames and encoded passwords.

Note: Ocserv supports client certificate authentication, but Let’s Encrypt does not issue client certificate. You need to set up your own CA to issue client certificate.

Next, if you don’t want ocserv to use TCP and UDP port 443, then find the following two lines and change the port number. Otherwise leave them alone.

tcp-port = 443
 udp-port = 443

Then find the following two lines. We need to change them.

server-cert = /etc/ssl/certs/ssl-cert-snakeoil.pem
 server-key = /etc/ssl/private/ssl-cert-snakeoil.key

Replace the default setting with the path of Let’s Encrypt server certificate and server key file.

server-cert = /etc/letsencrypt/live/vpn.example.com/fullchain.pem
 server-key = /etc/letsencrypt/live/vpn.example.com/privkey.pem

Then, set the maximal number of clients. Default is 128. Set to zero for unlimited.

max-clients = 128

Set the number of devices a user is able to log in from at the same time. Default is 2. Set to zero for unlimited.

max-same-clients = 2

By default, keepalive packets are sent every 300 seconds (5 minutes). I prefer to use a short time (30 seconds) to reduce the chance of VPN connection dropout.

keepalive = 30

Next, find the following line. Change false to true to enable MTU discovery, which can optimize VPN performance.

try-mtu-discovery = false

You can set the time that a client is allowed to stay idle before being disconnected via the following two parameters. If you prefer the client to stay connected indefinitely, then comment out these two parameters.

idle-timeout=1200
 mobile-idle-timeout=1800

After that, set the default domain to vpn.example.com.

default-domain = vpn.example.com

The IPv4 network configuration is as follows by default. This will cause problems because many home routers also set the IPv4 network range to 192.168.1.0/24.

ipv4-network = 192.168.1.0
 ipv4-netmask = 255.255.255.0

We can use another private IP address range (10.10.10.0/24) to avoid IP address collision, so change the value of ipv4-network to

ipv4-network = 10.10.10.0

Now uncomment the following line to tunnel all DNS queries via the VPN.

tunnel-all-dns = true

The default DNS resolver addresses are as follows, which is fine.

dns = 8.8.8.8
 dns = 1.1.1.1

Note: If you are a VPN service provider, then it’s a good practice to run your own DNS resolver on the same server. If there’s a DNS resolver running on the same server, then specify the DNS as

dns = 10.10.10.1

10.10.10.1 is the IP address of OpenConnect VPN server in the VPN LAN. This will speed up DNS lookups a little bit for clients because the network latency between the VPN server and the DNS resolver is eliminated.

Then comment out all the route parameters (add # symbol at the beginning of the following lines), which will set the server as the default gateway for the clients.

#route = 10.0.0.0/8
 #route = 172.16.0.0/12
 #route = 192.168.0.0/16
 #route = fd00::/8
 #route = default
 
 #no-route = 192.168.5.0/255.255.255.0

Save and close the file  Then restart the VPN server for the changes to take effect.

sudo systemctl restart ocserv

Step 5: Create VPN Accounts

Now use the ocpasswd tool to generate VPN accounts.

sudo ocpasswd -c /etc/ocserv/ocpasswd username

You will be asked to set a password for the user and the information will be saved to /etc/ocserv/ocpasswd file. To reset password, simply run the above command again.

Step 6: Enable IP Forwarding

In order for the VPN server to route packets between VPN clients and the Internet, we need to enable IP forwarding by running the following command.

echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/60-custom.conf

Then apply the changes with the below command. The -p option will load sysctl settings from /etc/sysctl.d/60-custom.conf file. This command will preserve our changes across system reboots.

sudo sysctl -p /etc/sysctl.d/60-custom.conf

Step 7: Configure IP Masquerading in Firewall

We need to set up IP masquerading in the server firewall, so that the server becomes a virtual router for VPN clients. I will use UFW, which is a front end to the iptables firewall. Install UFW on Ubuntu with:

sudo apt install ufw

First, you need to allow SSH traffic.

sudo ufw allow 22/tcp

Then find the name of your server’s main network interface.

ip addr

As you can see, it’s named ens3 on my Ubuntu server.

To configure IP masquerading, we have to add iptables command in a UFW configuration file.

sudo nano /etc/ufw/before.rules

By default, there are some rules for the filter table. Add the following lines at the end of this file. Replace ens3 with your own network interface name.

# NAT table rules
 *nat
 :POSTROUTING ACCEPT [0:0]
 -A POSTROUTING -s 10.10.10.0/24 -o ens3 -j MASQUERADE
 
 # End each table with the 'COMMIT' line or these rules won't be processed
 COMMIT
 

In Nano text editor, you can go to the end of the file by pressing Ctrl+W, then pressing Ctrl+V.

The above lines will append (-A) a rule to the end of of POSTROUTING chain of nat table. It will link your virtual private network with the Internet. And also hide your network from the outside world. So the Internet can only see your VPN server’s IP, but can’t see your VPN client’s IP, just like your home router hides your private home network.

By default, UFW forbids packet forwarding. We can allow forwarding for our private network. Find the ufw-before-forward chain in this file and add the following 3 lines, which will accept packet forwarding if the source IP or destination IP is in the 10.10.10.0/24 range.

# allow forwarding for trusted network
 -A ufw-before-forward -s 10.10.10.0/24 -j ACCEPT
 -A ufw-before-forward -d 10.10.10.0/24 -j ACCEPT

Save and close the file. Then enable UFW.

sudo ufw enable

If you have enabled UFW before, then you can use systemctl to restart UFW.

sudo systemctl restart ufw

Now if you list the rules in the POSTROUTING chain of the NAT table by using the following command:

sudo iptables -t nat -L POSTROUTING

You can see the Masquerade rule.

It can take some time for UFW to process the firewall rules. If the masquerade rule doesn’t show up, then restart UFW again (sudo systemctl restart ufw).

Step 8: Open Port 443 in Firewall

Run the following command to open TCP and UDP port 443. If you configured a different port for ocserv, then change 443 to your configured port.

sudo ufw allow 443/tcp
 sudo ufw allow 443/udp

Now OpenConnect VPN server is ready to accept client connections.

If you run a local DNS Resolver

For those of you who run a local DNS resolver, if you specified 10.10.10.1 as the DNS server for VPN clients, then you must allow VPN clients to connect to port 53 with the following UFW rule.

sudo ufw insert 1 allow in from 10.10.10.0/24

You also need to edit the BIND DNS server’s configuration file (/etc/bind/named.conf.options) to allow VPN clients to send recursive DNS queries like below.

allow-recursion { 127.0.0.1; 10.10.10.0/24; };

Then restart BIND.

sudo systemctl restart named

How to Install and Use OpenConnect VPN client on Ubuntu 20.04 Desktop

Run the following command to install OpenConnect VPN command line client on Ubuntu desktop.

sudo apt install openconnect

You can Connect to VPN from the command line like below. -b flag will make it run in the background after connection is established.

sudo openconnect -b vpn.example.com:port-number

You will be asked to enter VPN username and password. If the connection is successfully established, you will see the following message.

Got CONNECT response: HTTP/1.1 200 CONNECTED
 CSTP connected. DPD 90, Keepalive 32400
 Connected tun0 as 192.168.1.139, using SSL
 Established DTLS connection (using GnuTLS). Ciphersuite (DTLS1.2)-(RSA)-(AES-256-GCM).

To stop the connection, run:

sudo pkill openconnect

To run the client non-interactively, use the following syntax.

echo -n password | sudo openconnect -b vpn.example.com -u username --passwd-on-stdin

If you want to use Network Manager to manage VPN connection, then you also need to install these packages.

sudo apt install network-manager-openconnect network-manager-openconnect-gnome

If you are successfully connected to the VPN server, but your public IP address doesn’t change, that’s because IP forwarding or IP masquerading is not working. I once had a typo in my iptables command (using a wrong IP address range), which caused my computer not being able to browse the Internet.

If you encounter the following error, then you should disable the UDP port in ocserv, which is explained later in the speed optimization section.

DTLS handshake failed: Resource temporarily unavailable, try again

If you have the following error, it’s likely that your VPN username or password is wrong.

fgets (stdin): Inappropriate ioctl for device

Auto-Connect on System Startup

To let OpenConnect VPN client automatically connect to the server at boot time, we can create a systemd service unit.

sudo nano /etc/systemd/system/openconnect.service

Put the following lines to the file. Replace the red text.

[Unit]
 Description=OpenConnect VPN Client
 After=network-online.target systemd-resolved.service
 Wants=network-online.target
 
 [Service]
 Type=simple
 ExecStart=/bin/bash -c '/bin/echo -n password | /usr/sbin/openconnect vpn.example.com -u username --passwd-on-stdin'
 KillSignal=SIGINT
 Restart=always
 RestartSec=2
 
 [Install]
 WantedBy=multi-user.target
 

Save and close the file. Then enable this service so that it will start at boot time.

sudo systemctl enable openconnect.service

Explanation of the file content:

  • After=network-online.target systemd-resolved.service and Wants=network-online.target make this service run after network is up. We want the openconnect.service start after the systemd-resolved.service because that will ensure the DNS server address set by OpenConnect won’t be overridden by systemd-resolved.service.
  • In reality, this service can still run before network is up. We add Restart=always and RestartSec=2 to restart this service after 2 seconds if this service fails.
  • Systemd doesn’t recognise pipe redirection, so in the ExecStart directive, we wrap the comand in single quotes and run it with the Bash shell.
  • Since OpenConnect VPN client will run as a systemd service, which runs in the background, there’s no need to add -b flag to the openconnect command.
  • The KillSignal directive tells Systemd to send the SIGINT signal when the systemctl stop openconnect command is issued. This will performs a clean shutdown by logging the session off, and restoring DNS server settings and the Linux kernel routing table.

To start this Systemd service immediately, run

sudo systemctl start openconnect

To stop this Systemd service, run

sudo systemctl stop openconnect

How to Automatically Restart OpenConnect Client When Resuming from Suspend

If your Ubuntu desktop goes into suspend state, the OpenConnect client would lose connection to the VPN server. To make it automatically restart when resuming from suspend, we need to create another systemd service unit.

sudo nano /etc/systemd/system/openconnect-restart.service

Add the following lines in the file.

[Unit]
 Description=Restart OpenConnect client when resuming from suspend
 After=suspend.target
 
 [Service]
 Type=simple
 ExecStart=/bin/systemctl --no-block restart openconnect.service
 
 [Install]
 WantedBy=suspend.target
 

Save and close the file. Then enable this service.

sudo systemctl enable openconnect-restart.service

Automatic-Restart When VPN Connection Drops

Sometimes the VPN connection would drop due to other reasons. You can run the following command to check if the VPN client can ping the VPN server’s private IP address (10.10.10.1). If the ping is unsuccessful, then the command on the right will be executed to restart the VPN client. || is the OR operator in Bash. It executes the command on the right only if the command on the left returned an error.

ping -c9 10.10.10.1 || systemctl restart openconnect

The ping will be done 9 times, i.e 9 seconds. You can use an infinite loop in the Bash shell to make the whole command run forever. Press Ctrl+C to stop it.

for ((; ; )) do (ping -c9 10.10.10.1 || systemctl restart openconnect) done

Now we can create a systemd service for this task.

sudo nano /etc/systemd/system/openconnect-check.service

Add the following lines to this file. We specify that this service should run after the openconnect.service.

[Unit]
 Description=OpenConnect VPN Connectivity Checker
 After=openconnect.service
 
 [Service]
 Type=simple
 ExecStart=/bin/bash -c 'for ((; ; )) do (ping -c9 10.10.10.1 || systemctl restart openconnect) done'
 
 [Install]
 WantedBy=multi-user.target
 

Save and close the file. Then start this service.

sudo systemctl start openconnect-check

Enable auto-start at boot time.

sudo systemctl enable openconnect-check

Once this service is started, the ping command will run forever. If the VPN connection drops, it will automatically restart openconnect.service.

OpenConnect GUI Client for Windows and macOS

They can be downloaded from OpenConnect GUI Github Page.

Speed

OpenConnect VPN is pretty fast. I can use it to watch 4k videos on YouTube. As you can see, my connection speed is 63356 Kbps, which translates to 61 Mbit/s.

And here’s the test results on speedtest.net.

Speed Optimization

OpenConnect by default uses TLS over UDP protocol (DTLS) to achieve faster speed, but UDP can’t provide reliable transmission. TCP is slower than UDP but can provide reliable transmission. One optimization tip I can give you is to disable DTLS, use standard TLS (over TCP), then enable TCP BBR to boost TCP speed.

To disable DTLS, comment out (add # symbol at the beginning) the following line in ocserv configuration file.

udp-port = 443

Save and close the file. Then restart ocserv service.

sudo systemctl restart ocserv.service

To enable TCP BBR, please check out the following tutorial. Note that you need to disable DTLS in ocserv, or TCP BBR won’t work.

In my test, standard TLS with TCP BBR enabled is two times faster than DTLS.

Another very important factor affecting speed is how good the connection between your local computer and the VPN server is. If you live in the middle east and the VPN server is located in the U.S, the speed would be slow. Choose a data center that’s close to where you live.

Also, check your CPU load average. (htop can be installed by sudo apt install htop).

htop

Make sure the CPU load average is under 1. I once had a CPU load average of 3, which caused a high latency between the VPN client and VPN server.

Auto-Renew Let’s Encrypt Certificate

Edit root user’s crontab file.

sudo crontab -e

Add the following line at the end of the file. It’s necessary to reload ocserv service for the VPN server to pick up new certificate and key file.

@daily certbot renew --quiet && systemctl reload ocserv

Troubleshooting Tips

OpenVZ

Note that if you are using OpenVZ VPS, make sure you enable the TUN virtual networking device in VPS control panel. (If you use Vultr VPS, then you have KVM-based VPS, so you don’t have to worry about this.)

Log File

If you encounter any problem, then check OpenConnect VPN server log.

sudo journalctl -eu ocserv.service

I found that if I change port 443 to a different port, the great firewall of China will block this VPN connection.

Debugging Mode

If ocserv tells you that it can’t load the /etc/ocserv/ocserv.conf file, you can stop ocserv.

sudo systemctl stop ocserv

Then run it in the foreground with debugging enabled.

sudo /usr/sbin/ocserv --foreground --pid-file /run/ocserv.pid --config /etc/ocserv/ocserv.conf --debug=10

Then output might give you some clues why ocserv isn’t working.

Can’t browse the Internet

If you are successfully connected to the VPN server, but you can’t browse the Internet, that’s because IP forwarding or IP masquerading is not working. I remember my VPS provider once did a platform upgrade, which changed the name of the main network interface from ens3 to enp3s0, so I had to update the name in the UFW file (/etc/ufw/before.rules).

Syntax Error

If you see the following error when trying to establish VPN connection, it’s probably because there’s a syntax error in your ocserv config file. Check the journal (sudo journalctl -eu ocserv) to find out.

Got inappropriate HTTP CONNECT response: HTTP/1.1 401 Cookie is not acceptable

Restart Your Computer

If you see the following error when trying to establish VPN connection, it’s likely a local computer problem. Try restarting your computer.

Server 'vpn.your-domain.com' requested Basic authentication which is disabled by default

TLS connection was non-properly terminated

If you see the following error on the client when trying to establish a VPN connection,

SSL connection failure: The TLS connection was non-properly terminated.

you probably should restart the ocserv service on the VPN server.

sudo systemctl restart ocserv

You can create a cron job to automatically restart ocserv once per day at 4 AM.

sudo crontab -e

Add the following line.

0 4 * * * systemctl restart ocserv

Save and close the file.

How to Install the Latest Version of ocserv

Check your current ocserv version.

ocserv -v

Sometimes, the latest version of ocserv will fix an issue. You may also want to use a new feature that’s only available in the latest release. Follow the instructions below to install the latest ocserv version.

Install build dependency packages.

sudo apt install -y git ruby-ronn libbsd-dev libsystemd-dev libpcl-dev libwrap0-dev libgnutls28-dev libev-dev libpam0g-dev liblz4-dev libseccomp-dev libreadline-dev libnl-route-3-dev libkrb5-dev libradcli-dev libcurl4-gnutls-dev libcjose-dev libjansson-dev libprotobuf-c-dev libtalloc-dev libhttp-parser-dev protobuf-c-compiler gperf nuttcp lcov libuid-wrapper libpam-wrapper libnss-wrapper libsocket-wrapper gss-ntlmssp haproxy iputils-ping freeradius gawk gnutls-bin iproute2 yajl-tools tcpdump

Clone the ocserv Git repository.

git clone https://gitlab.com/openconnect/ocserv.git

Generate configuration scripts.

cd ocserv
 
 autoreconf -fvi

Compile the source code. If you see deprecated warnings, you can ignore them.

./configure && make

Install the binaries.

sudo make install

The files will be install to /usr/loca/bin/ and /usr/local/sbin/. Next, we need to copy the systemd service file.

sudo cp /lib/systemd/system/ocserv.service /etc/systemd/system/ocserv.service

Edit this file.

sudo nano /etc/systemd/system/ocserv.service

Because the compiled version of ocserv binary is located at /usr/local/sbin/ocserv, we need to change

ExecStart=/usr/sbin/ocserv --foreground --pid-file /run/ocserv.pid --config /etc/ocserv/ocserv.conf

to

ExecStart=/usr/local/sbin/ocserv --foreground --pid-file /run/ocserv.pid --config /etc/ocserv/ocserv.conf

Save and close the file. Then reload systemd.

sudo systemctl daemon-reload

Restart ocserv service.

sudo systemctl restart ocserv

Make OpenConnect VPN server and web server use port 443 at the same time

Please read the following article:

More Useful Tips

Wrapping Up

That’s it! I hope this tutorial helped you install and configure OpenConnect VPN on Ubuntu 20.04. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks 🙂

Rate this tutorial
[Total: 9 Average: 5]

93 Responses to “Set Up OpenConnect VPN Server (ocserv) on Ubuntu 20.04 with Let’s Encrypt

  • Stev
    2 years ago
    Reply

    Everyone, Pls use English instead of Chinese to avoid this site to be blocked by GFW~!!!!!!

  • papino
    2 years ago
    Reply

    Hi, I have successfully connected but got the error message as below:

    Established DTLS connection (using GnuTLS). Ciphersuite (DTLS1.2)-(PSK)-(AES-256-GCM).
     Failed to read from SSL socket: The transmitted packet is too large (EMSGSIZE).
     Failed to recv DPD request (1434)
     Command line is not complete. Try option "help"
     

    How to fix this problem? please help!!

    • Try disabling UDP/DTLS in ocserv. To disable DTLS, comment out (add # symbol at the beginning) the following line in ocserv configuration file.

      udp-port = 443

      Save and close the file. Then restart ocserv service.

      sudo systemctl restart ocserv.service

      To enable TCP BBR, please check out the following tutorial. Note that you need to disable DTLS in ocserv, or TCP BBR won’t work.

      How to Easily boost Ubuntu Network Performance by enabling TCP BBR

      In my test, standard TLS with TCP BBR enabled is faster than DTLS.

  • Merik
    2 years ago
    Reply

    Xiao Guoan
    Hello
    My problem is that after connecting to OpenConnect the speed is lost or does not exceed 0.78mb. How to fix the problem

    • OpenConnect VPN protocol itself is very fast. However, there are other factors that can impact speed, such as the network condition between the VPN client and the VPN server. Always choose a server close to the client as the VPN server.

      You can enable the TCP BBR algorithm to speed up TCP connection speed.

  • visir
    2 years ago
    Reply

    The user is constantly banned, for example, between the transition from 3g to a wi fi network.
    Can you help me find a solution?

  • Marat
    2 years ago
    Reply

    hello,
    did you faced an error like:
    main.c:868: bind UDP to [::]:443: Invalid argument
    … Network is unreachable

    client works fine and can access internet but still see this errors in my logs 🙁

    • Marat
      2 years ago
      Reply

      it seems issue was with udp-port, tried to comment it in config file.

      • Mostafa Ghadimi
        1 year ago
        Reply

        Hi Marat,

        Would you please give more information of how your issue was resolved?
        I have the same issue but I don’t know how to fix it?
        https://askubuntu.com/questions/1325690/ufw-block-error-seen-in-journalctl-xe-command

        Thanks

        • Hi Mostafa,
          To be honest, I don’t remember, try to comment related line in config file 🙂

  • Hello Xiao!

    Great tutorial!
    I have a question. If I have the nginx running in parallel with the vpn and use the haproxy as you explained in the linked tutorial is there a way to make a site from nginx available only to the vpn? What would be needed in the haproxy, nginx and vpn configuration?
    From a newbie perspective I expect something like an client IP forward through haproxy to nginx where nginx decides to deny/accept the connection. And the vpn needs to do something like a split tunnel. But I need to search some more documentation for all of these.
    Any terms that would be helpful in this when I look into the manuals?

    Many thanks!

    • Ok, after working some days on this issue this is what I did. Let me know if there are other things that need to be taken care of besides what I did here.

      I first did the in the /etc/sysctl.conf file

       net.ipv4.ip_nonlocal_bind=1

      In /etc/haproxy/haproxy.cfg
      I added the

      bind 10.10.10.1:443

      to bind the vpn internal ip to the frontend
      In the nginx backaned I added server

      send-proxy-v2

      I created the rpz dns resolver and added in it all the dns entries from the sites that I wanted to be in the “intranet” as stated in this tutorial (/etc/bind/db.rpz.local):
      https://corejumping.com/muzehiki/ubuntu/set-up-response-policy-zone-rpz-in-bind-resolver-on-debian-ubuntu

      In nginx I added the proxy_protocol directive to the listen ssl directive, this is required to get the real ip from haproxy (that is why I modified that configuration file as well):

      listen 127.0.0.1:443 ssl proxy_protocol;

      And to allow and deny ip connections the known lines:

       allow 10.10.10.0/24;
       deny all;
    • If you allow access to all your Nginx virtual hosts to VPN clients only, you can simply make Nginx listen on the VPN interface,

      listen 10.10.10.1:443 ssl

      Check the /etc/nginx/nginx.conf file and the default Nginx virtual host to see the there are listen 443 ssl directives, change them to listen 10.10.10.1:443 ssl. So your Nginx virtual host won’t accept connections from the public Internet. Then use RPZ to make an “intranet” DNS record for the domain.

      You don’t need to change the HAProxy configurations or add allow, deny directives in Nginx.

      • Yeah!

        You’re right. That is simpler than the way I did it. 🙂

  • visir
    2 years ago
    Reply

    Hello, how can I know exactly if my client is connected to my ocserv?
    And see it online.

  • visir
    2 years ago
    Reply

    Help please view the client connection history in ocserv through specific commands

  • visir
    2 years ago
    Reply

    Thank you so much.
    Please tell me how you can make sure AnyConnect does not turn off on mobile.

  • Mysterion
    2 years ago
    Reply

    Great tutorial. Thanks!

  • roam
    2 years ago
    Reply

    Ubuntu 20.10 gives below error , When i checked the file is present there.

    error connecting to sec-mod socket ‘/run/ocserv.socket.83a664e5’: No such file or directory

    ● ocserv.service - OpenConnect SSL VPN server
     Loaded: loaded (/lib/systemd/system/ocserv.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2020-12-04 11:22:49 UTC; 6s ago
     Docs: man:ocserv(8)
     Main PID: 3513 (ocserv-main)
     Tasks: 2 (limit: 8100)
     Memory: 1.6M
     CGroup: /system.slice/ocserv.service
     ├─3513 ocserv-main
     └─3514 ocserv-sm
     
     Dec 04 11:22:49 b2-7-de1-2 ocserv[3513]: note: setting 'pam' as primary authentication method
     Dec 04 11:22:49 b2-7-de1-2 ocserv[3513]: error connecting to sec-mod socket '/run/ocserv.socket.83a664e5': No such file or directory
     Dec 04 11:22:49 b2-7-de1-2 ocserv[3513]: note: setting 'file' as supplemental config option
     Dec 04 11:22:49 b2-7-de1-2 ocserv[3513]: listening (TCP) on 0.0.0.0:443...
     Dec 04 11:22:49 b2-7-de1-2 ocserv[3513]: listening (TCP) on [::]:443...
     Dec 04 11:22:49 b2-7-de1-2 ocserv[3513]: listening (UDP) on 0.0.0.0:443...
     Dec 04 11:22:49 b2-7-de1-2 ocserv[3513]: listening (UDP) on [::]:443...
     Dec 04 11:22:49 b2-7-de1-2 ocserv[3513]: main: initialized ocserv 0.12.6
     Dec 04 11:22:49 b2-7-de1-2 ocserv[3514]: sec-mod: reading supplemental config from files
     Dec 04 11:22:49 b2-7-de1-2 ocserv[3514]: sec-mod: sec-mod initialized (socket: /run/ocserv.socket.83a664e5)
     
    • If you look carefully at the log, it said it can’t find the socket, and next, it initialized this socket. So problem solved, right? 🙂

  • Murat
    1 year ago
    Reply

    how to fix the: transmitted packet is too large (emsgsize) ?

  • Joe
    1 year ago
    Reply

    Hi,

    You said to edit /etc/bind/named.conf.options to allow VPN clients to send recursive DNS queries
    I didn’t find this file on my server, what should I do exactly?

    thanks for your article

  • Ray
    1 year ago
    Reply

    So everything is running fine with IPv4. When enabling ipv6 on the dns. After I add

    allow-recursion { 127.0.0.1; 10.10.10.0/24; fda9:4efe:7e3b:03ea::/48; };

    The DNS for the IPv6 and the IPv4 stop working.

    If I remove fda9:4efe:7e3b:03ea::/48; from the bind9 config the ipv4 dns will start working again. any ideas?

  • Adam
    1 year ago
    Reply

    Hi, I’ve used this guide a few times for ipv4 successfully, but just now found that the ipv6 section seems to be incomplete. In the “Set Up IPv6 in Firewall (Debian, Ubuntu)” section of your other guide here https://corejumping.com/muzehiki/linux-server/ocserv-vpn-server-apache-nginx-haproxy and there is the additional step of adding the two

    -A ufw6-before-forward...

    , which is missing from this guide. Once I added those lines, ipv6 forwarding works properly.

  • Khazhbikar Tsarnaev
    1 year ago
    Reply

    First of all, thank you very much for this valuable article and your beautiful expression. I did everything successfully. However, there is one point that I do not understand or cannot do. Cisco AnyConnect uses TLS 1.2 for some reason. Can’t we force this to use TLS 1.3? All packages on my system have the latest version. Looking forward to your valuable feedback. Good work.

    • Cisco Annyconnect client has some problems when using TLS 1.3. You can force the server to use TLS 1.3, but if the client has a compatibility problem, the VPN would stop working.

      • Khazhbikar Tsarnaev
        1 year ago
        Reply

        Thank you for your valuable reply. Thank you for your valuable reply. OpenConnect’s own client also uses the TLS 1.2 protocol. Either there is a different situation in these applications or I am doing something wrong. I want to understand the issue better. How can I force the system to use TLS 1.3? Even though I edit this on Apache, it doesn’t work. It persistently uses TLS 1.2. By the way, I’m running with TCP only, DTLS is turned off. I wonder if TLS over TCP currently only supports TLS 1.2? What is your opinion on this? I’m curious about your comments.

    • TLS1.3 will be disabled when cisco client compatibility is enabled. See here: ocserv changelog

  • I do exactly as told.
    when I ran iptables -t nat -L POSTROUTING
    The response is :

    Chain POSTROUTING (policy ACCEPT)
     target prot opt source destination
     MASQUERADE all -- 10.10.10.0/24 anywhere
     

    Why did this happen?
    Does this matter?

    • It’s correct. I forgot to update the screenshot

      • Another Question.
        I deployed Open Connect on Ubuntu 20.04 VPS step by step as you showed in this article.
        I can use it on iOS devices smoothly.
        But It is very slow on Windows 10.
        I tried Cisco Anyconnect and OpenConnect-GUI, It is to slow to use. I can connect to the server, everything seems ok. No error happens. But It just toooooooooo slow.

    • The most important factor affecting speed is how good is the connection between your local computer and the VPN server. If you live in the middle east and the VPN server is located in the U.S, the speed would be slow. Choose a data center that’s close to where you live.

      One great way to improve the speed of OpenConnect VPN is disabling UDP port 443 in ocserv and enabling TCP BBR algorithm in the Linux kernel, as I have already said in the “speed optimization” section in this article.

      The OpenConnect VPN protocol is not slow in its own right. If you really think it’s slow, you might want to try the WireGuard VPN protocol, which is the fastest VPN protocol.

      If your speed is still slow when using WireGuard VPN, you should change data center location. Some VPS hosting providers allow you to easily migrate from one data center to another.

      The advantage of OpenConnect VPN is that it’s a HTTPS-based VPN and operates on TCP port 443, so its super hard to block it by a national firewall. WireGuard VPN can be easily identified and blocked. You can see the OpenConnect VPN speed tested on my Windows computer.

      • My Windows 10 PC and iOS devices use the same Wi-Fi. Also, Latest Cisco official Anyconnect client app installed on Windows 10 PC and iOS devices.
        Connection speed on iOS devices is much much much much much faster than Windows’.
        I do not know why and how to fix.

      • Thank U.
        I enabled BBR on my VPS.
        It’s much faster now.

  • 运行systemctl status ocserv的时候,提示信息中有红色的一行
    Jul 04 01:17:40 vultr.guest ocserv[11868]: error connecting to sec-mod socket ‘/run/ocserv.socket.efb2f1d4’: No such file or directory

    这个提示,但貌似不影响使用。
    但OpenConnect一直一般 不知道是不是受这个的影响

    • sudo journalctl -eu ocserv

      后面还有一行.

      sec-mod: sec-mod initialized (socket: /var/run/ocserv-socket.1a0b21e9)

      这个表示 ocserv 开始找不到这个 socket 文件, 所以它就要初始化这个 socket 文件.

      Jul 05 12:18:56 debian ocserv[18677]: error connecting to sec-mod socket '/var/run/ocserv-socket.1a0b21e9': No such file or directory
       Jul 05 12:18:56 debian ocserv[18677]: main: processed 1 CA certificate(s)
       Jul 05 12:18:56 debian ocserv[18677]: note: setting 'file' as supplemental config option
       Jul 05 12:18:56 debian ocserv[18677]: listening (TCP) on [::1]:443...
       Jul 05 12:18:56 debian ocserv[18677]: listening (TCP) on 127.0.0.1:443...
       Jul 05 12:18:56 debian ocserv[18677]: main: initialized ocserv 0.12.2
       Jul 05 12:18:56 debian ocserv[18678]: sec-mod: reading supplemental config from files
       Jul 05 12:18:56 debian ocserv[18678]: sec-mod: reading supplemental config from files
       Jul 05 12:18:56 debian ocserv[18678]: sec-mod: sec-mod initialized (socket: /var/run/ocserv-socket.1a0b21e9)
       

      这是正常的. 要影响的话, 所有客户端都会受到影响.

      • 貌似不影响使用,但是OpenConnect的速度一直一般,不知道是不是受这个影响

    • 其实选对了数据中心,以及内地的宽带运营商,速度不会很慢。
      我用中国移动的100M宽带连新加坡的VPN,下载速度可以达到 72Mbit/s, 上传速度可达 69 Mbit/s。

  • 另外我发现,1号至6号白天,新搭建的OpenConnect服务器,断开重连几次后,就再也连不上了。
    从今天开始,就不会有这种现象。不知道是不是因为特征太明显被强了。

    • 我几乎所有时间都是用OpenConnect, 并没有这种情况。我认为是数据中心的问题。 有些数据中心会受到重点关注。

      我用 nDPI 深度检测包工具测试过,OpenConnect 只会被检测为 TLS 连接,并不能检测到 VPN 协议。

  • 以前用过ikev2的梯子,速度、客户端支持都非常好,对移动设备也格外友好,自动休眠、断开重连也好,耗电也非常少。服务端好像使用strongswan搭建的。
    不知道您对这个是否研究,可否写一篇教程,造福墙内的朋友们。

  • Dylan
    1 year ago
    Reply

    Hello and thank you for the amazing tutorials. I’m having an issue with the IP masquerading. I can connect to my VPN, no problem. Everything checks out ‘ok’ as far as I can tell. My IP does not become the IP of the VPN server. It stays the same.

    When I run sudo iptables -t nat -L POSTROUTING, I get the same results as written in the tutorial. Any way you can help me figure this out? Thank you!

    • Dylan
      1 year ago
      Reply

      Hello again, I figured it out. I had some errors in the config files. I missed the commenting out of the routing parameters.

      You are so thorough and clear with your directions. I think we all love you LinuxBabe. You rock. Thank you again =)

  • Hossein
    1 year ago
    Reply

    Hay Xiao

    Thank you for this awesome and detailed tutorial

    I build an OpenConnect server using your instruction. It works well except for a site that I have on the very same VPS.
    I can access my site only through VPN in my country, but it seems that when OpenConnect VPN and site are on the same server, VPN neglects the site.

    Could you please help me with this?

    • You can create a special DNS record for your VPN users with Response Policy Zone, pointing the site domain to the 10.10.10.1 IP address, so when VPN users visit your site, their traffic will be tunnelled through the VPN. You also need to make the site listen on the 10.10.10.1 interface for both port 80 and 443.

  • 罗海琼
    12 months ago
    Reply

    您的教程,非常详尽,非常感谢。按照您的教程,部署了服务器,用起来一切正常,速度也很快。
    但有一个现象:每次晚上在iOS设备上连着VPN入睡,屏幕常量,软件前台运行,但醒来时Anyconnect一定会断开,重连也能连上。无论使用WiFi还是5G,都会断开。
    Windows10上使用OpenConnect,却能够长时间保持连接,查看日志,也未查到断线自动重连的痕迹。所以似乎不是因为GFW的干扰?

    那么,有木有什么方法,让手机上掉线的机率变小一点呢

    您文章里提到了一个参数,但似乎效果并不好。

  • kstka
    10 months ago
    Reply

    Amazing article, thank you!
    Error found: openconnect-restart script
    Line “ExecStart=/bin/systemctl –no-block restart ocnyc.service” should be “ExecStart=/bin/systemctl –no-block restart openconnect.service”

  • kstka
    10 months ago
    Reply

    And it is better to add “deploy-hook = systemctl restart ocserv” into /etc/letsencrypt/cli.ini to reload ocserv after certbot certificate renewal for Ubuntu >= 18.04

  • Jonathan
    9 months ago
    Reply

    Is it really necessary to have a VPS? Can’t I use my home server for this?

    I checked on VPS Vultr and the cheapest is $6/month =$72 per year….

    NordVPN is $50/year for me….which nullifies the purpose of wanting to reduce costs

    • If you want to use VPN for privacy, you can’t use your home server, because when you are at your home, there’s no point in connecting to a VPN server hosted at home. Your IP address won’t change. And when you are not at your home, connecting to a VPN server hosted at home will always let the websites know your home IP address, which can be easily used to track you personally.

      Yes, the starting price at Vultr has increased. You can use Kamatera VPS, which starts at $4/month ($48/year)

    • I don’t know where you find the $5/month pricing. On my computer, the Kamatera web page says $4/month and I have a VPS at Kamatera that costs $4 per month.

      Hostinger starts at $3.95 per month, but it uses OVZ (OpenVZ) for the virtualization of VPS, which is much slower in performance and you can’t install your own Linux kernel. I would never use OpenVZ-based VPS. Always choose KVM or Xen-based VPS.

  • 非常感谢你详细的教程。我跟随教程配置好后,能连上VPN, 但仍然显示的是我自己的IP。我觉得问题似乎在IP-forwarding 上。systemctl restart ufw 出现下面的错误。

    Nov 06 11:59:19 web ufw-init[413]: Bad argument `COMMIT'
     Nov 06 11:59:19 web ufw-init[413]: Error occurred at line: 87
     Nov 06 11:59:19 web ufw-init[413]: Try `iptables-restore -h' or 'iptables-restore --help' for more information.
     Nov 06 11:59:19 web systemd[1]: ufw.service: Main process exited, code=exited, status=1/FAILURE
     Nov 06 11:59:19 web ufw-init[477]: Problem running '/etc/ufw/before.rules'
     Nov 06 11:59:19 web systemd[1]: ufw.service: Failed with result 'exit-code'.
     Nov 06 11:59:19 web systemd[1]: Failed to start Uncomplicated firewall.
     Warning: journal has been rotated since unit was started, output may be incomplete.
     

    sudo iptables -t nat -L POSTROUTING 也没有规则出现。附上ufw 规则文件。能麻烦你帮我看一下吗?再一次非常感谢!

    • 我去掉了前面一个COMMIT,又出现这个错误。

      Nov 06 12:26:00 web ufw-init[414]: Bad argument `*nat'
       Nov 06 12:26:00 web ufw-init[414]: Error occurred at line: 82
       Nov 06 12:26:00 web ufw-init[414]: Try `iptables-restore -h' or 'iptables-restore --help' for more information.
       Nov 06 12:26:00 web systemd[1]: ufw.service: Main process exited, code=exited, status=1/FAILURE
       Nov 06 12:26:00 web ufw-init[474]: Problem running '/etc/ufw/before.rules'
       Nov 06 12:26:00 web systemd[1]: ufw.service: Failed with result 'exit-code'.
       Nov 06 12:26:00 web systemd[1]: Failed to start Uncomplicated firewall.
       Warning: journal has been rotated since unit was started, output may be incomplete.
       
      • G.W.
        8 months ago
        Reply

        不好意思,ufw 现在起来了,iptables规则也出现了,但还是显示自己的IP。

        [email protected]:~# iptables -t nat -L POSTROUTING
         Chain POSTROUTING (policy ACCEPT)
         target prot opt source destination
         MASQUERADE all -- 10.10.10.0/24 anywhere
         

        sysctl -p 也执行了

        [email protected]:~# sysctl -p
         net.ipv6.conf.all.accept_ra = 2
         net.core.default_qdisc = fq
         net.ipv4.tcp_congestion_control = bbr
         fs.file-max = 65535
         net.ipv4.ip_forward = 1
         

        真想不出还应该看哪儿了!

    • 把你的/etc/ufw/before.rules 以及 /etc/ocserv/ocserv.conf 文件发给我看一下。

  • Joo Nice
    8 months ago
    Reply

    Hi,

    Is there any option so that we can have a web panel for this open connect server? I mean, we can add/delete/edit/manipulate the users via this web panel.

  • Hi Xiao Guoan, I’m very sorry about missing your prompt reply. I’ve managed to make ocserv work for me, though I’m still not sure where went wrong, and how exactly I got it to work.

    If you don’t mind, I have another question. Is it possible to use haproxy on 443 to route ssh request to the service which listens to port 222? I used to have a working setup but now I forgot how to do it…

    Thanks again for your time!

    # User authentication method. Could be set multiple times and in 
     # that case all should succeed. To enable multiple methods use
     # multiple auth directives. Available options: certificate, 
     # plain, pam, radius, gssapi.
     #
     # Note that authentication methods cannot be changed with reload.
     
     # certificate:
     # This indicates that all connecting users must present a certificate.
     #
     # pam[gid-min=1000]:
     # This enabled PAM authentication of the user. The gid-min option is used 
     # by auto-select-group option, in order to select the minimum valid group ID.
     #
     # plain[passwd=/etc/ocserv/ocpasswd,otp=/etc/ocserv/users.otp]
     # The plain option requires specifying a password file which contains
     # entries of the following format.
     # "username:groupname1,groupname2:encoded-password"
     # One entry must be listed per line, and 'ocpasswd' should be used
     # to generate password entries. The 'otp' suboption allows to specify
     # an oath password file to be used for one time passwords; the format of
     # the file is described in https://github.com/archiecobbs/mod-authn-otp/wiki/UsersFile
     #
     # radius[config=/etc/radiusclient/radiusclient.conf,groupconfig=true,nas-identifier=name]:
     # The radius option requires specifying freeradius-client configuration
     # file. If the groupconfig option is set, then config-per-user/group will be overriden,
     # and all configuration will be read from radius. That also includes the
     # Acct-Interim-Interval, and Session-Timeout values.
     #
     # See doc/README-radius.md for the supported radius configuration atributes.
     #
     # gssapi[keytab=/etc/key.tab,require-local-user-map=true,tgt-freshness-time=900]
     # The gssapi option allows to use authentication methods supported by GSSAPI,
     # such as Kerberos tickets with ocserv. It should be best used as an alternative
     # to PAM (i.e., have pam in auth and gssapi in enable-auth), to allow users with
     # tickets and without tickets to login. The default value for require-local-user-map
     # is true. The 'tgt-freshness-time' if set, it would require the TGT tickets presented
     # to have been issued within the provided number of seconds. That option is used to
     # restrict logins even if the KDC provides long time TGT tickets.
     
     #auth ="pam"
     #auth ="pam[gid-min=1000]"
     auth ="plain[passwd=/etc/ocserv/ocpasswd]"
     #auth ="plain[passwd=./sample.passwd,otp=./sample.otp]"
     #auth ="plain[passwd=./sample.passwd]"
     #auth ="certificate"
     #auth ="radius[config=/etc/radiusclient/radiusclient.conf,groupconfig=true]"
     
     # Specify alternative authentication methods that are sufficient
     # for authentication. That is, if set, any of the methods enabled
     # will be sufficient to login.
     #enable-auth ="certificate"
     #enable-auth ="gssapi"
     #enable-auth ="gssapi[keytab=/etc/key.tab,require-local-user-map=true,tgt-freshness-time=900]"
     
     # Accounting methods available:
     # radius: can be combined with any authentication method, it provides
     # radius accounting to available users (see also stats-report-time).
     #
     # pam: can be combined with any authentication method, it provides
     # a validation of the connecting user's name using PAM. It is
     # superfluous to use this method when authentication is already
     # PAM.
     #
     # Only one accounting method can be specified.
     #acct ="radius[config=/etc/radiusclient/radiusclient.conf]"
     
     # Use listen-host to limit to specific IPs or to the IPs of a provided 
     # hostname.
     #listen-host = [IP|HOSTNAME]
     listen-host = 127.0.0.1
     
     # Use udp-listen-host to limit udp to specific IPs or to the IPs of a provided
     # hostname. if not set, listen-host will be used
     #udp-listen-host = [IP|HOSTNAME]
     
     # When the server has a dynamic DNS address (that may change),
     # should set that to true to ask the client to resolve again on
     # reconnects.
     #listen-host-is-dyndns = true
     
     # TCP and UDP port number
     # Note: These options are controlled by ocserv.socket if socket-activated
     # version of systemd configuration is used
     tcp-port = 443
     udp-port = 443
     
     # Accept connections using a socket file. It accepts HTTP
     # connections (i.e., without SSL/TLS unlike its TCP counterpart),
     # and uses it as the primary channel. That option cannot be
     # combined with certificate authentication.
     #listen-clear-file = /run/ocserv-conn.socket
     
     # The user the worker processes will be run as. It should be
     # unique (no other services run as this user).
     run-as-user = nobody
     run-as-group = daemon
     
     # socket file used for IPC with occtl. You only need to set that,
     # if you use more than a single servers.
     #occtl-socket-file = /run/occtl.socket
     
     # socket file used for server IPC (worker-main), will be appended with .PID
     # It must be accessible within the chroot environment (if any), so it is best
     # specified relatively to the chroot directory.
     socket-file = /run/ocserv.socket
     
     # The default server directory. Does not require any devices present.
     #chroot-dir = /var/lib/ocserv
     
     # The key and the certificates of the server
     # The key may be a file, or any URL supported by GnuTLS (e.g., 
     # tpmkey:uuid=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx;storage=user
     # or pkcs11:object=my-vpn-key;object-type=private)
     #
     # The server-cert file may contain a single certificate, or
     # a sorted certificate chain.
     #
     # There may be multiple server-cert and server-key directives,
     # but each key should correspond to the preceding certificate.
     # The certificate files will be reloaded when changed allowing for in-place
     # certificate renewal (they are checked and reloaded periodically;
     # a SIGHUP signal to main server will force reload).
     
     server-cert = /etc/letsencrypt/live/v.some.site/fullchain.pem
     server-key = /etc/letsencrypt/live/v.some.site/privkey.pem
     
     # Diffie-Hellman parameters. Only needed if for old (pre 3.6.0
     # versions of GnuTLS for supporting DHE ciphersuites.
     # Can be generated using:
     # certtool --generate-dh-params --outfile /etc/ocserv/dh.pem
     #dh-params = /etc/ocserv/dh.pem
     
     # In case PKCS #11, TPM or encrypted keys are used the PINs should be available
     # in files. The srk-pin-file is applicable to TPM keys only, and is the 
     # storage root key.
     #pin-file = /etc/ocserv/pin.txt
     #srk-pin-file = /etc/ocserv/srkpin.txt
     
     # The password or PIN needed to unlock the key in server-key file.
     # Only needed if the file is encrypted or a PKCS #11 object. This
     # is an alternative method to pin-file.
     #key-pin = 1234
     
     # The SRK PIN for TPM.
     # This is an alternative method to srk-pin-file.
     #srk-pin = 1234
     
     # The Certificate Authority that will be used to verify
     # client certificates (public keys) if certificate authentication
     # is set.
     ca-cert = /etc/ssl/certs/ssl-cert-snakeoil.pem
     
     
     ### All configuration options below this line are reloaded on a SIGHUP.
     ### The options above, will remain unchanged. Note however, that the 
     ### server-cert, server-key, dh-params and ca-cert options will be reloaded
     ### if the provided file changes, on server reload. That allows certificate
     ### rotation, but requires the server key to remain the same for seamless
     ### operation. If the server key changes on reload, there may be connection
     ### failures during the reloading time.
     
     
     # Whether to enable seccomp/Linux namespaces worker isolation. That restricts the number of 
     # system calls allowed to a worker process, in order to reduce damage from a
     # bug in the worker process. It is available on Linux systems at a performance cost.
     # The performance cost is roughly 2% overhead at transfer time (tested on a Linux 3.17.8).
     # Note however, that process isolation is restricted to the specific libc versions
     # the isolation was tested at. If you get random failures on worker processes, try
     # disabling that option and report the failures you, along with system and debugging
     # information at: https://gitlab.com/ocserv/ocserv/issues
     isolate-workers = true
     
     # A banner to be displayed on clients
     #banner ="Welcome"
     
     # Limit the number of clients. Unset or set to zero for unlimited.
     #max-clients = 1024
     max-clients = 2
     
     # Limit the number of identical clients (i.e., users connecting 
     # multiple times). Unset or set to zero for unlimited.
     max-same-clients = 2
     
     # When the server receives connections from a proxy, like haproxy
     # which supports the proxy protocol, set this to obtain the correct
     # client addresses. The proxy protocol (v2) would then be expected in
     # the TCP or UNIX socket (not the UDP one).
     listen-proxy-proto = true
     
     # Limit the number of client connections to one every X milliseconds 
     # (X is the provided value). Set to zero for no limit.
     #rate-limit-ms = 100
     
     # Stats report time. The number of seconds after which each
     # worker process will report its usage statistics (number of
     # bytes transferred etc). This is useful when accounting like
     # radius is in use.
     #stats-report-time = 360
     
     # Stats reset time. The period of time statistics kept by main/sec-mod
     # processes will be reset. These are the statistics shown by cmd
     # 'occtl show stats'. For daily: 86400, weekly: 604800
     # This is unrelated to stats-report-time.
     server-stats-reset-time = 604800
     
     # Keepalive in seconds
     keepalive = 180
     
     # Dead peer detection in seconds.
     # Note that when the client is behind a NAT this value
     # needs to be short enough to prevent the NAT disassociating
     # his UDP session from the port number. Otherwise the client
     # could have his UDP connection stalled, for several minutes.
     dpd = 60
     
     # Dead peer detection for mobile clients. That needs to
     # be higher to prevent such clients being awaken too 
     # often by the DPD messages, and save battery.
     # The mobile clients are distinguished from the header
     # 'X-AnyConnect-Identifier-Platform'.
     mobile-dpd = 300
     
     # If using DTLS, and no UDP traffic is received for this
     # many seconds, attempt to send future traffic over the TCP
     # connection instead, in an attempt to wake up the client
     # in the case that there is a NAT and the UDP translation
     # was deleted. If this is unset, do not attempt to use this
     # recovery mechanism.
     switch-to-tcp-timeout = 25
     
     # MTU discovery (DPD must be enabled)
     try-mtu-discovery = false
     
     # If you have a certificate from a CA that provides an OCSP
     # service you may provide a fresh OCSP status response within
     # the TLS handshake. That will prevent the client from connecting
     # independently on the OCSP server.
     # You can update this response periodically using:
     # ocsptool --ask --load-cert=your_cert --load-issuer=your_ca --outfile response
     # Make sure that you replace the following file in an atomic way.
     #ocsp-response = /etc/ocserv/ocsp.der
     
     # The object identifier that will be used to read the user ID in the client 
     # certificate. The object identifier should be part of the certificate's DN
     # Useful OIDs are: 
     # CN = 2.5.4.3, UID = 0.9.2342.19200300.100.1.1
     cert-user-oid = 0.9.2342.19200300.100.1.1
     
     # The object identifier that will be used to read the user group in the 
     # client certificate. The object identifier should be part of the certificate's
     # DN. If the user may belong to multiple groups, then use multiple such fields
     # in the certificate's DN. Useful OIDs are: 
     # OU (organizational unit) = 2.5.4.11 
     #cert-group-oid = 2.5.4.11
     
     # The revocation list of the certificates issued by the 'ca-cert' above.
     # See the manual to generate an empty CRL initially. The CRL will be reloaded
     # periodically when ocserv detects a change in the file. To force a reload use
     # SIGHUP.
     #crl = /etc/ocserv/crl.pem
     
     # Uncomment this to enable compression negotiation (LZS, LZ4).
     compression = true
     
     # Set the minimum size under which a packet will not be compressed.
     # That is to allow low-latency for VoIP packets. The default size
     # is 256 bytes. Modify it if the clients typically use compression
     # as well of VoIP with codecs that exceed the default value.
     no-compress-limit = 256
     
     # GnuTLS priority string; note that SSL 3.0 is disabled by default
     # as there are no openconnect (and possibly anyconnect clients) using
     # that protocol. The string below does not enforce perfect forward
     # secrecy, in order to be compatible with legacy clients.
     #
     # Note that the most performant ciphersuites are the moment are the ones
     # involving AES-GCM. These are very fast in x86 and x86-64 hardware, and
     # in addition require no padding, thus taking full advantage of the MTU.
     # For that to be taken advantage of, the openconnect client must be
     # used, and the server must be compiled against GnuTLS 3.2.7 or later.
     # Use "gnutls-cli --benchmark-tls-ciphers", to see the performance
     # difference with AES_128_CBC_SHA1 (the default for anyconnect clients)
     # in your system.
     
     # More combinations in priority strings are available, check
     # http://gnutls.org/manual/html_node/Priority-Strings.html
     # E.g., the string below enforces perfect forward secrecy (PFS) 
     # on the main channel.
     tls-priorities ="NORMAL:%SERVER_PRECEDENCE:%COMPAT:-RSA:-VERS-SSL3.0:-ARCFOUR-128"
     
     # That option requires the established DTLS channel to use the same
     # cipher as the primary TLS channel. This cannot be combined with
     # listen-clear-file since the ciphersuite information is not available
     # in that configuration. Note also, that this option implies that
     # dtls-legacy option is false; this option cannot be enforced
     # in the legacy/compat protocol.
     #match-tls-dtls-ciphers = true
     
     # The time (in seconds) that a client is allowed to stay connected prior
     # to authentication
     auth-timeout = 240
     
     # The time (in seconds) that a client is allowed to stay idle (no traffic)
     # before being disconnected. Unset to disable.
     idle-timeout = 1200
     
     # The time (in seconds) that a mobile client is allowed to stay idle (no
     # traffic) before being disconnected. Unset to disable.
     mobile-idle-timeout = 1800
     
     # The time (in seconds) that a client is not allowed to reconnect after 
     # a failed authentication attempt.
     min-reauth-time = 300
     
     # Banning clients in ocserv works with a point system. IP addresses
     # that get a score over that configured number are banned for
     # min-reauth-time seconds. By default a wrong password attempt is 10 points,
     # a KKDCP POST is 1 point, and a connection is 1 point. Note that
     # due to difference processes being involved the count of points
     # will not be real-time precise.
     #
     # Score banning cannot be reliably used when receiving proxied connections
     # locally from an HTTP server (i.e., when listen-clear-file is used).
     #
     # Set to zero to disable.
     max-ban-score = 80
     
     # The time (in seconds) that all score kept for a client is reset.
     ban-reset-time = 300
     
     # In case you'd like to change the default points.
     #ban-points-wrong-password = 10
     #ban-points-connection = 1
     #ban-points-kkdcp = 1
     
     # Cookie timeout (in seconds)
     # Once a client is authenticated he's provided a cookie with
     # which he can reconnect. That cookie will be invalidated if not
     # used within this timeout value. This cookie remains valid, during
     # the user's connected time, and after user disconnection it
     # remains active for this amount of time. That setting should allow a
     # reasonable amount of time for roaming between different networks.
     cookie-timeout = 300
     
     # If this is enabled (not recommended) the cookies will stay
     # valid even after a user manually disconnects, and until they
     # expire. This may improve roaming with some broken clients.
     #persistent-cookies = true
     
     # Whether roaming is allowed, i.e., if true a cookie is
     # restricted to a single IP address and cannot be re-used
     # from a different IP.
     deny-roaming = false
     
     # ReKey time (in seconds)
     # ocserv will ask the client to refresh keys periodically once
     # this amount of seconds is elapsed. Set to zero to disable (note
     # that, some clients fail if rekey is disabled).
     rekey-time = 172800
     
     # ReKey method
     # Valid options: ssl, new-tunnel
     # ssl: Will perform an efficient rehandshake on the channel allowing
     # a seamless connection during rekey.
     # new-tunnel: Will instruct the client to discard and re-establish the channel.
     # Use this option only if the connecting clients have issues with the ssl
     # option.
     rekey-method = ssl
     
     # Script to call when a client connects and obtains an IP.
     # The following parameters are passed on the environment.
     # REASON, USERNAME, GROUPNAME, DEVICE, IP_REAL (the real IP of the client),
     # IP_REAL_LOCAL (the local interface IP the client connected), IP_LOCAL
     # (the local IP in the P-t-P connection), IP_REMOTE (the VPN IP of the client),
     # IPV6_LOCAL (the IPv6 local address if there are both IPv4 and IPv6
     # assigned), IPV6_REMOTE (the IPv6 remote address), IPV6_PREFIX, and
     # ID (a unique numeric ID); REASON may be "connect" or "disconnect".
     # In addition the following variables OCSERV_ROUTES (the applied routes for this
     # client), OCSERV_NO_ROUTES, OCSERV_DNS (the DNS servers for this client),
     # will contain a space separated list of routes or DNS servers. A version
     # of these variables with the 4 or 6 suffix will contain only the IPv4 or
     # IPv6 values. The connect script must return zero as exit code, or the
     # client connection will be refused.
     
     # The disconnect script will receive the additional values: STATS_BYTES_IN,
     # STATS_BYTES_OUT, STATS_DURATION that contain a 64-bit counter of the bytes 
     # output from the tun device, and the duration of the session in seconds.
     
     #connect-script = /usr/bin/myscript
     #disconnect-script = /usr/bin/myscript
     
     # UTMP
     # Register the connected clients to utmp. This will allow viewing
     # the connected clients using the command 'who'.
     #use-utmp = true
     
     # Whether to enable support for the occtl tool (i.e., either through D-BUS,
     # or via a unix socket).
     use-occtl = true
     
     # PID file. It can be overriden in the command line.
     pid-file = /run/ocserv.pid
     
     # Set the protocol-defined priority (SO_PRIORITY) for packets to
     # be sent. That is a number from 0 to 6 with 0 being the lowest
     # priority. Alternatively this can be used to set the IP Type-
     # Of-Service, by setting it to a hexadecimal number (e.g., 0x20).
     # This can be set per user/group or globally.
     #net-priority = 3
     
     # Set the VPN worker process into a specific cgroup. This is Linux
     # specific and can be set per user/group or globally.
     #cgroup ="cpuset,cpu:test"
     
     #
     # Network settings
     #
     
     # The name to use for the tun device
     device = vpns
     
     # Whether the generated IPs will be predictable, i.e., IP stays the
     # same for the same user when possible.
     predictable-ips = true
     
     # The default domain to be advertised
     default-domain = v.weast.ml
     
     # The pool of addresses that leases will be given from. If the leases
     # are given via Radius, or via the explicit-ip? per-user config option then 
     # these network values should contain a network with at least a single
     # address that will remain under the full control of ocserv (that is
     # to be able to assign the local part of the tun device address).
     # Note that, you could use addresses from a subnet of your LAN network if you
     # enable proxy arp in the LAN interface (see http://ocserv.gitlab.io/www/recipes-ocserv-pseudo-bridge.html);
     # in that case it is recommended to set ping-leases to true.
     #ipv4-network = 10.10.10.0
     ipv4-network = 192.168.86.0
     ipv4-netmask = 255.255.255.0
     
     # An alternative way of specifying the network:
     #ipv4-network = 192.168.1.0/24
     
     # The IPv6 subnet that leases will be given from.
     #ipv6-network = fda9:4efe:7e3b:03ea::/48 
     
     # Specify the size of the network to provide to clients. It is
     # generally recommended to provide clients with a /64 network in
     # IPv6, but any subnet may be specified. To provide clients only
     # with a single IP use the prefix 128.
     #ipv6-subnet-prefix = 128
     #ipv6-subnet-prefix = 64
     
     # Whether to tunnel all DNS queries via the VPN. This is the default
     # when a default route is set.
     tunnel-all-dns = true
     
     # The advertized DNS server. Use multiple lines for
     # multiple servers.
     # dns = fc00::4be0
     dns = 8.8.8.8
     dns = 1.1.1.1
     
     # The NBNS server (if any)
     #nbns = 192.168.1.3
     
     # The domains over which the provided DNS should be used. Use
     # multiple lines for multiple domains.
     #split-dns = example.com
     
     # Prior to leasing any IP from the pool ping it to verify that
     # it is not in use by another (unrelated to this server) host.
     # Only set to true, if there can be occupied addresses in the
     # IP range for leases.
     ping-leases = false
     
     # Use this option to set a link MTU value to the incoming
     # connections. Unset to use the default MTU of the TUN device.
     # Note that the MTU is negotiated using the value set and the
     # value sent by the peer.
     #mtu = 1420
     
     # Unset to enable bandwidth restrictions (in bytes/sec). The
     # setting here is global, but can also be set per user or per group.
     #rx-data-per-sec = 40000
     #tx-data-per-sec = 40000
     
     # The number of packets (of MTU size) that are available in
     # the output buffer. The default is low to improve latency.
     # Setting it higher will improve throughput.
     #output-buffer = 10
     
     # Routes to be forwarded to the client. If you need the
     # client to forward routes to the server, you may use the 
     # config-per-user/group or even connect and disconnect scripts.
     #
     # To set the server as the default gateway for the client just
     # comment out all routes from the server, or use the special keyword
     # 'default'.
     
     #route = 10.0.0.0/8
     #route = 172.16.0.0/12
     #route = 192.168.0.0/16
     #route = fd00::/8
     #route = default
     
     # Subsets of the routes above that will not be routed by
     # the server.
     
     #no-route = 192.168.5.0/255.255.255.0
     no-route = 192.168.10.0/255.255.255.0
     
     # Note the that following two firewalling options currently are available
     # in Linux systems with iptables software. 
     
     # If set, the script /usr/bin/ocserv-fw will be called to restrict
     # the user to its allowed routes and prevent him from accessing
     # any other routes. In case of defaultroute, the no-routes are restricted.
     # All the routes applied by ocserv can be reverted using /usr/bin/ocserv-fw
     # --removeall. This option can be set globally or in the per-user configuration.
     #restrict-user-to-routes = true
     
     # This option implies restrict-user-to-routes set to true. If set, the
     # script /usr/bin/ocserv-fw will be called to restrict the user to
     # access specific ports in the network. This option can be set globally
     # or in the per-user configuration.
     #restrict-user-to-ports ="tcp(443), tcp(80), udp(443), sctp(99), tcp(583), icmp(), icmpv6()"
     
     # You could also use negation, i.e., block the user from accessing these ports only.
     #restrict-user-to-ports ="!(tcp(443), tcp(80))"
     
     # When set to true, all client's iroutes are made visible to all
     # connecting clients except for the ones offering them. This option
     # only makes sense if config-per-user is set.
     #expose-iroutes = true
     
     # Groups that a client is allowed to select from.
     # A client may belong in multiple groups, and in certain use-cases
     # it is needed to switch between them. For these cases the client can
     # select prior to authentication. Add multiple entries for multiple groups.
     # The group may be followed by a user-friendly name in brackets.
     #select-group = group1
     #select-group = group2[My special group]
     
     # The name of the (virtual) group that if selected it would assign the user
     # to its default group.
     #default-select-group = DEFAULT
     
     # Instead of specifying manually all the allowed groups, you may instruct
     # ocserv to scan all available groups and include the full list.
     #auto-select-group = true
     
     # Configuration files that will be applied per user connection or
     # per group. Each file name on these directories must match the username
     # or the groupname.
     # The options allowed in the configuration files are dns, nbns,
     # ipv?-network, ipv4-netmask, rx/tx-per-sec, iroute, route, no-route,
     # explicit-ipv4, explicit-ipv6, net-priority, deny-roaming, no-udp, 
     # keepalive, dpd, mobile-dpd, max-same-clients, tunnel-all-dns,
     # restrict-user-to-routes, user-profile, cgroup, stats-report-time,
     # mtu, idle-timeout, mobile-idle-timeout, restrict-user-to-ports,
     # split-dns and session-timeout.
     #
     # Note that the 'iroute' option allows to add routes on the server
     # based on a user or group. The syntax depends on the input accepted
     # by the commands route-add-cmd and route-del-cmd (see below). The no-udp
     # is a boolean option (e.g., no-udp = true), and will prevent a UDP session
     # for that specific user or group. The hostname option will set a
     # hostname to override any proposed by the user. Note also, that, any 
     # routes, no-routes, DNS or NBNS servers present will overwrite the global ones.
     
     #config-per-user = /etc/ocserv/config-per-user/
     #config-per-group = /etc/ocserv/config-per-group/
     
     # When config-per-xxx is specified and there is no group or user that
     # matches, then utilize the following configuration.
     #default-user-config = /etc/ocserv/defaults/user.conf
     #default-group-config = /etc/ocserv/defaults/group.conf
     
     # The system command to use to setup a route. %{R} will be replaced with the
     # route/mask, %{RI} with the route in CIDR format, and %{D} with the (tun) device.
     #
     # The following example is from linux systems. %{R} should be something
     # like 192.168.2.0/255.255.255.0 and %{RI} 192.168.2.0/24 (the argument of iroute).
     
     #route-add-cmd ="ip route add %{R} dev %{D}"
     #route-del-cmd ="ip route delete %{R} dev %{D}"
     
     # This option allows to forward a proxy. The special keywords '%{U}'
     # and '%{G}', if present will be replaced by the username and group name.
     #proxy-url = http://example.com/
     #proxy-url = http://example.com/%{U}/
     
     # This option allows you to specify a URL location where a client can
     # post using MS-KKDCP, and the message will be forwarded to the provided
     # KDC server. That is a translation URL between HTTP and Kerberos.
     # In MIT kerberos you'll need to add in realms:
     # EXAMPLE.COM = {
     # kdc = https://ocserv.example.com/KdcProxy
     # http_anchors = FILE:/etc/ocserv-ca.pem
     # }
     # In some distributions the krb5-k5tls plugin of kinit is required.
     #
     # The following option is available in ocserv, when compiled with GSSAPI support. 
     
     #kkdcp ="SERVER-PATH KERBEROS-REALM [email protected]:PORT"
     #kkdcp ="/KdcProxy KERBEROS.REALM [email protected]:88"
     #kkdcp ="/KdcProxy KERBEROS.REALM [email protected]:88"
     #kkdcp ="/KdcProxy KERBEROS.REALM [email protected][::1]:88"
     
     #
     # The following options are for (experimental) AnyConnect client 
     # compatibility. 
     
     # This option will enable the pre-draft-DTLS version of DTLS, and
     # will not require clients to present their certificate on every TLS
     # connection. It must be set to true to support legacy CISCO clients
     # and openconnect clients < 7.08. When set to true, it implies dtls-legacy = true.
     cisco-client-compat = true
     
     # This option allows to disable the DTLS-PSK negotiation (enabled by default).
     # The DTLS-PSK negotiation was introduced in ocserv 0.11.5 to deprecate
     # the pre-draft-DTLS negotiation inherited from AnyConnect. It allows the
     # DTLS channel to negotiate its ciphers and the DTLS protocol version.
     #dtls-psk = false
     
     # This option allows to disable the legacy DTLS negotiation (enabled by default,
     # but that may change in the future).
     # The legacy DTLS uses a pre-draft version of the DTLS protocol and was
     # from AnyConnect protocol. It has several limitations, that are addressed
     # by the dtls-psk protocol supported by openconnect 7.08+.
     dtls-legacy = true
     
     # Client profile xml. A sample file exists in doc/profile.xml.
     # It is required by some of the CISCO clients.
     # This file must be accessible from inside the worker's chroot. 
     # Note that enabling this option is not recommended as it will allow
     # the worker processes to open arbitrary files (when isolate-workers is
     # set to true).
     #user-profile = /path/to/file.xml
     
     #Advanced options
     
     # Option to allow sending arbitrary custom headers to the client after
     # authentication and prior to VPN tunnel establishment. You shouldn't
     # need to use this option normally; if you do and you think that
     # this may help others, please send your settings and reason to
     # the openconnect mailing list. The special keywords '%{U}'
     # and '%{G}', if present will be replaced by the username and group name.
     #custom-header ="X-My-Header: hi there"
     
     # An example virtual host with different authentication methods serviced
     # # by this server.
     #
     # [vhost:www.example.com]
     # auth ="certificate"
     #
     # ca-cert = ../tests/certs/ca.pem
     #
     # # The certificate set here must include a 'dns_name' corresponding to
     # # the virtual host name.
     #
     # server-cert = ../tests/certs/server-cert-secp521r1.pem
     # server-key = ../tests/certs/server-key-secp521r1.pem
     #
     # ipv4-network = 192.168.2.0
     # ipv4-netmask = 255.255.255.0
     #
     # cert-user-oid = 0.9.2342.19200300.100.1.1
     #
     
    • You are using the 192.168.86.0/24 network in /etc/ocserv/ocserv.conf file, but you use 10.10.10.0/24 network in /etc/ufw/before.rules file?

  • Hi Xiao Guoan, yes I think that might be the very reason it didn’t work at first. The network in before.rules is correctly configured now, so it’s working!

    Just wondering if you had a chance to look into my additional question about routing ssh requests through haproxy on 443 port?

    Again this blog is awesome, your efforts put into it are very much appreciated!

    • If you don’t want your SSH traffic to be monitored, use the following command for SSH.

      ssh [email protected]

      or

      ssh [email protected]

      Your SSH traffic will be encrypted by the VPN tunnel and it looks like HTTPS traffic to others.

      I don’t think you can proxy SSH traffic with HAProxy and even if you can, it will be detected as SSH traffic.

  • Ruslan
    7 months ago
    Reply

    Hello. Thank you for such a good and useful article! What a great job has been done. Excellent. But I still had difficulties. I did everything according to the instructions. But the devices do not connect to the vpn server. Errors are displayed in the log, but I don’t understand what they say at all. Help please. Thanks!

  • 一匹马
    6 months ago
    Reply

    大佬,

    I just get through all the procedures on local server as a test . seems OK. thanks a lot for the detailed informative sharing. learned a lot.

    Just tried Kamatera , but seems cannot receive the phone verification code from the website to 中国联通 . Don’t know if you encounter the same problem before.

    In China , I just got a domain name. but seems only after 备案, can be fully functioning. even though in domestic it is DNSed already . but when I tried to get the CA from Let’s certificate , failed for reasons of firewall ( I guess the domain name already occupied by Ali, but still not yet propagate the my IP to the outside china DNS servers) . How do you think the reason?

    thanks again for this tutorial and others

    • I have a China Mobile (中国移动) phone number, and I can receive the verification code from Kamatera.

      Go to https://dnsmap.io to check your DNS record propagation status.
      Never used Aliyun before.

      • 一匹马
        6 months ago
        Reply

        Thank you for your reply

        I tried the dnsmap.io . also ipdonation.net all can get the correct IP of my new domain.

        I just tried to get the CA . but still failed on the stage “http-01 challenge” , like below:
        ++++++++
        Performing the following challenges:
        http-01 challenge for my.domain.xyz
        Waiting for verification…
        Challenge failed for domain my.domain.xyz
        +++++++

        When free, pls give some hint . thanks a lot

      • 一匹马
        6 months ago
        Reply

        I sort of figured out the source of problem …

        seems the firewall configuration imposed by the Ali cloud on the workstation.

        Let me try to find a way out …

        thanks again

      • 一匹马
        6 months ago
        Reply

        大佬

        this is the message from my PC , VPNed through Ali , mentored by you.

        thank you for this tutorial .

        learned a lot

        My mentioned problems originate from ignorance of network and typo .

        your guide is superb!

  • 一匹马
    6 months ago
    Reply

    now connected with the ocserv server . cheers and thanks

    but still two problems:
    1. the default gateway for the client end is set to itself , so, there would be no internet for client.
    2. when I ctrl+c , stop the openconnenct client, the client PC’s route table is not recovered to the original. actually the route table is empty.

    ========= here below is my part in the configuration file.

    #route = 10.0.0.0/8
     #route = 172.16.0.0/12
     #route = 192.168.0.0/16
     route = fd00::/8
     route = default
     

    —-below is the message from ocserv to the client terminal:

    add net 10.10.10.0: gateway 10.10.10.238 ( 10.10.10.238 is the PC's new IP address )
     delete net default: gateway 192.168.1.1 (after ctrl+c , no recovery to 192.168.1.1)
     

    When you are free , PLS help give some hint 🙂

    • Correct config should be

      #route = 10.0.0.0/8
       #route = 172.16.0.0/12
       #route = 192.168.0.0/16
       #route = fd00::/8
       #route = default 
       #no-route = 192.168.5.0/255.255.255.0
       
  • Junise Safvan
    4 months ago
    Reply

    Hi Admin,

    Your tutorial is great.

    I did everything and now both from Ubuntu Laptop and Android mobile I can connect to the VPN network without showing any error.

    But the problem is, when check *What is my IP* in the browser, it is showing the old ISP IP itself instead of the ocserv server IP.

    Any idea how to solve this?

    • Junise Safvan
      3 months ago
      Reply

      Myself found the solution. It was actually due to my misunderstanding.

      I thought the commenting of route is a part of the DNS resolver running on the same server which I don’t had.

      Issue solved after commenting all routes..

  • visir
    3 months ago
    Reply

    Hello, is it possible for oscerv to connect to one domain with TLS Certificate from Let’s Encrypt two (2) or (3) vps/vds servers and use either…

    • Yes, simply create multiple DNS A records for the same hostname.

      vpn.example.com A 1.2.3.4
       A 1.2.3.5
       A 1.2.3.6
       

      When a hostname has multiple A records, the VPN client will choose one of the A records randomly.

      You need to make sure all VPN servers has the same TLS certificate.

  • Ali Mohammadi
    3 months ago
    Reply

    hello tutorial is very good. i have two issues here:
    1: when i connect with any connect i can not stablish ssh connection to the server it self ?
    2: i want to use split-tunneling here and i add no-route lines(1580 lines) to .conf file but in client side it is not effecting and my whole traffic is tunneling. in status i have got messages for excluding routes but in client side its not working.. so what can i do ?

    • 1. VPN connection doesn’t affect SSH connection. You can SSH using the public IP address or the private VPN address.

      ssh [email protected]

      2. Split tunneling in ocserv accepts at most 200 no-route/route lines.

      • Ali Mohammadi
        3 months ago
        Reply

        I appreciate the quick response & ssh worked on private ip address.

  • Ali Mohammadi
    2 months ago
    Reply

    hello. i installed service thats awesome , so i want to ask username & password in one page , how should we do it ? can you help me ? thanks

    • use the ocpasswd tool to generate VPN accounts.

      sudo ocpasswd -c /etc/ocserv/ocpasswd username

      What do you mean by “username & password in one page”?

  • Ali Mohammadi
    2 months ago
    Reply

    when client is going to connect first prompt for entering username and then prompt for password and its two times prompt. but i see any connect vpn that asks for username and password same time in just one prompt. like picture that i attached

    • That’s done in the client software. If you use the OpenConnect GUI client, you can ask the software author to change this, but I really think it’s not an issue for most people.

      • Ali Mohammadi
        2 months ago
        Reply

        no thats totally server side configuration but i cant find right one. so no that is not issue. thanks

  • visir
    2 months ago
    Reply

    Hello, can I control the system ocserv on ubuntu, specifically I need to account for user traffic, I would like to know how much was downloaded by specific users, what exactly, and visit https.
    Thanks in advance

    • visir
      2 months ago
      Reply

      Hello, can I control the system ocserv on ubuntu, specifically I need to account for user traffic, I would like to know how much was downloaded by specific users, what exactly, and visit https.
      Thanks in advance

  • Saud
    2 months ago
    Reply

    I was also getting the error Server ‘vpn.your-domain.com’ requested Basic authentication which is disabled by default and it took me a while to figure out that “ocpasswd -c /etc/ocserv/ocpasswd username” has been changed to “ocpasswd -c /etc/ocserv/passwd username” on the default installation.

Leave a Comment Cancel reply