Back in July we did an OpenVPN “reboot”.
This is Part 1 of OpenVPN at Scale. Be sure to also read Part 2: Monitoring!
Back in May, our original VPN setup meant we had many OpenVPN instances, all carefully and manually crafted and built and an inconsistent way of managing user logins and passwords and MFA methods, none of which was self-service. Most of the time, resetting passwords or MFA required a back-and-forth in Jira.
It was basically friction and the antithesis of building for lazy #BeachOps.
Our goals were simple:
- Consolidated our OpenVPNs into one (we had many).
- Codify VPN setup, including VPC peering and host configuration in Terraform & Ansible.
- Consolidate authentication using our SAML provider, Okta.
That last bullet led us down a very windy and not well-documented world.
So this blog post hopes to help the next persons searching for a how-to.
- How to setup OpenVPN SSL certificates with Let’s Encrypt
- How to use Okta as an LDAP provider
- How to configure OpenVPN to use Okta LDAP
- Tweaking authentication timeouts for Okta MFA
- (How to debug Okta & LDAP)
- How to login to OpenVPN with Okta & Okta MFA
We’ll generally assume you know how to install OpenVPN – we opted for the AWS Marketplace version.
We’re using (almost) real hostnames and users in the examples below but adjust as necessary.
Let’s Encrypt & OpenVPN
First things first, we secure the OpenVPN WebUI.
The following two guides were helpful:
- Guide: OpenVPN Access Server & Let’s Encrypt
- Using Let’s Encrypt and Certbot to automate the creation of certificates for OpenVPN
Install Certbot. We used Ansible to do this part:
--- - block: - name: add certbot repository apt_repository: repo: "ppa:certbot/certbot" state: present update_cache: yes - name: install certbot package: name=certbot state=latest
Run Certbot. There are a couple ways to do this but we found the steps in the second post the easiest:
sudo certbot certonly \ --standalone \ --non-interactive \ --agree-tos \ --email YOUR_EMAIL \ --domains YOUR_DOMAIN \ --pre-hook 'sudo service openvpnas stop' \ --post-hook 'sudo service openvpnas start'
Install the certificates. Certbot puts its files in
/etc/letsencrypt/live/ and the easiest way was to symlink them. There’s a more complicated way that involves using the OpenVPN command line,
sacli, and a couple
ConfigPut but since these certificates will need to renew every 90-days or so, we went with symlinks:
sudo ln -s -f /etc/letsencrypt/live/YOUR_DOMAIN/cert.pem /usr/local/openvpn_as/etc/web-ssl/server.crt sudo ln -s -f /etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem /usr/local/openvpn_as/etc/web-ssl/server.key
Using Okta as an LDAP provider
We wanted to consolidate all authentications into Okta which already is already part of our IT processes. We also like that, for the most part, Okta has enough self-service for most things and is a central place to ensure password policies.
Enable Okta LDAP
There are only two things you have to do:
- In the Okta Admin console, go to Directory | Directory Integrations
- Click Add Directory | Add LDAP Directory
That’s it! You will want to make note of
Add Okta/LDAP group (optional)
Unless you want everyone in your Okta organization to have access to OpenVPN, you’ll want to create an Okta group and add users to it. For simplicity, we went with a single word, lowercase group
openvpn. Make a note of the group name you use.
Configuring OpenVPN & Okta LDAP
Create a Bind User. We created a specific, authenticated service account for the initial LDAP bind.
- Create Service Account, perhaps
- Disable MFA requirement for Service Account
We have to disable MFA for this Service Account since it’s not possible (or really hard?) to inject an MFA response for each LDAP bind request. Do this with care and adjust for your own local password rotation policy.
Disable MFA for your Service Account Okta user:
- In the Okta Admin console, Security | Authentication
- Edit your existing MFA policy and include your Service Account user in “Exclude Users”.
Configuring OpenVPN. You’ll need to enable LDAP now. In the OpenVPN Admin UI (
https://vpn.example.com/admin/ldap_configuration). This is under Authentication | LDAP:
- LDAP Settings | Primary server
- Use SSL to connect to LDAP servers
- Credentials for Initial Bind | Use these credentials
- Use Bind DN & password for your Service Account
- Fill in Base DN for User Entries (this comes from Okta in Directory | Directoroy Integrations | LDAP Interface, in case you lost it)
- Fill in Username Atttribue:
- Additional LDAP Requirement (group membership)
Caveat – OpenVPN Users
Quick note – LDAP users in OpenVPN don’t show up in User Management. If you need to adjust user permissions, for example enabling admin permissions, you’ll need to manually add their username and grant permissions.
Tweaking authentication timeouts for Okta MFA
Since OpenVPN will make an LDAP auth request to Okta and Okta will either make an MFA request (Okta Verify push notification) or expect one (software MFA), we need to increase the timeout that OpenVPN uses to wait for a response from LDAP:
/usr/local/openvpn_as/scripts/sacli --key "auth.ldap.0.timeout" --value 60 ConfigPut /usr/local/openvpn_as/scripts/sacli start
[This hint was taken from the Foxpass docs “OpenVPN AS via LDAP“.]
It’s been something like 42 years since any of us actually worked with LDAP. Testing this setup was a bit of manual debugging so we’ll leave the steps we used here.
Install LDAP tools:
sudo apt-get -y install ldap-utils
ldapsearch to test:
ldapsearch -H ldaps://lacework.ldap.okta.com -b "dc=lacework,dc=okta,dc=com" -s sub -D "uid=vpnServiceUser@lacework.net,dc=lacework,ou=users,dc=okta,dc=com" -W -z none -Z "(email@example.com)"
Test LDAP group/memberOf searches:
ldapsearch -H ldaps://lacework.ldap.okta.com -b "dc=lacework,dc=okta,dc=com" -s sub -D "uid=vpnServiceUser@lacework.net,dc=lacework,ou=users,dc=okta,dc=com" -W -z none -Z "(&(objectClass=inetOrgPerson)(memberOf=cn=openvpn,ou=users,dc=lacework,dc=okta,dc=com))"
Logging in with Okta credentials & MFA
Worth nothing that using Okta for LDAP works best Okta’s push client, Okta Verify. It’s super seemless and depending on your OpenVPN client, your username & password may be stored by your OS.
- Login to OpenVPN with your Okta username & password
- Wait for push notification
- Acknowledge the login request
- You are logged in
However, if you’re using a software MFA token, your MFA token is entered as part of your password. The format of your password is “
password-comma-MFA“. For example:
This method works, of course, but also means that you’ll have to type your password each time you login to OpenVPN. YMMV.
Wrapping it all up
What more is there to say?