Set up OpenVPN server with LDAP authentication against Active Directory, enabling centralized user management and group-based access control for enterprise VPN deployments.
Prerequisites
- Root or sudo access
- Active Directory server accessible
- Dedicated service account in AD
- Firewall access to AD server port 389
What this solves
This tutorial configures OpenVPN server with LDAP authentication to integrate with your existing Active Directory infrastructure. Instead of managing VPN users separately, you'll authenticate users against AD with group-based access control and automated certificate management.
Step-by-step configuration
Update system packages
Start by updating your package manager to ensure you get the latest versions of OpenVPN and required dependencies.
sudo apt update && sudo apt upgrade -y
Install OpenVPN and LDAP authentication plugin
Install OpenVPN server, Easy-RSA for certificate management, and the LDAP authentication plugin that connects to Active Directory.
sudo apt install -y openvpn easy-rsa openvpn-auth-ldap libldap2-dev
Set up Certificate Authority and server certificates
Create a Certificate Authority to manage VPN certificates. This CA will sign the server certificate and any client certificates if needed.
sudo mkdir -p /etc/openvpn/easy-rsa
sudo cp -r /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/
cd /etc/openvpn/easy-rsa
Initialize the PKI and create CA certificate
Initialize the Public Key Infrastructure and create the root Certificate Authority that will sign all certificates.
sudo ./easyrsa init-pki
sudo ./easyrsa --batch build-ca nopass
Generate server certificate and DH parameters
Create the server certificate and Diffie-Hellman parameters for secure key exchange. The server certificate identifies your VPN server.
sudo ./easyrsa build-server-full server nopass
sudo ./easyrsa gen-dh
sudo openvpn --genkey --secret pki/ta.key
Copy certificates to OpenVPN directory
Move the generated certificates to the OpenVPN configuration directory with correct permissions.
sudo cp pki/ca.crt pki/issued/server.crt pki/private/server.key pki/dh.pem pki/ta.key /etc/openvpn/server/
sudo chown root:root /etc/openvpn/server/*
sudo chmod 600 /etc/openvpn/server/server.key /etc/openvpn/server/ta.key
sudo chmod 644 /etc/openvpn/server/ca.crt /etc/openvpn/server/server.crt /etc/openvpn/server/dh.pem
Create OpenVPN server configuration
Configure the OpenVPN server with LDAP authentication enabled. This configuration listens on port 1194 and uses the LDAP plugin for user authentication.
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
tls-auth ta.key 0
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
tls-crypt ta.key
cipher AES-256-GCM
auth SHA256
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
explicit-exit-notify 1
LDAP Authentication
plugin /usr/lib/openvpn/openvpn-auth-ldap.so /etc/openvpn/auth-ldap.conf
client-cert-not-required
username-as-common-name
Configure LDAP authentication plugin
Create the LDAP authentication configuration to connect to your Active Directory server. Replace the values with your AD server details.
<LDAP>
# LDAP server URL - replace with your domain controller
URL ldap://dc1.example.com:389
# Bind credentials for LDAP search
BindDN "CN=vpn-service,CN=Users,DC=example,DC=com"
Password "SecureServiceAccountPassword"
# Connection timeout
Timeout 15
# Follow LDAP referrals
FollowReferrals yes
# TLS configuration (uncomment for secure LDAP)
# TLSEnable yes
# TLSCACertFile /etc/ssl/certs/ca-certificates.crt
</LDAP>
<Authorization>
# Base DN for user searches
BaseDN "CN=Users,DC=example,DC=com"
# Search filter for users
SearchFilter "(&(objectClass=user)(sAMAccountName=%u)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"
# Require group membership for access
RequireGroup true
<Group>
# Base DN for group searches
BaseDN "CN=Users,DC=example,DC=com"
# Group search filter - only allow VPN Users group
SearchFilter "(&(objectClass=group)(cn=VPN Users))"
# Group membership attribute
MemberAttribute member
# Group member format
MemberAttributeIsDN true
</Group>
</Authorization>
Create service account in Active Directory
Create a dedicated service account in Active Directory for OpenVPN LDAP authentication. This account needs read permissions on user and group objects.
Create VPN Users group in Active Directory
Create a security group to control VPN access. Only users in this group will be able to authenticate to the VPN.
Set up OpenVPN log directory
Create the log directory for OpenVPN with appropriate permissions for the nobody user.
sudo mkdir -p /var/log/openvpn
sudo chown nobody:nogroup /var/log/openvpn
sudo chmod 755 /var/log/openvpn
Configure IP forwarding and firewall
Enable IP forwarding to route VPN traffic and configure firewall rules to allow VPN connections and NAT.
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
sudo ufw allow 1194/udp
sudo ufw allow OpenSSH
sudo ufw --force enable
Configure NAT for VPN traffic
echo 'net/ipv4/ip_forward=1' | sudo tee -a /etc/ufw/sysctl.conf
sudo sed -i '1i# NAT for OpenVPN\n*nat\n:POSTROUTING ACCEPT [0:0]\n-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE\nCOMMIT\n' /etc/ufw/before.rules
Enable and start OpenVPN service
Enable the OpenVPN service to start automatically on boot and start it now.
sudo systemctl enable openvpn-server@server
sudo systemctl start openvpn-server@server
sudo systemctl status openvpn-server@server
Create client configuration template
Create a base client configuration that users can download and configure with their credentials.
client
dev tun
proto udp
remote your-server-ip 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
verb 3
auth-user-pass
<ca>
Paste contents of /etc/openvpn/server/ca.crt here
</ca>
<tls-crypt>
Paste contents of /etc/openvpn/server/ta.key here
</tls-crypt>
Test LDAP authentication
Test LDAP connection manually
Verify that the LDAP authentication is working by testing the connection to your Active Directory server.
sudo apt install -y ldap-utils
ldapsearch -x -H ldap://dc1.example.com:389 -D "CN=vpn-service,CN=Users,DC=example,DC=com" -W -b "CN=Users,DC=example,DC=com" "(sAMAccountName=testuser)"
Check OpenVPN logs for authentication attempts
Monitor the OpenVPN logs to see authentication attempts and troubleshoot any LDAP connection issues.
sudo tail -f /var/log/openvpn/openvpn.log
Configure group-based access control
Create multiple VPN groups for different access levels
Configure different groups for various access levels like full access, restricted access, or department-specific access.
<LDAP>
URL ldap://dc1.example.com:389
BindDN "CN=vpn-service,CN=Users,DC=example,DC=com"
Password "SecureServiceAccountPassword"
Timeout 15
FollowReferrals yes
</LDAP>
<Authorization>
BaseDN "CN=Users,DC=example,DC=com"
SearchFilter "(&(objectClass=user)(sAMAccountName=%u)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"
RequireGroup true
# Full access VPN group
<Group>
BaseDN "CN=Users,DC=example,DC=com"
SearchFilter "(&(objectClass=group)(cn=VPN Full Access))"
MemberAttribute member
MemberAttributeIsDN true
</Group>
# IT Department VPN access
<Group>
BaseDN "CN=Users,DC=example,DC=com"
SearchFilter "(&(objectClass=group)(cn=VPN IT Department))"
MemberAttribute member
MemberAttributeIsDN true
</Group>
</Authorization>
Configure client-specific configurations
Set up client-specific configurations based on group membership to provide different network access levels.
sudo mkdir -p /etc/openvpn/ccd
sudo chown root:root /etc/openvpn/ccd
sudo chmod 755 /etc/openvpn/ccd
Add this line to your server configuration to enable client-specific configurations:
# Add this line to the existing server.conf
client-config-dir /etc/openvpn/ccd
Verify your setup
sudo systemctl status openvpn-server@server
sudo netstat -tlunp | grep :1194
sudo tail -20 /var/log/openvpn/openvpn.log
ldapsearch -x -H ldap://dc1.example.com:389 -D "CN=vpn-service,CN=Users,DC=example,DC=com" -W -b "CN=Users,DC=example,DC=com" "(cn=VPN Users)"
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| LDAP bind failed | Wrong service account credentials | Verify BindDN and password in auth-ldap.conf |
| User authentication fails | User not in VPN group | Add user to "VPN Users" group in Active Directory |
| Can't connect to LDAP server | Firewall blocking port 389 | Allow port 389/tcp from OpenVPN server to domain controller |
| Certificate verification failed | Missing or wrong certificates | Regenerate certificates with sudo ./easyrsa build-server-full server nopass |
| No internet access through VPN | IP forwarding or NAT not configured | Check net.ipv4.ip_forward=1 and firewall NAT rules |
| Plugin load failed | LDAP plugin not installed | Install openvpn-auth-ldap package |
Next steps
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Script variables
SCRIPT_NAME=$(basename "$0")
LOG_FILE="/tmp/openvpn-ldap-install.log"
# Default values
LDAP_SERVER=""
LDAP_BIND_DN=""
LDAP_PASSWORD=""
LDAP_BASE_DN=""
usage() {
cat << EOF
Usage: $SCRIPT_NAME [OPTIONS]
Install and configure OpenVPN with LDAP authentication
OPTIONS:
-s, --ldap-server LDAP server URL (required)
-b, --bind-dn LDAP bind DN (required)
-p, --password LDAP bind password (required)
-d, --base-dn LDAP base DN (required)
-h, --help Show this help
Example:
$SCRIPT_NAME -s ldap://dc1.example.com:389 \\
-b "CN=vpn-service,CN=Users,DC=example,DC=com" \\
-p "password123" \\
-d "CN=Users,DC=example,DC=com"
EOF
}
error_exit() {
echo -e "${RED}Error: $1${NC}" >&2
exit 1
}
success_msg() {
echo -e "${GREEN}✓ $1${NC}"
}
warn_msg() {
echo -e "${YELLOW}⚠ $1${NC}"
}
info_msg() {
echo -e "ℹ $1"
}
cleanup() {
warn_msg "Installation failed. Check $LOG_FILE for details"
}
trap cleanup ERR
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-s|--ldap-server)
LDAP_SERVER="$2"
shift 2
;;
-b|--bind-dn)
LDAP_BIND_DN="$2"
shift 2
;;
-p|--password)
LDAP_PASSWORD="$2"
shift 2
;;
-d|--base-dn)
LDAP_BASE_DN="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
error_exit "Unknown option $1. Use -h for help."
;;
esac
done
# Validate required arguments
if [[ -z "$LDAP_SERVER" || -z "$LDAP_BIND_DN" || -z "$LDAP_PASSWORD" || -z "$LDAP_BASE_DN" ]]; then
error_exit "All LDAP parameters are required. Use -h for help."
fi
# Check if running as root
if [[ $EUID -ne 0 ]]; then
error_exit "This script must be run as root"
fi
# Detect distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update && apt upgrade -y"
PKG_INSTALL="apt install -y"
LDAP_PLUGIN_PATH="/usr/lib/openvpn/openvpn-auth-ldap.so"
OPENVPN_GROUP="nogroup"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
LDAP_PLUGIN_PATH="/usr/lib64/openvpn/plugins/openvpn-auth-ldap.so"
OPENVPN_GROUP="nobody"
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum update -y"
PKG_INSTALL="yum install -y"
LDAP_PLUGIN_PATH="/usr/lib64/openvpn/plugins/openvpn-auth-ldap.so"
OPENVPN_GROUP="nobody"
;;
*)
error_exit "Unsupported distribution: $ID"
;;
esac
else
error_exit "Cannot detect distribution"
fi
info_msg "Installing OpenVPN with LDAP authentication on $PRETTY_NAME"
# Step 1: Update system packages
echo "[1/8] Updating system packages..."
$PKG_UPDATE >> "$LOG_FILE" 2>&1
success_msg "System packages updated"
# Step 2: Install required packages
echo "[2/8] Installing OpenVPN and dependencies..."
if [[ "$PKG_MGR" == "apt" ]]; then
$PKG_INSTALL openvpn easy-rsa openvpn-auth-ldap libldap2-dev >> "$LOG_FILE" 2>&1
else
$PKG_INSTALL openvpn easy-rsa openvpn-auth-ldap openldap-devel >> "$LOG_FILE" 2>&1
fi
success_msg "OpenVPN and dependencies installed"
# Step 3: Setup Easy-RSA
echo "[3/8] Setting up Certificate Authority..."
mkdir -p /etc/openvpn/easy-rsa
cp -r /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/
cd /etc/openvpn/easy-rsa
# Initialize PKI and create CA
./easyrsa init-pki >> "$LOG_FILE" 2>&1
EASYRSA_BATCH=1 ./easyrsa build-ca nopass >> "$LOG_FILE" 2>&1
success_msg "Certificate Authority created"
# Step 4: Generate server certificates
echo "[4/8] Generating server certificates..."
EASYRSA_BATCH=1 ./easyrsa build-server-full server nopass >> "$LOG_FILE" 2>&1
./easyrsa gen-dh >> "$LOG_FILE" 2>&1
openvpn --genkey secret pki/ta.key >> "$LOG_FILE" 2>&1
success_msg "Server certificates generated"
# Step 5: Copy certificates
echo "[5/8] Installing certificates..."
mkdir -p /etc/openvpn/server
cp pki/ca.crt pki/issued/server.crt pki/private/server.key pki/dh.pem pki/ta.key /etc/openvpn/server/
chown root:root /etc/openvpn/server/*
chmod 600 /etc/openvpn/server/server.key /etc/openvpn/server/ta.key
chmod 644 /etc/openvpn/server/ca.crt /etc/openvpn/server/server.crt /etc/openvpn/server/dh.pem
# Create log directory
mkdir -p /var/log/openvpn
chown root:root /var/log/openvpn
chmod 755 /var/log/openvpn
success_msg "Certificates installed with proper permissions"
# Step 6: Create OpenVPN server configuration
echo "[6/8] Creating OpenVPN server configuration..."
cat > /etc/openvpn/server/server.conf << EOF
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
tls-auth ta.key 0
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
tls-crypt ta.key
cipher AES-256-GCM
auth SHA256
user nobody
group $OPENVPN_GROUP
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
explicit-exit-notify 1
plugin $LDAP_PLUGIN_PATH /etc/openvpn/auth-ldap.conf
client-cert-not-required
username-as-common-name
EOF
chmod 644 /etc/openvpn/server/server.conf
success_msg "OpenVPN server configuration created"
# Step 7: Create LDAP authentication configuration
echo "[7/8] Creating LDAP authentication configuration..."
cat > /etc/openvpn/auth-ldap.conf << EOF
<LDAP>
URL $LDAP_SERVER
BindDN "$LDAP_BIND_DN"
Password "$LDAP_PASSWORD"
Timeout 15
FollowReferrals yes
</LDAP>
<Authorization>
BaseDN "$LDAP_BASE_DN"
SearchFilter "(&(objectClass=user)(sAMAccountName=%u))"
RequireGroup false
</Authorization>
EOF
chmod 600 /etc/openvpn/auth-ldap.conf
chown root:root /etc/openvpn/auth-ldap.conf
success_msg "LDAP authentication configuration created"
# Step 8: Configure system services and firewall
echo "[8/8] Configuring system services..."
# Enable IP forwarding
echo 'net.ipv4.ip_forward = 1' > /etc/sysctl.d/99-openvpn-forward.conf
sysctl --system >> "$LOG_FILE" 2>&1
# Configure firewall based on available tools
if command -v firewall-cmd &> /dev/null; then
# RHEL-based systems with firewalld
systemctl enable firewalld >> "$LOG_FILE" 2>&1
systemctl start firewalld >> "$LOG_FILE" 2>&1
firewall-cmd --permanent --add-service=openvpn >> "$LOG_FILE" 2>&1
firewall-cmd --permanent --add-masquerade >> "$LOG_FILE" 2>&1
firewall-cmd --reload >> "$LOG_FILE" 2>&1
elif command -v ufw &> /dev/null; then
# Ubuntu/Debian with ufw
ufw --force enable >> "$LOG_FILE" 2>&1
ufw allow 1194/udp >> "$LOG_FILE" 2>&1
ufw allow OpenSSH >> "$LOG_FILE" 2>&1
fi
# Enable and start OpenVPN
systemctl enable openvpn-server@server >> "$LOG_FILE" 2>&1
systemctl start openvpn-server@server >> "$LOG_FILE" 2>&1
success_msg "System services configured"
# Verification
echo ""
info_msg "Verifying installation..."
if systemctl is-active --quiet openvpn-server@server; then
success_msg "OpenVPN server is running"
else
error_exit "OpenVPN server failed to start. Check logs: journalctl -u openvpn-server@server"
fi
if ss -ulpn | grep -q ":1194"; then
success_msg "OpenVPN is listening on port 1194/UDP"
else
warn_msg "OpenVPN may not be listening on expected port"
fi
echo ""
success_msg "OpenVPN LDAP installation completed successfully!"
echo ""
info_msg "Next steps:"
echo "1. Test LDAP connectivity: ldapsearch -H $LDAP_SERVER -D '$LDAP_BIND_DN' -w '$LDAP_PASSWORD' -b '$LDAP_BASE_DN'"
echo "2. Create client configuration files"
echo "3. Configure client certificates if needed"
echo "4. Monitor logs: tail -f /var/log/openvpn/openvpn.log"
echo ""
info_msg "Configuration files:"
echo "- Server config: /etc/openvpn/server/server.conf"
echo "- LDAP config: /etc/openvpn/auth-ldap.conf"
echo "- Certificates: /etc/openvpn/server/"
Review the script before running. Execute with: bash install.sh