07 Feb 2020 - by 'Maurits van der Schee'
In a previous post I have shown how to add an IPsec IKEv2 VPN to your (Ubuntu 18.04) KVM setup. In this post I will show you how to add and configure OpenConnect VPN. I will show how to install the VPN endpoint on a virtual machine, as a replacement for the VPN installation that we did in the previous post. OpenConnect may be easier to setup and maintain, but it is not clientless on Windows 10 and does require a (user-friendly and free) VPN client.
First you need to install the OpenConnect VPN software (on Ubuntu 18.04):
sudo apt install ocserv
The config file for this software is "
In this tutorial I assume that you are running the VPN server as a guest on your KVM host machine and that the KVM host machine is running UFW.
Add the following to "
/etc/ufw/before.rules" in the "nat" chain (as explained in the pevious post) on the KVM host:
-A PREROUTING -i eno1 -p tcp -d 188.8.131.52 --dport 8443 -j DNAT --to-destination 10.0.122.8 -A PREROUTING -i eno1 -p udp -d 184.108.40.206 --dport 8443 -j DNAT --to-destination 10.0.122.8
Note that in this example "220.127.116.11" is the public IP address of the KVM host and "10.0.122.8" is the (private and only) IP address of the VPN server.
If you run a webserver you have probably forwarded port 80 to this webserver. Since we want to use "certbot" we need to configure a proxy forward for the specific hostame of your VPN server. We use "
mod_proxy_http" for this.
sudo a2enmod proxy_http
Then add the following in "
<VirtualHost *:80> ServerName vpn.tqdev.com # Proxy all requests ProxyPreserveHost On ProxyPass / http://10.0.122.8:80/ </VirtualHost>
Replace "10.0.122.8" with the internal IP address of your VPN server and "vpn.tqdev.com" with the hostname you use for your VPN server.
To install the latest "certbot" you may run:
sudo add-apt-repository ppa:certbot/certbot sudo apt update sudo apt install certbot sudo certbot certonly --standalone --preferred-challenges http -d vpn.tqdev.com sudo nano /etc/letsencrypt/renewal/vpn.tqdev.com.conf
A text file will open with some configuration options. Add your hook on the last line:
renew_hook = systemctl restart ocserv.service
Save and close the file, then run a "certbot dry run" to make sure the syntax is ok:
sudo certbot renew --dry-run
This command should give a warning:
Dry run: skipping deploy hook command
And otherwise run correct, printing:
Congratulations, all renewals succeeded.
Showing that certbot configuration is correct.
We configure OpenConnect by editing the file "
/etc/ocserv.conf" so that it has the following content:
auth = "plain[/etc/ocserv/ocpasswd]" tcp-port = 8443 udp-port = 8443 run-as-user = nobody run-as-group = daemon socket-file = /var/run/ocserv-socket server-cert = /etc/letsencrypt/live/vpn.tqdev.com/fullchain.pem server-key = /etc/letsencrypt/live/vpn.tqdev.com/privkey.pem ca-cert = /etc/letsencrypt/live/vpn.tqdev.com/chain.pem use-occtl = true max-clients = 25 max-same-clients = 1 device = vpns dns = 10.0.122.1 # client addresses: 10.0.122.66-10.0.122.94 ipv4-network = 10.0.122.64/27 default-domain = kvm route = 10.0.122.0/255.255.255.0
Make sure the "leftid" matches your hostname prefixed with an "at" sign (which means: don't resolve). Adjust the "leftsubnet" to match with your private network and the "rightsourceip" with the (virtual) ip addresses you want to give to clients connecting to your VPN server.
If you want to capture all traffic and set the default route over the VPN tunnel, you need to set:
route = default
Using the command "
ocpasswd" you can add users to the file "
sudo ocpasswd -c /etc/ocserv/ocpasswd username1
The password is not stored in plain text. If you want to know who is connected, run:
sudo occtl show users
Use "occtl help" for other management features.
You probably noted the "
default-domain = kvm" line in the config. It allows VPN clients (and virtual machines) to contact each other by name. This configuration is called "split-DNS". In order to add it you must edit the network configuration using:
virsh net-edit default
Look for the line:
<ip address='10.0.122.1' netmask='255.255.255.0'>
Add a domain configuration on the line before it, like this:
<domain name='kvm' localOnly='yes'/> <ip address='10.0.122.1' netmask='255.255.255.0'>
Now this setting allows the named virtual machine "
maurits-cloud" to be reached by other virtual machines on the hostname "
This will NOT be effective until you destroy and start the network.
Add the following lines to the end of the file "
/etc/sysctl.conf" to make your Linux machine act as an IPv4 router:
# enable ipv4 routing net.ipv4.ip_forward = 1 net.ipv4.conf.all.proxy_arp = 1
Note that the "proxy_arp" is an alternative for masquerading all traffic on the VPN host. Now you need to run:
sudo sysctl -p
This command reloads sysctl config file and makes the settings effective.
Although connecting might succeed, it may connect slow and you may encounter the following message in the (sys)log:
DTLS handshake failed: Resource temporarily unavailable, try again.
To fix this error, we need to edit the "/lib/systemd/system/ocserv.service" file. First copy it from the "/lib/systemd/system/" directory to "/etc/systemd/system/" directory. This avoids your modifications from being overridden or reverted by a package update.
sudo cp /lib/systemd/system/ocserv.service /etc/systemd/system/ocserv.service sudo nano /etc/systemd/system/ocserv.service
Comment out the following two lines:
Save and close the file. Then reload systemd and restart ocserv service.
sudo systemctl daemon-reload sudo systemctl stop ocserv.socket sudo systemctl disable ocserv.socket sudo systemctl restart ocserv.service
The ocserv systemd service won’t output any message if it fails to restart, so we need to check the status to make sure it’s actually running.
systemctl status ocserv
It should show "active (running)".
If you are connecting from Windows 10, then you need to install external client software for this VPN connection.
If you use Ubuntu, then you also need to install a client. You can do so by running:
sudo apt install network-manager-openconnect-gnome
If you don't see the VPN option marked "openconnect" in the network manager applet, then you may have to log out and in for it to appear.
In the next post I will show you how to add an IKEv1 L2TP to your KVM setup. I will show how to install the VPN endpoint on a virtual machine, as a replacement for the VPN installation that we did in this (and previous) post. IKEv1 L2TP may be easier to configure than IKEv2 and also does not require a VPN client on Windows 10.