This offers a set of lib and binary to authenticate users against Okta Authentication API , with support for MFA (TOTP or PUSH only). It also offers a plugin for OpenVPN (Community Edition) using the lib mentionned above.
❗ Note: The plugin does not work with OpenVPN Access Server (OpenVPN-AS)
The plugin requires that OpenVPN Community Edition to be configured or used in one the following ways:
- OpenVPN can be configured to call plugins via a deferred call (aka
Shared Object Plugin
mode) or call the binary directly (akaScript Plugin
mode). - By default, OpenVPN clients must authenticate using client SSL certificates.
- If authenticating requires MFA, the end user will authenticate by appending their six-digit MFA TOTP to the end of its password or by validating Push notifications.
For TOTP, if a user's password is correcthorsebatterystaple
and their six-digit MFA TOTP is 123456
, he should use correcthorsebatterystaple123456
as the password for their OpenVPN client
You have three options to install the Okta OpenVPN plugin:
Thanks to the OpenSUSE Build Service packages are available for multiple distros: CentOS, Debian, Fedora, openSUSE, Ubuntu.
Choose the proper instructions for your Linux distribution here.
- CentOS (amd64, arm64):
8
,8 Stream
- Fedora (amd64, arm64):
38
,39
,40
- Mageia (amd64, arm64):
8
,9
- openSUSE (amd64, arm64, ppc64le):
15.4
,15.5
,15.5
- Debian (amd64, arm64):
Buster
(10),Bullseye
(11),Bookworm
(12) - Raspbian(arm64):
10
,11
,12
- Ubuntu (amd64, arm64):
Focal Fossa
(20.04),Jammy Jellyfish
(22.04),Lunar Lobster
(23.04),Mantic Minotaur
(23.10),Noble Numbat
(24.04)
Build requirements:
- gcc
- golang (>= 1.21)
- make
If you have a default OpenVPN setup, where plugins are stored in /usr/lib/openvpn/plugins
and configuration files are stored in /etc/okta-auth-validator
, then you can use the make install
command to install the Okta OpenVPN plugin:
sudo make install
Build requirements:
- gcc
- golang (>= 1.21)
- make
Compile the plugin from this directory using this command:
make plugin
Compile the Golang binary from this repository using this command:
make binary
If you have a custom setup, follow the instructions below to install the C plugin and Golang library that constitute the Okta OpenVPN plugin.
To manually install the C plugin, copy the build/openvpn-plugin-auth-okta.so
file to the location where your OpenVPN plugins are stored and the libokta-auth-validator.so
file to your system libdir.
To manually install the binary, copy the okta-auth-validator
to your system bin dir; the pinset.cfg
, and api.ini
files to the location where your OpenVPN plugin scripts are stored.
In OpenVPN, the "deferred plugin" model requires the use of temporary files to work. It is recommended that these temporary files are stored in a directory that only OpenVPN has access to. The default location for this directory is /etc/openvpn/tmp
. If this directory doesn't exist, create it using this command:
sudo mkdir /etc/openvpn/tmp
Use the chown and chmod commands to set permissions approprate to your setup (The user that runs OpenVPN should be owner and only writer).
The Okta OpenVPN plugin is configured using the api.ini
file. You must update this file with the configuration options for your Okta organization for the plugin to work.
If you installed the Okta OpenVPN plugin to the default location, run this command to edit your configuration file.
sudo $EDITOR /etc/okta-auth-validator/api.ini
⚠️ As this file contains your Okta token, please ensure it has limited permissions (should only be readable by root or the user running OpenVPN) !
See api.ini for configuration options.
Set up OpenVPN to call the Okta plugin by adding the following lines to your OpenVPN server.conf
configuration file:
plugin openvpn-plugin-auth-okta.so
tmp-dir "/etc/openvpn/tmp"
The default location for the OpenVPN configuration file is /etc/openvpn/server.conf
.
This method is considered the safest as no credential is exported to a process environment or written to disk.
Set up OpenVPN to call the Golang binary by adding the following lines to your OpenVPN server.conf
configuration file:
# "via-file" method
auth-user-pass-verify /usr/bin/okta-auth-validator via-file
tmp-dir "/etc/openvpn/tmp"
❗ it is strongly advised when using the via file method, that the tmp-dir is located on a tmpfs filesystem (so that the user's credentials never reach the disk). Systemd can help for that:
VUSER=openvpn
echo "d /run/openvpn/tmp 1750 ${VUSER} root" | sudo tee /etc/tmpfiles.d/openvpn-tmp.conf
sudo systemd-tmpfiles --create /etc/tmpfiles.d/openvpn-tmp.conf
# "via-env" method
auth-user-pass-verify /usr/bin/okta-auth-validator via-env
tmp-dir "/etc/openvpn/tmp"
Please check the OpenVPN manual for security considerations regarding this mode.
Outputs have been designed to be easily parsable, you'll find 2 different formats depending on wether the username has been set or not, ie:
Before
Thu Dec 21 03:41:28 2023 [okta-auth-validator:4dd5f892-c51d-43bf-94c7-87b25b81707e](ERROR): Initpool failure
After
Thu Dec 21 03:41:28 2023 [okta-auth-validator:50bc833a-dcea-4337-9d73-41af17371c4e](INFO): [[email protected]] Authenticating
A grok pattern could be:
DATESTAMP_OKTA %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{YEAR}
%{DATESTAMP_OKTA:timestamp} \[okta-auth-validator:%{UUID:session_id}\]\(%{LOGLEVEL:level}\):(%{SPACE}\[((%{EMAILADDRESS:username})|(%{EMAILLOCALPART:username}))\])? %{GREEDYDATA:message}
- OpenVPN: Using alternative authentication methods
- OpenVPN 2.4 manual
- Openvpn multi-auth sample plugin code
- Okta API - PreAuth
- Okta API - Auth with TOTP MFA
- Okta API - Auth with Push MFA
Updates or corrections to this document are very welcome. Feel free to send me pull requests with suggestions or open issues.