Update: Check latest up2date docs: https://github.com/jkroepke/openvpn-auth-oauth2/wiki
Introduction
We all love free Open Source software and OpenVPN is one of the most open source VPN solutions around the world.
While OpenVPN works great on Small Business, issuing VPN certificates on a large enterprise environment can be an issue. Many companies are buying VPN appliances with Self-Service Portal to on board OpenVPN users.
In history, a lot of solutions based on OpenVPN plugins or PAM modules together with OpenVPN PAM module. Another solution was OpenVPN LDAP module, but the experience for an MFA was terrible.
After long reason, I figure out that OpenVPN 2.5 or higher supports deferred authentication. With deferred authentication method. OpenVPN can tell the users’ client to open a browser page. This pattern can be used to initialize SSO flows and fully delegates the authentication to an external programs.
Using the clients’ browser to initiate the authentication has a lot of benefits. Looking to Azure AD or Keycloak, modern MFA technics a side from OTP can be used for a secure authentication, e.g. FIDO2 (WebAuth) or Microsoft Authenticator (push). Additional restrictions can be applied through an IDP like Keycloak for example restrict the client IP address or allow connections only from MDM devices (Intune; Conditional Access).
Setup OpenVPN
[openvpn-auth-oauth2]https://github.com/jkroepke/openvpn-auth-oauth2() just adds an additional authentication layer on OpenVPN. You can still use client certificates if you wish or omit them, if you no longer want to depend on them.
openvpn-auth-oauth2 is a dedicated binary which start a HTTP server and connect to an OpenVPN management interface. You have to enable to management interface on your OpenVPN server first.
# /etc/openvpn/password.txt is a password file where the password must be on first line
management /run/openvpn/server.sock unix /etc/openvpn/password.txt
management-client-auth
Keep in mind, never expose the management interface to the public internet! You have to create as password.txt near to your OpenVPN configuration file. Put a strong password into the first line and save the file.
Next, you have to create a standard OAUTH2 application on the IdP on your choice. As example, we will use Entra ID:
Create a App Registration in Entra ID
- Login as admin into your tenant
- Open App registrations in Azure AD portal
- Click
new registration
- Pick a name, chose a “Supported account types”-option. Leave the default value, if you are not sure.
- For redirect uri, choice Web and enter the public endpoint of
openvpn-auth-oauth2
, for examplehttps://openvpn-auth-oauth2.example.com/oauth2/callback
. Behind the URL, theopenvpn-auth-oauth2
binary should be accessible. - Click Register.
- Copy the tenant-id and client-id. You need the both as configuration option for
openvpn-auth-oauth2
. - After creation, select
Certificates & secrets
on the left side. - Select the tab
Client secrets
and create a new client secret. - Copy the client-secret. You need it as configuration option for
openvpn-auth-oauth2
. - Then, select Token configuration on the left side.
- Add optional claim
- On the right panel, select ID as token type
- Select
ipaddr
from the list of claims. - Select Add.
Setup openvpn-auth-oauth2
After setup OpenVPN and you OAUTH2 App/Client, all prerequirements are met for openvpn-auth-oauth2.
Download the binary from GitHub Releases and store the binary under /usr/local/bin/openvpn-auth-oauth2
. To run the binary, setup a systemd service.
[Unit]
Description=OpenVPN authenticator
Documentation=https://github.com/jkroepke/openvpn-auth-oauth2
Wants=network-online.target openvpn.service
After=network-online.target openvpn.service openvpn@.service openvpn-server@.service
PartOf=openvpn.service openvpn@.service openvpn-server@.service
[Service]
DynamicUser=true
Group=nogroup
ExecStart=/usr/local/bin/openvpn-auth-oauth2
EnvironmentFile=/etc/sysconfig/openvpn-auth-oauth2
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ConfigurationDirectory=openvpn-auth-oauth2
ReadWritePaths=-/run/openvpn -/run/openvpn-server
# CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoExecPaths=/
ExecPaths=/usr/local/bin/openvpn-auth-oauth2
Restart=always
RestartSec=5s
Restart=on-failure
[Install]
WantedBy=multi-user.target
Configure
If you run the binary as systemd service, you can use the /etc/sysconfig/openvpn-auth-oauth2
file toset up the environment variables. If you are preferring Docker containers, use the known tools to declare environment variables
CONFIG_OAUTH2_ISSUER=https://login.microsoftonline.com/<tenant-id>/v2.0
CONFIG_OAUTH2_CLIENT_ID=
CONFIG_OAUTH2_CLIENT_SECRET=
CONFIG_HTTP_SECRET= # Define a random value with 16 or 24 chacters
CONFIG_HTTP_BASEURL=https:// # Define the public http endpoint here.
After configuration, you can start the service with systemctl enable --now openvpn-auth-ouath2
and you are done.
Top comments (0)