Tutorial: Add Duo Two-Factor Authentication to Access Server
Follow these instructions to add Cisco's Duo two-factor authentication to your users’ Access Server logins.
Overview
Adding Duo 2FA to Access Server provides your business with enhanced security. You’ll provide remote, encrypted connections for users and strengthen authentication by introducing a second factor.
With Duo integration, users can authenticate using:
Push notifications (Duo Mobile app)
SMS passcodes
Phone call verification
Access Server also has built-in TOTP MFA support.
Important
If you are using Duo MFA, do not enable TOTP MFA, as it will cause user authentication problems.
When configured, the authentication flow works as follows.

The user signs in with OpenVPN Connect.
Access Server authenticates username and password (primary auth).
Access Server notifies Duo via HTTPS API to begin the 2FA procedure.
Duo sends secondary auth via the user’s chosen method.
The user sends a correct response.
Duo sends an authentication response back to Access Server.
OpenVPN connection established.
Prerequisites
A Duo account.
An installed Access Server.
Sign in to the Duo Admin Panel and configure Access Server as a protected application.
Sign in to the Duo Admin Panel.
Click Applications.
Click Protect an Application.
Search for OpenVPN Access Server.
Click Protect.

Access Server is added to your Duo-protected applications.
Note the following values for later use:
Integration key
Secret key
API hostname
Download and configure the Duo post-authentication script, then apply it to Access Server.
Option 1: Download directly on the Access Server
Connect to your Access Server console and get root privileges.
Change to the scripts directory:
cd /usr/local/openvpn_as/scripts/
Download the Duo post-auth script:
wget https://raw.githubusercontent.com/duosecurity/duo_openvpn_as/master/duo_openvpn_as.py
Insert your Duo credentials:
sed -i \ -e "s|^IKEY = '.*'|IKEY = 'DUO_INTEGRATION_KEY_HERE'|" \ -e "s|^SKEY = '.*'|SKEY = 'DUO_INTEGRATION_SECRET_KEY_HERE'|" \ -e "s|^HOST = '.*'|HOST = 'DUO_API_HOSTNAME_HERE'|" \ duo_openvpn_as.py
Replace:
DUO_INTEGRATION_KEY_HERE→ Your Duo key.DUO_INTEGRATION_SECRET_KEY_HERE→ Your Duo secret key.DUO_API_HOSTNAME_HERE→ Your Duo API hostname.
Verify the values:
grep -E "^(IKEY|SKEY|HOST)" duo_openvpn_as.py
Load the script and restart the Access Server service:
sacli --key "auth.module.post_auth_script" --value_file="/usr/local/openvpn_as/scripts/duo_openvpn_as.py" ConfigPut sacli start
Test your setup by signing in as a VPN user.
Tip
Test with both an enrolled Duo user and a new user.
Duo also provides additional documentation on its website: OpenVPN Access Server Documentation, OpenVPN Access Server FAQ page, and OpenVPN Knowledge Base articles.
Option 2: Configure on an external machine
Download the Duo OpenVPN Access Server package from GitHub.
Extract the Duo OpenVPN Access Server package.
Open the duo_openvpn_as.py script with a text editor.
Find the section where you fill in your integration credentials and enter your integration key, secret key, and API hostname:
# Fill in your integration credentials on the following three lines: IKEY = 'DUO_INTEGRATION_KEY_HERE' SKEY = 'DUO_INTEGRATION_SECRET_KEY_HERE' HOST = 'DUO_API_HOSTNAME_HERE'
Replace:
DUO_INTEGRATION_KEY_HERE→ Your Duo key.DUO_INTEGRATION_SECRET_KEY_HERE→ Your Duo secret key.DUO_API_HOSTNAME_HERE→ Your Duo API hostname.
Connect to your Access Server console and get root privileges.
Move or upload the duo_openvpn_as.py script to the Access Server scripts folder (/usr/local/openvpn_as/scripts/) on your server.
Connect to your Access Server console and get root privileges.
Load the script and restart the Access Server service:
sacli --key "auth.module.post_auth_script" --value_file="/usr/local/openvpn_as/scripts/duo_openvpn_as.py" ConfigPut sacli start
Test your setup by signing in as a VPN user.
Tip
Test with both an enrolled Duo user and a new user.
Duo also provides additional documentation on its website: OpenVPN Access Server Documentation, OpenVPN Access Server FAQ page, and OpenVPN Knowledge Base articles.
Verify that Duo MFA works in both the Admin/Client Web UIs and VPN connections.
Test with Admin or Client Web UI
Sign in with your credentials to the Admin Web UI or Client Web UI.
The Duo MFA prompt displays:

Enter a Duo factor:
Passcode
push→ It will perform a Duo push authentication.phone→ It will perform a phone call.sms→ It will send a new batch of SMS passcodes. Your authentication attempt will be denied. You can then authenticate with one of the new passcodes.
Complete authentication.
Important
Phone calls and SMS authentication consume Duo telephony credits. Refer to:
Test with VPN
Connect using OpenVPN Connect.
Enter your credentials.
The Duo MFA prompt displays:

Enter a Duo factor:
Passcode
push→ It will perform a Duo push authentication.phone→ It will perform a phone call.sms→ It will send a new batch of SMS passcodes. Your authentication attempt will be denied. You can then authenticate with one of the new passcodes.
Complete authentication.
Important
Phone calls and SMS authentication consume Duo telephony credits. Refer to:
Optionally restrict authentication to Duo Push only.
Connect to your Access Server console and get root privileges.
Change to the scripts directory (where your Duo post-auth script is located):
cd /usr/local/openvpn_as/scripts/
Enable AutoPush:
sed -i "s|^AUTOPUSH = False$|AUTOPUSH = True|" duo_openvpn_as.py
Verify the change:
grep -E "^(AUTOPUSH)" duo_openvpn_as.py
Reload the configuration and restart the Access Server service:
sacli --key "auth.module.post_auth_script" --value_file="/usr/local/openvpn_as/scripts/duo_openvpn_as.py" ConfigPut sacli start
After this change, only Duo Push authentication will be used.
If you no longer use Duo for your users and need to remove the integration, follow these steps:
Connect to your Access Server console and get root privileges.
Remove the Duo setup:
sacli --key "auth.module.post_auth_script" ConfigDel
Reload the service to commit the changes:
sacli start