App Support.

We're here to help.



U2F Two-Factor Authentication with OpenVPN and Viscosity

After setting up your own OpenVPN server, you may want to enhance its security by requiring two-factor authentication. This guide will expand on setting up an OpenVPN server on Ubuntu by adding FIDO/U2F (Universal Two Factor) security-key authentication using Viscosity's built-in FIDO support.

FIDO/U2F authentication adds an extra step after the user's username and password have been accepted. The first time a user connects they will be prompted to register a compatible security key. On later connections they will be prompted to authenticate with that key.

Preparation

For this guide, we assume:

  • You have already installed the latest version of Ubuntu LTS (26.04 at time of writing)
  • You have root access to this installation
  • You have already set up and tested an OpenVPN server using our Setting up an OpenVPN server with Ubuntu guide
  • You already have a copy of Viscosity installed on your client device and already set up for this server
  • You have a compatible FIDO/U2F security key

This guide assumes you are already able to connect to your OpenVPN server using certificate/key authentication. This guide will add two more authentication steps: a username and password using PAM, and a FIDO/U2F security-key challenge.

PAM authentication is the simplest form of username/password authentication we can use with OpenVPN. By default the plugin will use Ubuntu's normal user authentication, so you do not need to manage a separate username/password database.

FIDO/U2F authentication does not require your OpenVPN server to have a fully qualified domain name. Your server can use either a hostname or an IP address, as long as the FIDO application ID configured below matches the address your Viscosity clients use to connect. However we recommend using a domain name where possible (a dynamic DNS service is fine) so moving to a different IP address in the future doesn't cause existing tokens to need to be re-registered.

Ubuntu

The following instructions for Ubuntu assume that you have already set up an OpenVPN server using our Setting up an OpenVPN server with Ubuntu guide.

Installing the FIDO/U2F Enabled OpenVPN Packages

OpenVPN needs additional support to pass FIDO/U2F challenges to VPN clients. SparkLabs provides a patched OpenVPN package and the FIDO/U2F PAM plugin in our Ubuntu PPA.

First, update your server and install the tools needed to add a PPA:

sudo apt update
sudo apt install -y software-properties-common

Next, add the SparkLabs PPA:

sudo add-apt-repository -y ppa:sparklabs/ppa

Ubuntu also provides an openvpn package. To make sure the patched SparkLabs package is used for OpenVPN, create an apt preferences file:

sudo nano /etc/apt/preferences.d/sparklabs-openvpn

Paste in the following:

Package: openvpn
Pin: release o=LP-PPA-sparklabs
Pin-Priority: 1001

Package: openvpn
Pin: release o=Ubuntu
Pin-Priority: -1

This ensures apt uses the SparkLabs OpenVPN package, and fails instead of silently installing Ubuntu's standard OpenVPN package if the patched package is not available for your Ubuntu release.

Save the file and exit nano. Now update apt and install OpenVPN and the FIDO/U2F plugin:

sudo apt update
sudo apt install -y openvpn openvpn-u2f-plugin

To confirm the correct version of OpenVPN was installed, enter:

openvpn --version

If the correct OpenVPN package was installed, you should see [FIDO] in the output, for example:

OpenVPN 2.x.x x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] [DCO] [FIDO]

Creating VPN Users

The FIDO/U2F plugin uses PAM for username/password authentication. With the default login PAM service used below, this means users authenticate using normal local accounts.

If you need to create a new local user, enter the following and follow the prompts:

sudo adduser exampleuser

Replace exampleuser with the username you want to create.

Setting up OpenVPN

Now we can enable FIDO/U2F authentication for the OpenVPN server. Edit your server configuration:

sudo nano /etc/openvpn/server/server.conf

Scroll to the bottom of the configuration and add the following:

# FIDO/U2F and PAM authentication plugin
plugin /usr/lib/openvpn/plugins/pam-u2f/auth-pam-u2f.so login

# FIDO/U2F application ID. Replace YOURSERVER with the hostname or IP address
# Viscosity clients use to connect to this OpenVPN server.
setenv OPENVPN_FIDO_APP_ID openvpn://YOURSERVER

# Allow OpenVPN to reauthenticate during renegotiation without prompting for
# the security key again.
auth-gen-token

Replace YOURSERVER with the address your Viscosity clients use to connect to the server. For example:

setenv OPENVPN_FIDO_APP_ID openvpn://vpn.example.com

or:

setenv OPENVPN_FIDO_APP_ID openvpn://123.4.5.67

Save the configuration and restart OpenVPN:

sudo systemctl restart openvpn-server@server

To check the server status, enter:

sudo systemctl status openvpn-server@server

To which it should reply with:

Active: active (running)

If the server is not listed as active (running), you can view the OpenVPN server log by entering:

sudo journalctl -u openvpn-server@server -xe

The plugin will automatically create its local FIDO/U2F database the first time a registration challenge is generated. For new installations this database is stored at:

/var/lib/openvpn-u2f-plugin/u2f.db

Upgrading From an Older u2fval-Based Setup

Older versions of this guide (prior to 2026) used u2fval to manage U2F registration and authentication. The updated plugin no longer uses u2fval, and new installations do not need to install or run it.

If you previously followed the old guide, your registered devices should continue to work. The updated plugin will automatically use the old u2fval database if it exists at:

/etc/yubico/u2fval/u2fval.db

Do not delete this database unless you want all users to re-register their security keys.

The old u2fval service is no longer required. If it exists, you can stop and disable it with:

sudo systemctl stop u2fval.service
sudo systemctl disable u2fval.service

If you manually created the service file from the old guide, you can remove it with:

sudo rm /etc/systemd/system/u2fval.service
sudo systemctl daemon-reload

Setting up Viscosity

Now the server is set up, you only need to make a single change to your connection in Viscosity:

  • Open Viscosity's Preferences and edit your connection.
  • Go to the Authentication tab and tick 'Use Username/Password authentication'


     

  • Save the connection

Using Viscosity

Now that the changes to your configuration in Viscosity are finished, you can connect to the VPN server to test the connection.

The first time you connect, you'll be prompted to enter your username and password. After these are accepted, Viscosity will prompt you to register your FIDO/U2F security key. Follow the on-screen instructions by connecting your key to your computer, and if required, touching the key to activate and register it.



 

Once your key has been registered, future connections will prompt you to authenticate using the same security key. Make sure your key is connected to your computer, and if required, touch the key to activate it. Your VPN connection will then proceed to connect if authentication was successful.

Advanced

Resetting Registered Devices for a User

If a user needs to register a new security key, or you need to clear their registered devices, you can reset their FIDO/U2F registration with the helper script:

sudo /usr/share/openvpn/pam-u2f/auth-pam-u2f.py reset-devices USERNAME

Replace USERNAME with the user's username.

If you are using a custom database path, include the --db option:

sudo /usr/share/openvpn/pam-u2f/auth-pam-u2f.py reset-devices --db /path/to/u2f.db USERNAME

The next time the user connects they will be prompted to register a security key again.

Using a Different PAM Service

The login value in the plugin line is the PAM service name:

plugin /usr/lib/openvpn/plugins/pam-u2f/auth-pam-u2f.so login

On Ubuntu this uses the PAM configuration at /etc/pam.d/login, which authenticates against normal local Linux accounts by default.

Advanced administrators can create or use a different PAM service and change the plugin line to match. PAM can be configured to authenticate against other systems, such as LDAP, RADIUS, or directory-backed authentication through tools like SSSD. Setting up those systems is beyond the scope of this guide, but the FIDO/U2F plugin can be used with them as long as they are exposed through PAM.

Multiple Server Addresses

If users connect to the same OpenVPN server using more than one hostname or IP address, you may need to allow multiple FIDO/U2F origins. You can do this by setting OPENVPN_FIDO_VALID_FACETS to a comma-separated list of trusted origins:

setenv OPENVPN_FIDO_VALID_FACETS openvpn://vpn.example.com,openvpn://203.0.113.10

The OPENVPN_FIDO_APP_ID setting is still required for new databases, and should be set to the primary address users normally connect to.