Press "Enter" to skip to content

OpenConnect Server with Duo Two-Factor Auth in Ubuntu 16.04

Ever need access to your home network, but you are somewhat locked into the Cisco AnyConnect client for some reason?  OpenConnect Server is a great alternative to OpenVPN for these situations, and the OpenConnect client is commonly used on Linux distros to connect to Cisco AnyConnect servers.  In my case, I use a combination of Windows, Mac, and Linux some of which are rather locked down.

In my case, I setup a single-purpose Ubuntu 16.04 LTS VM for this running the bare minimum of Ubuntu, OpenSSH for remote support, and occserv.  I won’t detail the step-by-step of the OS install as there are hundreds of howtos which can walk you through it.  Remember: This server is internet exposed – lock it down tight!

Once you have the base server setup, run the following to get ocserv installed:

sudo apt update && sudo apt install ocserv gnutls-bin

Now, you will need to setup either a self-signed certificate or purchase a third-party certificate.  As a security professional, I would strongly encourage you to purchase a third-party cert simply for the added protection.  In my case, I created a self-signed cert for now with the intention of coming back later to correct the issue.

cd /etc/ocserv
sudo nano ca.tmpl

Then create the certificate template similar to the format below:


Once you have your template completed, run the certtool and generate your CA certificate:

sudo certtool –generate-privkey –outfile ca-key.pem # generates the private key
sudo certtool –generate-self-signed –load-privkey ca-key.pem –template ca.tmpl –outfile ca-cert.pem

Next, you will need to create the server certificate template:

sudo nano server.tmpl

Create the template similar to below – your CN should match the host address of your vpn server.


Next, generate the private and public keys for your server:

sudo certtool –generate-privkey –outfile server-key.pem
sudo certtool –generate-certificate –load-privkey server-key.pem –load-ca-certificate ca-cert.pem –load-ca-privkey ca-key.pem –template server.tmpl –outfile server-cert.pem

Now that your certificates have been created, it’s time to configure ocserv

cp ocserv.conf ocserv.conf.original # just in case you screw up 🙂
nano ocserv.conf

Since we are going to use PAM authentication (local Ubuntu user accounts), we need to comment out everything but the PAM module (see below).

#auth = “pam”
auth = “pam[gid-min=1000]”
#auth = “plain[passwd=./sample.passwd,otp=./sample.otp]”
#auth = “plain[passwd=./sample.passwd]”
#auth = “certificate”
#auth = “radius[config=/etc/radiusclient/radiusclient.conf,groupconfig=true]”
##auth = “plain[/etc/ocserv/ocpasswd]”

Then find the server-cert/server-key stanza and ensure they are pointing to your public/private key pair.

server-cert = /etc/ocserv/server-cert.pem
server-key = /etc/ocserv/server-key.pem

I would also change the DNS server to your local network DNS.  This allows you to both access any DNS-named local resources and avoid DNS-hijacking attacks while using your VPN connection.
dns = # set to your internal DNS server
Next setup your internal network routes:
route =
route =
Now save the file and close nano.
You will also need to change IPTABLES and SYSCTL to allow ocserv to work:
iptables -A INPUT -p tcp –dport 443 -j ACCEPT
iptables -A INPUT -p udp –dport 443 -j ACCEPT
iptables -t nat -A POSTROUTING -j MASQUERADE
nano /etc/sysctl.conf


Uncomment “net.ipv4.ip_forward=1” similar to below:

# Uncomment the next line to enable packet forwarding for IPv4


Now activate the changes to sysctl:
sudo sysctl -p
Now test using Cisco Anyconnect or OpenConnect to see if you can log in before we setup Duo.  (If you have any issues, DM me on twitter or comment here and I will try to help.)
OK – Assuming you have OpenConnect up and running and a Duo Free account, we can setup two-factor authentication.
First – install and configure the Duo Unix plugin based on the instructions for Ubuntu 16.04 located here:
Create the link to the DUO repository by running the following command:
sudo echo ‘deb xenial main’ > /etc/apt/sources.list.d/duosecurity.list
curl -s | sudo apt-key add –
sudo apt update && sudo apt install duo-unix
Edit /etc/duo/pam_duo.conf to include your Duo keys and host.  I also added autopush because I despise having to type “push” on a normal Cisco Anyconnect client connection.
WARNING!  Do not close your primary SSH/Console session from this point forward!  If Duo doesn’t work the first time (which it didn’t for me) you might be hosed.  Use a new SSH session to test for the prompts.  Trust me!
In my case, I ran into trouble trying to get the proper PAM config.  After attempting a few different ways to get Duo to prompt globally, I settled on commenting out everything in /etc/pam.d/common-auth and using this config:
# auth [success=1 default=ignore] nullok_secure
auth requisite nullok_secure
auth [success=1 default=ignore] /lib64/security/
auth requisite
auth required
Notice the /lib64/security/  Without the path as part of the statement, I could not get Duo to work.  If you are successful, your test SSH session should ping your Duo device before allowing you to log in.
Did it work?  OK now try another test connection to OpenConnect.  It should also prompt you to accept the login via Duo.
I hope this helps you and would love to hear back if it does.

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *