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:

 cn="YourOrgNameCA"  
 organization="YourOrgName"  
 serial=1  
 expiration_days=3650  
 ca  
 signing_key  
 cert_signing_key  
 crl_signing_key  

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.

 cn="vpn.yourorgname.blah"  
 organization="YourOrgName"  
 expiration_days=3650  
 signing_key  
 encryption_key  
 tls_www_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 = 10.10.10.10 # set to your internal DNS server   
Next setup your internal network routes:
 route = 10.10.10.0/255.255.255.0  
 route = 10.10.20.0/255.255.255.0  
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  
 net.ipv4.ip_forward=1  

 

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: https://duo.com/docs/duounix#linux-distribution-packages
Create the link to the DUO repository by running the following command:
 sudo echo 'deb http://pkg.duosecurity.com/Ubuntu xenial main' > /etc/apt/sources.list.d/duosecurity.list  
 curl -s https://duo.com/APT-GPG-KEY-DUO | 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.
 [duo]  
 ikey=DIXXXXXXXXXXXXXXXXXX  
 skey=X1hXztPX1rb1X71x1wXkpnmXXvqXXXqqj1XoXbbXu  
 host=api-xxxxxxxx.duosecurity.com  
 pushinfo=yes  
 autopush=yes  
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:
 ##FOR DUO##  
 # auth [success=1 default=ignore] pam_unix.so nullok_secure  
 auth requisite pam_unix.so nullok_secure  
 auth [success=1 default=ignore] /lib64/security/pam_duo.so  
 auth requisite pam_deny.so  
 auth required pam_permit.so  
Notice the /lib64/security/pam_duo.so?  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.
Sources:

  • https://lowendbox.com/blog/install-openconnect-server-on-ubuntu-16-04/
  • http://ocserv.gitlab.io/www/recipes-ocserv-2fa.html#Duo
  • https://duo.com/docs/duounix

Leave a Reply