OpenConnect VPN Server and Windows Client

OpenConnect is an SSL VPN initially created to be compatible with Cisco’s AnyConnect SSL VPN. This article shows you how to install OpenConnect on a server and on a Windows client.


Begin by visiting DigitalOcean and opening and funding an account. If you use my link, they may reward you with an extra credit when you add funds for the first time. Follow the remainder of the article Basic Linux VPS Set Up from a Windows PC to create and set up your “droplet” (VPS). For China, you will likely get the best performance if you locate your droplet in San Francisco.

This article uses Ubuntu 16.04. If you selected a different Linux distribution, you will need to make appropriate changes to the Linux commands.

When you have created your droplet, continue as follows.

The first thing we’re going to do is to open the firewall. We need to open port 443 for TCP and UDP. Assuming you’re using iptables as your firewall, it’ll look like this:

sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

sudo iptables -A INPUT -p udp --dport 443 -j ACCEPT

So that’s the firewall opened. We’re also going to need to do network address translation (NAT) on output packets going from our VPN to the outside world. That’s also done with iptables. In this example, we are using the range for our VPN, so:

sudo iptables -t nat -A POSTROUTING -s -j MASQUERADE

Again, note that long commands may span multiple lines on this web page, but they must be entered as a single command.

MASQUERADE only works with KVM and Xen, which is fine for DigitalOcean, but not necessarily for other VPS providers.

Now we save those changes to iptables to make them persist across reboots. We do that by reconfiguring the iptables-persistent package:

sudo dpkg-reconfigure iptables-persistent

That’s the firewall done.

The next thing we need is to get an SSL certificate for the OpenConnect server to use. We can get free SSL certificates from Let’s Encrypt.

Before you do this, you will need to set up the DNS records for your host name

Then you are ready to install the Let’s Encrypt client:

sudo apt-get install letsencrypt

When it’s installed, we request our certificate like this:

sudo letsencrypt certonly --standalone -m --agree-tos -d

Of course, you must substitute in your choice of email address and server name.

You leave that to run for a minute. When it’s done, it displays a message to the effect, “Congratulations, I’ve issued you a certificate, and here’s where it is.”

You’ll have to renew that certificate every ninety days. First, test the effects of the renewal command with the --dry-run option:

sudo letsencrypt renew --dry-run -m --agree-tos

Since we are not within thirty days of expiry, the dry run of renewal will do nothing at this time.

We will set up a cron job to check for renewal every week. Most weeks, it will check for pending expiry of the Let’s Encrypt SSL certificate and discover that nothing needs to be done yet. Once we get within thirty days of expiry, it will do the actual renewal.

Edit a new file for the renewal script:

sudo vi /usr/local/bin/

Insert the following contents:

export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
letsencrypt renew > /var/log/letsencrypt/renew.log

Press Esc to get out of insert mode, and type :wq to write the file out to disk and quit the editor.

Make the script executable:

sudo chmod +x /usr/local/bin/

Since the script must be run as root, edit root’s cron job table by issuing the command:

sudo crontab -e

If this is the first time you have used crontab, you will be prompted to select an editor. At the end of the crontab file, insert a single line that reads:

12 3 * * 4 /usr/local/bin/ > /var/log/letsencrypt/renew.log 2>&1

This says that at 3:12 a.m. every Thursday (day 4), run the script, and send the output of the script to the file /var/log/letsencrypt/renew.log.

Write the crontab out to disk, and quit the editor.

You can check your crontab by issuing the crontab list command:

sudo crontab -l

You can check the results of the renewal process by periodically looking at the renewal script log file to see what the Let’s Encrypt client has done:

sudo cat /var/log/letsencrypt/renew.log

Now that that’s in place, we can the install the OpenConnect server package:

sudo apt-get install ocserv

We configure it by editing the OpenConnect server configuration file:

sudo vi /etc/ocserv/ocserv.conf

The first thing we’re going to do is to comment out the pluggable authentication module (PAM). Do that by inserting a hash sign at the beginning of the line. We’re going to do our authentication by just putting the password in a file. You specify that as:

#auth = "pam[gid-min=1000]"
auth = "plain[/etc/ocserv/ocpasswd]"

The next thing we have to change is the location of the server certificate and key. We got ours from Let’s Encrypt, so we have to give the location that Let’s Encrypt puts its certificate and key in:

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

Remember, of course, to change to your own server name in the above. The files in /etc/letsencrypt/live/ are actually symbolic links to the latest certificate and key. So when you renew the certificate, you don’t have to change those lines. They’ll always point to the most recent certificate and key.

A few more changes we have to make. We have to change try-mtu-discovery from false to true:

try-mtu-discovery = true

And then the pool of IP addresses we want it to use. As you recall, we are using in this example.

ipv4-network =

You can use that range, providing it’s free, but you may want to choose another one. If you do that, adjust the firewall’s NAT rule accordingly.

So that’s the range of IP addresses OpenConnect is going to issue to clients.

We’re going to use the OpenDNS servers, so delete the defaults and change them to:

dns =
dns =

We don’t need any special routes, so comment out those by putting a hash sign at the beginning of the line:

#route =

#route =

#no-route =

And that’s the changes to configuration done.

Press Esc to get out of insert mode, and type :wq to write the file out to disk and quit the editor.

We’re going to use username and password authentication for the clients. You generate those with a utility that comes with ocserv, and which is named ocpasswd:

sudo ocpasswd -c /etc/ocserv/ocpasswd derek

Choose a password and re-enter it.

The next thing we need to do is to allow forwarding by the Linux kernel. We do that by editing the system control configuration:

sudo vi /etc/sysctl.conf

Uncomment the line shown below, so that it allows packet forwarding in the Linux kernel:


Write that to disk, and quit the editor.

Make that active now, rather than at the next reboot, by doing:

sudo sysctl -p

And that’s it. That’s all the configuration of the server done. So now we just set that going:

sudo systemctl stop ocserv.socket

sudo systemctl start ocserv.socket

And that’s the server set up.


Now for the client. We get the OpenConnect GUI client for Windows from Github. So go to:

You want the latest release from the releases tab. Find the latest executable. Download that and save it.

When it’s downloaded, double-click on it to execute it. That’ll take you into the setup wizard. You can pretty much just accept the defaults there.

We’ll run OpenConnect VPN straight from the install.

We have to create a new profile:

OpenConnect GUI create new profile

Press Save & Connect.

It will ask you for your username.

OpenConnect GUI username

It will ask you for the password you specified on the server.

OpenConnect GUI password

It will then connect, and the lock icon turns green.

OpenConnect GUI connected

Then, if you ask Google or Bing, “What is my IP address?” (without the quotes), you’ll get the IP address of your VPN gateway server rather than your home IP address. That proves that you’re connected and that everything is working as intended.