Automating VPN User Authentication with LDAP and OpenVPN

We earn commissions using affiliate links.

Quick Summary: This guide shows how to integrate LDAP (OpenLDAP/Active Directory) with OpenVPN on Ubuntu. You’ll get a production-ready setup with TLS/SSL, group-based access control, failover, hardening, troubleshooting, and logging. The goal is centralized sign-in, stronger security, and simplified user management across systems.

1) Prerequisites & Target Architecture

  • Server: Ubuntu 20.04+ with root/sudo and a working tun kernel module.
  • PKI: EasyRSA to generate a CA, server certificate, DH parameters, and optionally tls-auth/tls-crypt.
  • Directory: OpenLDAP or Microsoft Active Directory, with a read-capable bind account and appropriate indexes (e.g., uid or sAMAccountName).
  • Security: LDAPS (ldaps:// 636) or StartTLS, firewall (UFW), at least AES-256-GCM, and tls-version-min.
  • Goal: Users authenticate to OpenVPN using directory credentials; access is enforceable via group/attribute rules.

2) Install OpenVPN & Basic System Checks

Update and install packages:

sudo apt update
sudo apt install -y openvpn openvpn3 easy-rsa

Verify TUN:

sudo modprobe tun
lsmod | grep tun

Autoload on boot (if missing):

echo "tun" | sudo tee /etc/modules-load.d/openvpn.conf

Allow VPN and SSH in the firewall (default UDP/1194):

sudo ufw allow 1194/udp
sudo ufw allow OpenSSH
sudo ufw enable

3) Build PKI with EasyRSA

Download and initialize PKI, then create keys/certs:

wget -q -O - https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz | tar xvz
cd EasyRSA-3.0.8/
./easyrsa init-pki
./easyrsa build-ca
./easyrsa gen-req server nopass
./easyrsa sign-req server server
./easyrsa gen-dh
openvpn --genkey --secret ta.key (optional, for tls-auth)

Copy resulting files to /etc/openvpn/ and apply restrictive permissions (chmod 600 where appropriate).

4) Base OpenVPN Server Configuration

Create /etc/openvpn/server.conf (secure minimal baseline):

port 1194
proto udp
dev tun
user nobody
group nogroup
persist-key
persist-tun
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh.pem
tls-auth /etc/openvpn/ta.key 0 # or prefer tls-crypt
cipher AES-256-GCM
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
tls-version-min 1.2
topology subnet
keepalive 10 120
explicit-exit-notify 1
status /var/log/openvpn-status.log
log-append /var/log/openvpn.log
verb 3

Enable and start:

sudo systemctl enable openvpn@server
sudo systemctl start openvpn@server
sudo systemctl status openvpn@server

5) Install & Configure the LDAP Plugin

Install the plugin (package name may vary by repo):

sudo apt install -y openvpn-auth-ldap # alternatively openvpn3-auth-ldap depending on distribution

Create /etc/openvpn/auth-ldap.conf:

# LDAP server
URL ldaps://ldap.example.com
TLSEnable yes
Timeout 15
FollowReferrals no

# Bind account
BindDN "cn=admin,dc=example,dc=com"
BindPW "yourpassword"

# Search base & filter
BaseDN "ou=users,dc=example,dc=com"
SearchFilter "(uid=%s)" # For AD use: “(sAMAccountName=%s)”

# Optional: group-based access control
RequireGroup true
<Group>
BaseDN "ou=groups,dc=example,dc=com"
SearchFilter "(cn=VPNUsers)"
MemberAttribute memberUid # For AD: member
</Group>

# Logging (raise during troubleshooting)
LogFile "/var/log/openvpn-ldap.log"
LogLevel 3

Enable the plugin in /etc/openvpn/server.conf:

plugin /usr/lib/openvpn/plugins/openvpn-auth-ldap.so /etc/openvpn/auth-ldap.conf
client-cert-not-required
username-as-common-name

Note: You can combine LDAP with client certificates for “2FA-like” security by removing client-cert-not-required and requiring both the client cert and password.

6) Validate LDAPS & Trust

If you use a private CA for LDAP, add it to the OpenVPN host trust store:

sudo cp /path/to/ldap-ca.crt /usr/local/share/ca-certificates/ldap-ca.crt
sudo update-ca-certificates

Test port 636 and the certificate chain:

openssl s_client -connect ldap.example.com:636 -showcerts

LDAP search smoke test:

ldapsearch -H ldaps://ldap.example.com -D "cn=admin,dc=example,dc=com" -w "yourpassword" -b "ou=users,dc=example,dc=com" "(uid=testuser)"

7) (Optional) Verification Script for Extra Logic

If you need additional checks (denylists, time windows, licensing caps), you can use a helper script. Example (/etc/openvpn/check-auth.sh):

#!/bin/bash
USER="$1"
PASS="$2"
# Example only — real password validation should be handled by the LDAP plugin or PAM/SSSD
ldapsearch -x -LLL -H ldaps://ldap.example.com \
-D "cn=admin,dc=example,dc=com" -w "yourpassword" \
-b "ou=users,dc=example,dc=com" "(uid=$USER)" | grep -q "^dn:"
if [ $? -eq 0 ]; then exit 0; else exit 1; fi

Make it executable: sudo chmod 700 /etc/openvpn/check-auth.sh
Enable in server.conf only if you go the script route: auth-user-pass-verify /etc/openvpn/check-auth.sh via-env

Recommendation: For password validation, prefer the auth-ldap plugin or PAM (e.g., plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so login) with libpam-ldapd/sssd. Scripts are best for auxiliary checks, not for primary auth.

8) Client Configuration & Hardening

Minimum client .ovpn entries:

client
dev tun
proto udp
remote vpn.example.com 1194
resolv-retry infinite
nobind
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
verb 3
auth-user-pass

Useful server hardening additions (server.conf):

push "redirect-gateway def1 bypass-dhcp" # force Internet via VPN if desired
push "dhcp-option DNS 10.8.0.1" # point clients to your internal resolver
tls-crypt /etc/openvpn/ta.key # stronger than tls-auth
sndbuf 0
rcvbuf 0
push "sndbuf 0"
push "rcvbuf 0"

Enable IP forwarding if routing is required:

sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-openvpn.conf

9) Performance & Scaling

  • LDAP Indexing: Index uid/sAMAccountName and group attributes (memberUid/member) for faster searches.
  • Timeouts: Use Timeout 10–15 in auth-ldap.conf. Reduce FollowReferrals in AD forests where needed.
  • Caching: PAM/SSSD cache or nscd reduces load on LDAP.
  • HA: Provide multiple endpoints in URL (e.g., ldaps://ldap1 ... ldaps://ldap2) and load-balance OpenVPN nodes via HAProxy/Keepalived.
  • TLS/CPU: Ensure AES-NI on Intel/AMD; consider CHACHA20-POLY1305 on low-power CPUs.

10) Security & Operations

  • Permissions: sudo chown root:root /etc/openvpn/auth-ldap.conf, sudo chmod 600 /etc/openvpn/auth-ldap.conf.
  • Secret Hygiene: Store credentials in a dedicated dir (e.g., /etc/openvpn/credentials/) with 600 perms.
  • Logging: Use LogFile/LogLevel in auth-ldap.conf; configure logrotate for OpenVPN logs.
  • Accounts: Enforce LDAP password policies, account expiration, lockouts for brute-force mitigation.
  • Network: Restrict LDAPS to OpenVPN hosts only; document data flows.
  • Auditing: Ship OpenVPN/LDAP logs to SIEM (Wazuh/Elastic/Splunk) for monitoring and alerts.

11) Troubleshooting

General “AUTH_FAILED”: Raise verb 4–5 in OpenVPN and LogLevel 5 in auth-ldap.conf. Confirm SearchFilter and BaseDN logic.

Active Directory specifics: Use SearchFilter "(sAMAccountName=%s)"; for groups use member (not memberUid).

LDAPS errors: Check CN/SAN vs FQDN, place CA in trust store, run update-ca-certificates.

Timeouts: Verify network/firewall; reduce referrals; test against secondary DC/LDAP.

Routing/DNS: If Internet doesn’t go through VPN, confirm redirect-gateway, NAT/forwarding, and pushed DNS.

12) End-to-End Validation

  1. Restart: sudo systemctl restart openvpn@server.
  2. Tail logs: sudo tail -f /var/log/openvpn.log.
  3. Client sign-in: Use OpenVPN client; enter LDAP username/password.
  4. Confirm IP: On the client, check new 10.8.0.0/24 address.
  5. Policy test: Attempt login with a non-member user (RequireGroup = true) — it should be denied.

Production Checklist (quick pass)

  • LDAPS active (URL ldaps://...), CA trusted on the VPN server.
  • Group-based control (RequireGroup true) validated with allow/deny tests.
  • Log rotation configured; LogLevel reduced after go-live.
  • IP forwarding enabled; NAT/routing verified; DNS pushed and tested.
  • Secrets locked down (chmod 600 conf/credentials; chmod 700 scripts).

FAQ – OpenVPN + LDAP

How do I enable LDAPS securely?

Install a valid server certificate on LDAP (CN/SAN = FQDN). Place the CA on the OpenVPN host (/usr/local/share/ca-certificates/) and run update-ca-certificates. Use URL ldaps://ldap.example.com in auth-ldap.conf. Verify with openssl s_client -connect ldap.example.com:636.

Can I use Active Directory with sAMAccountName?

Yes. Switch the search filter to (sAMAccountName=%s) and use group attribute member in the <Group> block. Example: BaseDN "OU=Users,DC=example,DC=com", SearchFilter "(sAMAccountName=%s)", MemberAttribute member.

How do I restrict VPN access to a specific LDAP group?

Set RequireGroup true and specify the group DN. For OpenLDAP you often use memberUid; in AD use member. Example:

<Group>
BaseDN "ou=groups,dc=example,dc=com"
SearchFilter "(cn=VPNUsers)"
MemberAttribute memberUid
</Group>

How do I combine client certificates with LDAP passwords?

Remove client-cert-not-required so client certificates are mandatory, and keep the LDAP plugin for username/password. Both factors are required at login (stronger security).

Common causes of “AUTH_FAILED”
  • Wrong SearchFilter/BaseDN (e.g., uid vs sAMAccountName).
  • BindDN lacks read permissions for the OU.
  • LDAPS certificate not trusted or CN/SAN mismatch with FQDN.
  • Firewall blocking 636/1194.
  • Group requirement (RequireGroup) not met.
Can I define multiple LDAP servers for failover?

Yes. Provide multiple endpoints in URL, e.g., URL ldaps://ldap1.example.com ldaps://ldap2.example.com. Consider replication and load balancing (HAProxy) for higher availability.

How do I enable more detailed logging for troubleshooting?

In auth-ldap.conf set LogLevel 5 and LogFile "/var/log/openvpn-ldap.log". In server.conf temporarily raise verb to 4–5. Use journalctl -u openvpn@server -f for live logs.

How do I secure secrets and config files?

Root ownership and minimal permissions: chown root:root /etc/openvpn/auth-ldap.conf, chmod 600 /etc/openvpn/auth-ldap.conf. For scripts use chmod 700. Store credentials separately.

Which ciphers and TLS parameters should I choose?

AES-256-GCM is great on modern CPUs (AES-NI). Add CHACHA20-POLY1305 for low-power devices. Set tls-version-min 1.2 and prefer tls-crypt.

How do I verify DNS and routing over VPN?

Push DNS via push "dhcp-option DNS 10.8.0.1" and force gateway with push "redirect-gateway def1". On the client, confirm public IP/DNS queries traverse the VPN.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *