Skip to content

Plugin for OpenVPN (CE) that authenticates users directly against Okta, with support for MFA (TOTP or PUSH only).

License

Notifications You must be signed in to change notification settings

algolia/openvpn-auth-okta

Repository files navigation

Release Go version Go Reference CI status Coverage Go Report Card Codacy Badge

Introduction

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)

Requirements

The plugin requires that OpenVPN Community Edition to be configured or used in one the following ways:

  1. OpenVPN can be configured to call plugins via a deferred call (aka Shared Object Plugin mode) or call the binary directly (aka Script Plugin mode).
  2. By default, OpenVPN clients must authenticate using client SSL certificates.
  3. 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

Installation

Install the Okta OpenVPN plugin

You have three options to install the Okta OpenVPN plugin:

1. Use pre-built packages from repositories

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.

Packages are available for

  • 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)

2. For default setups, use sudo make install to run the install for you

Build requirements:

  • gcc
  • golang (>= 1.23)
  • 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

3. For custom setups, follow the manual installation instructions below

Compile the plugin

Build requirements:

  • gcc
  • golang (>= 1.23)
  • make

Compile the plugin from this directory using this command:

make plugin

Compile the Golang binary from this repository using this command:

make binary

Manually installing the Okta OpenVPN plugin

If you have a custom setup, follow the instructions below to install the C plugin and Golang library that constitute the Okta OpenVPN plugin.

Manually installing the C 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.

Manually installing the Golang binary

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.

Make sure that OpenVPN has a tempory directory

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).

Configuration

Configure the Okta OpenVPN plugin

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.

Configure OpenVPN to use the C Shared Object Plugin

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.

Configure OpenVPN to use the binary in Script Plugin mode

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.

Log outputs

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}

Useful links

Contact

Updates or corrections to this document are very welcome. Feel free to send me pull requests with suggestions or open issues.

About

Plugin for OpenVPN (CE) that authenticates users directly against Okta, with support for MFA (TOTP or PUSH only).

Resources

License

Code of conduct

Stars

Watchers

Forks