Set Up OpenConnect VPN Server (ocserv) on Ubuntu 22.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 22.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.
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 22.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 22.04
Log into your Ubuntu 22.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 22.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 1.21.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 22.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 22.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, find the following two lines.
tcp-port = 443 udp-port = 443
Comment out the UDP port. (We will use TCP BBR algorithm to boost TCP speed.)
tcp-port = 443 #udp-port = 443
If you don’t want ocserv to use TCP port 443 (there’s a web server using port 443?), then change the TCP port number. Otherwise leave it alone.
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.
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
Find the following two lines and uncomment them, so VPN clients will be given private IPv6 addresses.
ipv6-network = fda9:4efe:7e3b:03ea::/48 ipv6-subnet-prefix = 64
If you see the following line
ipv6-network = fda9:4efe:7e3b:03ea::/64
Please change it to:
ipv6-network = fda9:4efe:7e3b:03ea::/48
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
Also, run the following two commands to enable TCP BBR algorithm to boost TCP speed.
echo "net.core.default_qdisc=fq" | sudo tee -a /etc/sysctl.d/60-custom.conf echo "net.ipv4.tcp_congestion_control=bbr" | sudo tee -a /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
Step 9: Fix Futex Error
Run the following command to check the ocserv
systemd journals.
sudo journalctl -eu ocserv
If your server has the following error, you need to install the latest ocserv
version to fix the futex error.
The futex facility returned an unexpected error code.
Check your current ocserv
version.
ocserv -v
Ubuntu 22.04 repository currently ships with ocserv 1.1.3. It might update ocserv
in the future, but right now you need to 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
How to Install and Use OpenConnect VPN client on Ubuntu 22.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
andWants=network-online.target
make this service run after network is up. We want theopenconnect.service
start after thesystemd-resolved.service
because that will ensure the DNS server address set by OpenConnect won’t be overridden bysystemd-resolved.service
.- In reality, this service can still run before network is up. We add
Restart=always
andRestartSec=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 theopenconnect
command. - The
KillSignal
directive tells Systemd to send theSIGINT
signal when thesystemctl 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.
0 5 * * * certbot renew --quiet && systemctl restart 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 Kamtera 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
).
You might also need to disable IPv6 on your local computer.
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.
The local network may not be trustworthy
If you use the Cisco AnyConnect VPN client on iOS, and you encounter the following error, it’s likely your TLS certificate has expired.
If the TLS certificate has expired, you will also see the following error when trying to establish a VPN connection on a Linux desktop.
Server certificate verify failed: certificate expired Certificate from VPN server "vpn.your-domain.com" failed verification. Reason: certificate expired To trust this server in future, perhaps add this to your command line: --servercert pin-sha256:er1Kv/37ZxHpN6VESmYVS7vw4wXEB1oYELwiBS2wcvc= Enter 'yes' to accept, 'no' to abort; anything else to view: fgets (stdin): Operation now in progress
You will need to run the following command to renew TLS certificate.
sudo certbot renew --quiet
Don’t forget to restart ocserv.
sudo systemctl restart ocserv
If this error still persists after renewing the certificate, be sure to check the server-cert
and server-key
parameter in the /etc/ocserv/ocserv.conf
file. Maybe it’s pointed to the wrong file.
No Tap-Windows Adapter installed on this system
If you use the OpenConnect GUI Windows client and found the “No Windows-TAP adapaters found” error in the logs (View – Log Window), this is likely because you have install other VPN clients afterward like OpenVPN.
To fix this error, you need to uninstall OpenConnect GUI client and reinstall it. In the setup wizard, you will have the option to install the TAP driver.
Two VPN Clients Share the Same Private IP Address?
I have an iPhone and iPad, and both of them use the AnyConnect VPN app to connect to ocserv VPN server, which is unable to tell the iPhone and iPad apart when they are in the same Wi-Fi network, so ocserv gives them the same private IP address, which causes the other unable to browse the Internet.
To fix this problem, I simply create two separate VPN accounts. One for iPhone and the other for iPad.
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 22.04. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks 🙂
I follow your instruction but still receive this error on client
DTLS handshake failed: Resource temporarily unavailable, try again.
what else I can do
It’s recommended to disable DTLS, 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 (/etc/ocserv/ocserv.conf).
Save and close the file. Then 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 two times faster than DTLS.
“I found that if I change port 443 to a different port, the Internet filtering system of my country will block this VPN connection.”
So what is your country?
China.
Ubuntu 16 has and old version of ocserv.
It’s version (0.10.11-1build1) and there are a lot of improvements since that version in the current one (0.12.2)
Now I’m working on compiling it to work on ubuntu, but seems like ocserv is more compatible with debian. Still I got some errors if I want to run it as service using systemctl.
Is this the only vpn working in china? Microsoft SSTP is working? OpenVPN port 443 working?
I now use self-hosted OpenConnect VPN and Shadowsocks proxy in China. They are very stable.
Microsoft SSTP VPN is also very fast and stable in China.
I used OpenVPN before with a VPN provider. It worked but can be easily interrupted by the great firewall.
To compile the lastest ocserv version from source, please read this section.
also I wanted to tell you that the email your system sends, is going to spam folder.
My email server complies with all legitimate email-sending practices. It takes time to build a good email reputation. Microsoft is very strict on accepting emails. Initially the emails are likely to go into spam folder. If many people mark my emails as not spam, then my emails are more likely to go to inbox.
Shadowsocks proxy is not blocked in China? You can make OpenVPN connects to it and then it can work without being filtered by the great firewall?
Shadowsocks is working. I don’t know the state of OpenVPN now because I haven’t used it for a long time.
Greetings, friend. great tutorial. I stayed here: sudo openconnect -b vpn.example.com:port-number. When the command is issued, the message:
Got inappropriate HTTP CONNECT response: HTTP/1.1 401 Unauthorized
Creating SSL connection failed
What I can do? tks
You need to enter a correct username and password after running the command.
thank you very much
I’m getting an error.
error: unknown user: nobody
Could you please guide me on what could be the problem?
This article does not require running a service as the nobody user. At which step did you see this error?
I fixed it. Thanks for your help anyways.
i just set up OpenConnect VPN server on ubuntu 18.04. Users are able to connect and get an IP address assigned by the OpenConnect server. Corp network is 172.16.4.0/23 OpenConnect server is 172.16.4.10 vpn clients get 10.1.1.0/24 addresses. From the vpn client i can ping 10.1.1.1 and 172.16.4.10, but can’t ping any other corp servers on the 17.16.4.0/23 network
ICMP packets get to the corp servers, but get dropped because the corp servers don’t know how to route to 10.1.1.0/24 subnet
any help is greatly appreciated
if I do route add 10.1.1.0 mask 255.255.255.0 172.16.4.10 on any of the corp servers I am able to communicate with the corp servers from the VPN client
Hello,
How can we disable TLS 1.0 in the OpenConnect VPN server config?
I just added instruction on how to disable TLS 1.0 in OpenConnect VPN server. Please see the end of this article.
Xiao,
Thanks for the TLS disablement update.
There is a few more things we would like to disable. Are you able to assist with disabling elliptic curves? P-192 (prime192v1) (192 bits) to be specific and a list of ciphers
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_DHE_RSA_WITH_AES_256_CCM
Thanks
I have set up the server successfully but I can’t route traffic through the VPN server. I can only ping the server successfully but can’t ping any other IP.
Double check your sysctl config and iptables firewall config.
Hi,
I am following your instructions to the letter but I run into this issue when trying to setup ocserv server.
Has something changed since this guide was posted?
Thanks
This line:
indicates that you didn’t correctly specify the path to TLS certificate. If you go to the /etc/letsencrypt/live/ directory, you will understand what went wrong.
Hi Guo An,
Thanks for the speedy response. I should have mentioned that I removed the site’s domain from the nginx log.
* From the ocserv log before posting it.
Because of the execution of the certbot command as sudo, I suspect that this may be a permissions issue, because as a regular user I cannot access the certificates directory.
However, I have tried the following:
– Running ocserv as a root user (just for testing)
– changing permissions and owner of the certificates.
ocserv is still unable to read the certificates, at this point I’m not sure if it’s an issue with the certificate.
you have a space ‘/etc/letsencrypt/live//fullchain.pem ‘ remove space
The problem is that ocserv can’t load the TLS certificate file. Please make sure the TLS certificate exist in the /etc/letsencrypt/live/vpn.example.com/ directory and double check your /etc/ocserv/ocserv.conf file.
From the log, I suspect that you added a whitespace at the end of the TLS certificate path.
What do you think about outline vpn
I haven’t set up outline VPN yet. From I have learned, Outline is based on Shadowsocks, which is a SOCKS5 proxy, not a VPN. Shadowsocks is very popular with Chinese netizens, used as a tool to bypass the Great Firewall. I have been using Shadowsocks for 3 years. It’s super fast.
it is super easy to set up. Can you please write a review about it
Thank you, real detailed guide.
Love this guide. Is there anything we can do to enable having an IPV6 address along with an IPV4 address?
Please read the following tutorial to set up IPv6.
Ocserv Advanced (Split Tunneling, IPv6, Static IP, Per User Configs, Virtual Hosting)
Thanks, this is really a great guide 🙂
Excellent guide! Thank you so much!!
I hope this help
I have successfully upgrade to TLS1.3
Hi Xiao Guo An
Thanks for fantastic post. I installed ocserv on ubuntu 18.04 and its worked like charm.
I want to create bunch user(more than 500 user) and I need to set some expiration period date after first users connection(like 3 month, 6 month etc… after first connection to the server).
Could you please guide me to do that?
Thanks.
how can I use the sql database to connect VPN users with ocserv server without using ocpassd file?
Hello, thanks for the great article. One comment, do not disable UDP because you think it’s unreliable. Your payload (in the tunnel) decides if its require an unreliable connection and if yes it uses in the tunnel TCP.
So if a TCP (in tunnel) package (e.g. HTTP package) gets lost it’s resent automatically again caused by the payload and not because of the VPN tunnel an that within an fast UDP frame. UDP performs much faster because it does not wait for ACKs on long distances and assume you stream video via UDP – if a package get’s lost it doesn’t make sense to resend it, if you put TCP around it resends it (and throws it away on destination but blocks your link).
I know it’s not an ideal solution, but using TLS on TCP port 443 is the only way to survive the great firewall of China. If I enable UDP, my openconnect client would complain about DTLS handshake failure.
I’ve tried this on a couple of servers now, my home server and a VPS I rent that both run Ubuntu 18.04, and I get the following error on each:
I tried googling for an answer, and all I could see was that there was an issue with the ports being used. Now I have webservers running on each (apache on one and nginx on the other) and I changed the port for ocserv to 8443 on each as per the tutorial for each type of server. I even tried creating /etc/systemd/system/ocserv.socket.d/port.conf file to no avail. Any help is apprceiated. 谢谢.
Double check your configuration file and the /etc/systemd/system/ocserv.service file. I can’t help fix an error that I didn’t encounter myself.
After thinking about it a bit, I realized I didn’t reboot the server (it never prompted me to), so I tried that and it fixed the issue.
Best VPS for openconnect where you can change IP in case of blockage by your country without rebuilding VPS: https://www.vultr.com/
how do I add mfa to it?
You can configure ocserv to require users to pass both certificate authentication and password authentication. That’s two factor authentication without a one-time passcode.
Set up Certificate Authentication in OpenConnect VPN Server (ocserv)
Hi Guoan,
Thanks for such a detail document and I tried to follow step by step to build my VPN server. But I met a UFW forwarding issue after inserted this part to /etc/ufw/before.rules
After doing that, I tried to restart the UFW, but it told me below, “Bad argument `*nat'”
The part I added into the before.rules is like below,
Checked the steps for several times but found nothing missed.
Could you please show me some hints?
I’m using 18.04 version.
Thx in advance,
Jonny Li
ok, I got the answer now, Still didn’t fully focus on reading.
“Add the following lines at the end of this file. Replace ens3 with your own network interface name.”
thx
Jonny Li
Hello there
I am noob and I want to know what does the Domain Name use for and this Domain Name should be linked to which host? does it need to be linked to the vps I wanna run openconnect on it or what?
First, you need to buy a domain name from a domain registrar like NameCheap. Then you should create a DNS A record for vpn.your-domain.com at your domain registrar’s website. The value of DNS A record is the IP address of your VPS.
Hello, first sorry for my English. Congratulation for the article.
I have 2 questions
1. I didn’t manage to fix “DTLS Handshake Failure”. I have done everything you have write above, probably there it’s something that i didn’t understand.
2. If i want to use application openvpn for windows to connect to the vpn server, i have to use my own CA, right?
Thank you very much and go on with these kind of articles
1. Which part you don’t understand?
2. You can’t use OpenVPN client to connect to the OpenConnect VPN server. OpenVPN and OpenConnect VPN are two different VPN protocols. You need to use the OpenConnect Client for Windows. And if you followed my tutorial, your OpenConnect VPN server is configured with a valid SSL/TLS certificate. You just need to enter the server address, username and password in the OpenConnect Client.
Thank you very much for your fast answer
2. I messed up the names 🙂 I thought that OpenVPN and OpenConnectVPN (the only difference it’s “connect” 🙂 ) it’s the same program 🙂 don’t laugh too loud 🙂
1. I guess that I didn’t understand something because even if I commented out the two lines that contain “ocserv.socket” and I disabled the service, I have the same problem with “handshake”
Happy New Year
P.S. or L.E.
I found out what was the problem :). The vpn server it’s behind a router and I was having opened only 443 tcp port, udp port wasn’t :). After I’ve opened udp port…everything it’s working well.
Don’t forget, keep going with these kind of articles 🙂
if some one looking for a openconnect vpn panel and custom applicaton where you can make bulk accounts auto expiry and many more thing just contact me
my portfolio: https://www.fiverr.com/share/8zYZ34
tnx for the useful article that help me so many time
but for now i need the connected user can see eche other in the private network for example i want to client1 that connect to openconnect can see the web server of client2
do you think that is possible?
They are in the same private network, so they can ping each other. If the web server is set to listen on all interfaces, then other hosts in the private network can browse the website.
Dear Xiao
I Done it all and its all ok. I even created multiple accounts and speed is good.
BUT
With some internet connection I Get this:
The secure gateway has rejected the connection attempt. A new connection attempt to the same or another secure gateway is needed, which requires re-authentication
I couldn’t find anything solid about it. The error is ambiguous to me.
If its helpful , I can send you the ocserv.conf
Great article.
I learned a lot.
It’s likely that you made multiple connection requests to the ocserv server from the same client.
Dear Xiao Guoan, is it possible to disable the timeout ocserv when not in use, and the locked phone turns off the tunnel after 15-20 minutes?
Is there any way to assure that time?
yes, it is possible through connect.sh script.
if you looking for a solution you can contact https://www.fiverr.com/share/8zYZ34
Hi
thanks for a really good guide.
but I have a problem:
I have a mtproto proxy running (https://github.com/alexbers/mtprotoproxy) on port 443 and I launched ocserv VPN on port 4443 they work OK when I use them separately, but when my VPN is on I can’t use my mtproto.
is there a fix for that so I don’t have to turn my mtproto off on my client device everytime I turn on VPN ?
You could add an additional IP address to your server, so MTProtoProxy and ocserv can listen on TCP port 443 on different IP addresses.
Hi Buddy, this is an excellent guide, great job! Thank you.
Thanks for your great article.
I didn’t find any article on the web that guide step by step so thanks to you again.
I’ve set it up on my VPS and it works properly.
Now I’m trying to put my server behind Cloudflare. Everything works well but in the last step of connection I get this:
and connection drop.
any hint?
OpenConnect VPN doesn’t work with Cloudflare CDN. You can use the Cloudflare DNS service, but don’t enable proxy in Cloudflare for your VPN server.
Go to cloudflare, DNS tab, DNS management section, and disable proxied(DNS only) for vpn.example.com record.
I did and works for me.
if some one looking for a openconnect vpn panel and custom applicaton where you can make bulk accounts auto expiry and many more thing just contact me
my portfolio: https://www.fiverr.com/share/8zYZ34
Hi,
Is there a way to not using Masquerading, just using route for packet forwarding?
I’ve been tried various ways but still no luck, and googled with some similar explorations of openvpn, which involved configuration on openvpn side.
It is because I am using a server behind NAT to run ocserv, if using Masquerading to forwarding packets, it would be double-NAT. Other scenarios including prioritizing various clients based on the ip they got, in which case, using Masquerading will lost original assigned ip info of these clients.
This is the best openconnect tutorial I’ve seen. Thank you
Hi Xiao,
many thanks for this (and all the other) great guide, it worked perfectly 100% without even one single error.
And the VPN works amazing.
I installed the ocserv in a Vultr VPS, and I have 2 additional IPv4 on that server.
My question is the following:
Is it possible to have a rotating IP for the VPN server?
So for example the external IP will switch every 8h (just as an example).
Many thanks for your great and inspiring work!
Thank you!
You can set up SNAT (Source NAT) in the firewall like this:
So the firewall will change IP address every other packet. You probably want to change 2 to a much bigger value like 1,000,000
hello i am trying to make the per-user-group for deferent levels of vpn, but when I make the group file and restart the server. I get the error
To add a user to a group, run
Then restart ocserv.
I did that, and still getting the error.. I added the two groups with the config for the routes in each per-user-group folder.. and uncommented the following lines to allow a drop down to select which group you want at login
so I got the group to work but what i am finding is i can’t add one user to two groups.
How can I connect a MikroTik router to this VPN&
As far as I can tell, MikroTik router doesn’t support OpenConnect VPN, but it does support SSTP VPN protocol, which is another HTTPS-based VPN protocol.
You can set up an SSTP VPN server with SoftEther, which is a multi-protcol VPN server, including OpenVPN, L2TP, IPSec and SSTP.
How to Set Up SoftEther VPN Server on Ubuntu 22.04/20.04
Hello. Thanks for great article.
Can I block some website ips, for example users can not connect to youtube.com or specific ip?
Any suggestion?
You can install a BIND DNS resolver on the VPN server and force all VPN clients to use this DNS resolver. Then set up Response Policy Zone to block youtube.com.
awesome blog to share
Hello, Thanks for your instruction. it worked for me, but I want another help to extend VPN compatibility. Assume I have two servers, A and B. Server A is on an interanet with some limitations, and server B is a free server on the internet without any limitations. My client can’t see server B but has access to server A. I have installed ocserv on server A and the client can connect to it successfully. Is there any way to tunnel server A through server B to connect to use server B’s internet? I tried
and even though it changed the server A IP address, after connecting to it by openconnect, the limitations still remain.
You can set up VPN relay with HAProxy.
On server A, install HAProxy.
Stop ocserv.
Edit main configuration file.
Create a front end and back end just like before. Replace 12.34.56.78 with server A’s public IP address. Replace 12.34.56.79 with server B’s public IP address.
Save and close the file.
On server B, you should enable proxy protocol in ocserv.
Uncomment the following line.
Restart ocserv on server B.
Restart HAProxy on server A.
Topology:
HAProxy will transparently redirect client requests to server B, without the client knowing it.
You may need to change the DNS A record of the ocserv hostname on server B to the IP address of server A.
Hi guys,
Imagine we can’t use proxy here, we can use sshuttle
Server A can’t access to server B with proxy like socks5 or others.
We wanna use sshuttle from A to B
I undrestand the whole part ecxept what should we do with domain after buying that, i mean the configuration or is it possible to use it without domain?
and also thanks for this amazing article
You should buy a domain. ocserv can’t work with IP address only. After buying a domain name, you should create a DNS A record for vpn.your-domain.com, pointing it to the IP address of your server.
Hi,
Thanks for the provided information. There are sometimes IP restriction in some countries to access a service. So I need to configure a server on a specific country to get access to the specific service. I need to hide my client IP address after connecting to ocserv.
Right now after connecting to the server my client IP is still detectable, But I want the server to hide it and make it inaccessible.
Would you please contribute on how to achieve this goal.
Thanks.
hi dear
i set up open connect with your guide.
all device connect to server and work correctly, bud iphone cellphones not open any site or application.
iphone connect to server after authentication but cant connect to web or application.
i try on 3 vps.
i use ubuntu 18.04 TLS 64bit
can you help me!
Hi Xiao Guoan
Thanks for the provided information.
I have a problem and I posted a picture of this.
Please help me.
Thanks.
If you look carefully at the log, it said it can’t find the socket, and next, it initialized this socket (/run/ocserv.socket.6a50f5b5). So ocserv solved the problem by itself, right? 🙂
Every ocserv instance has this phenomena. I think the ocserv developers should change the wording to make users not worry about it.
Hi Xiao Guoan
I can’t connect to the OpenConnect.
I have a problem again and I posted a picture of this.
Please help me.
Thanks.
Hi Xiao Guoan
Thanks for for guide
Why can I connect with open connect on my computer, but I can’t connect with anyconnect on my iPhone?
Hi Dear, can you tell me how I can connect PAM radius to ocserv, I did that but I still can’t connect
I’m using IBSng Radius
on Centos 7, I can use PAM Radius 1.4.0 easily, but in Ubuntu can’t use it
I’m thinking of migrating from Centos 7 to Ubuntu 22 due to more compatibility
can you help me with it, please?
Dear Xiao Guoan, I need your help, please check it, thanks a lot
Thanks for this great tutorial. I get this error on the client side.
TLS connection was non-properly terminated
And I do exactly what you have said about this error, but to avail. I search the whole internet but nothing solve it. Can it be because the certificate is new? Is any way not to use a ssl connection to connect to the server?