Skip to main content

Overview

OpenVPN server mode enables a single OpenVPN instance to handle multiple concurrent client connections. This guide covers everything from basic server setup to advanced features like client-specific configurations and VLAN tagging.
OpenVPN server mode requires SSL/TLS authentication and can support hundreds or thousands of clients on sufficiently fast hardware.

Basic server configuration

Here’s a production-ready server configuration based on the OpenVPN 2.6 sample:
server.conf
#################################################
# Sample OpenVPN 2.6 config file for            #
# multi-client server.                          #
#################################################

# Which TCP/UDP port should OpenVPN listen on?
port 1194

# TCP or UDP server?
proto udp

# "dev tun" will create a routed IP tunnel,
# "dev tap" will create an ethernet tunnel.
dev tun

# SSL/TLS root certificate (ca), certificate
# (cert), and private key (key).
ca ca.crt
cert server.crt
key server.key  # This file should be kept secret

# Network topology
# Should be subnet (addressing via IP)
topology subnet

# Configure server mode and supply a VPN subnet
# for OpenVPN to draw client addresses from.
server 10.8.0.0 255.255.255.0

# Maintain a record of client <-> virtual IP address
# associations in this file.
ifconfig-pool-persist ipp.txt

# Push routes to the client to allow it
# to reach other private subnets behind
# the server.
;push "route 192.168.10.0 255.255.255.0"
;push "route 192.168.20.0 255.255.255.0"

# Uncomment this directive to allow different
# clients to be able to "see" each other.
;client-to-client

# The keepalive directive causes ping-like
# messages to be sent back and forth over
# the link so that each side knows when
# the other side has gone down.
keepalive 10 120

# It's a good idea to reduce the OpenVPN
# daemon's privileges after initialization.
;user openvpn
;group openvpn

# The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-tun

# Output a short status file showing
# current connections, truncated
# and rewritten every minute.
status openvpn-status.log

# Set the appropriate level of log
# file verbosity.
verb 3

# Notify the client that when the server restarts so it
# can automatically reconnect.
explicit-exit-notify 1

Server setup process

1

Generate certificates and keys

Use Easy-RSA or your PKI to generate:
  • CA certificate (ca.crt)
  • Server certificate (server.crt)
  • Server private key (server.key)
  • Diffie-Hellman parameters (dh2048.pem)
# Using Easy-RSA 3.x
./easyrsa init-pki
./easyrsa build-ca
./easyrsa build-server-full server nopass
./easyrsa gen-dh
2

Place files in the correct location

sudo mkdir -p /etc/openvpn/server
sudo cp ca.crt server.crt server.key dh2048.pem /etc/openvpn/server/
sudo chmod 600 /etc/openvpn/server/server.key
sudo chmod 644 /etc/openvpn/server/*.crt
3

Configure the server

Create or edit /etc/openvpn/server/server.conf with your desired settings.
4

Enable IP forwarding

echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
5

Configure firewall

# Allow OpenVPN traffic
sudo iptables -A INPUT -p udp --dport 1194 -j ACCEPT

# Enable NAT for VPN clients
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

# Save rules
sudo iptables-save | sudo tee /etc/iptables/rules.v4
6

Start the server

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

Server mode options

The —server directive

The --server directive is a helper that simplifies server configuration:
# Simple form
server 10.8.0.0 255.255.255.0

# This automatically configures:
# - mode server
# - tls-server
# - ifconfig-pool for client IPs
# - route for the VPN subnet
# - push topology and routes to clients
The server takes the .1 address (10.8.0.1) as its VPN endpoint. Client IPs are allocated from the remaining addresses.

Prevent IP pool allocation

# Don't create dynamic IP pool (use only static assignments)
server 10.8.0.0 255.255.255.0 nopool

Network topology

# Recommended: subnet topology (more efficient)
topology subnet

# Legacy: net30 topology (for old Windows clients)
# topology net30

# Point-to-point topology
# topology p2p
The net30 topology is deprecated and wastes IP addresses. Use subnet topology for new deployments.

Client IP address management

Dynamic IP assignment

Clients receive IPs from the configured pool:
# Basic pool configuration (automatic with --server)
server 10.8.0.0 255.255.255.0

# Persist client IP assignments across restarts
ifconfig-pool-persist ipp.txt

# Custom pool (without --server helper)
ifconfig-pool 10.8.0.100 10.8.0.200

Static IP assignment

Assign specific IPs to clients using client config directory:
1

Enable client config directory

server.conf
client-config-dir /etc/openvpn/ccd
2

Create client-specific config

sudo mkdir -p /etc/openvpn/ccd
sudo nano /etc/openvpn/ccd/client1
3

Configure static IP

/etc/openvpn/ccd/client1
# Assign 10.8.0.100 to this client
ifconfig-push 10.8.0.100 255.255.255.0
The filename in /etc/openvpn/ccd/ must exactly match the client’s certificate Common Name (CN).

IPv6 support

# Enable IPv6 for the server
server-ipv6 fd00:1234:5678::/64

# Or configure manually
ifconfig-ipv6 fd00:1234:5678::1/64 fd00:1234:5678::2
ifconfig-ipv6-pool fd00:1234:5678::/64

# Push IPv6 routes
push "route-ipv6 fd00::/8"

Routing configuration

Push routes to clients

Make internal networks accessible to VPN clients:
# Push routes to private networks behind the server
push "route 192.168.10.0 255.255.255.0"
push "route 192.168.20.0 255.255.255.0"

# Make VPN the default gateway for all traffic
push "redirect-gateway def1 bypass-dhcp"

# Push DNS servers
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

Modern DNS configuration

OpenVPN 2.6+ supports the --dns directive:
# Configure DNS server for clients
push "dns server 0 address 8.8.8.8"
push "dns server 0 address 8.8.4.4"

# Configure search domains
push "dns search-domains company.local"

Internal routes (iroute)

Route traffic for client subnets through specific clients:
1

Configure internal route

/etc/openvpn/ccd/client1
# Client1 has subnet 192.168.40.0/24 behind it
iroute 192.168.40.0 255.255.255.0
ifconfig-push 10.8.0.100 255.255.255.0
2

Add system route

server.conf
# Add route to the system routing table
route 192.168.40.0 255.255.255.0
You need both --iroute (OpenVPN internal) and --route (system routing table) for client-side subnets to work properly.

Client-to-client communication

# Allow clients to see each other
client-to-client

# With this enabled, clients can directly communicate
# Otherwise, clients can only reach the server
When using Data Channel Offload (DCO), client-to-client has no effect. Traffic is always routed through the system routing table.

Security options

TLS authentication

Add HMAC authentication for additional security:
# Generate TLS auth key
openvpn --genkey secret ta.key
# Enable TLS auth (server uses direction 0)
tls-auth ta.key 0

Certificate verification

# Require client certificates
verify-client-cert require  # Default

# Allow connections without client cert (username/password only)
verify-client-cert none

# Optional client cert
verify-client-cert optional

Username/password authentication

# Use script for password verification
auth-user-pass-verify /etc/openvpn/auth.sh via-file
script-security 2

# Generate session tokens
auth-gen-token 86400  # Token lifetime in seconds
auth-gen-token-secret /etc/openvpn/auth-token.key

Cipher configuration

# Modern ciphers (OpenVPN 2.4+)
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305

# Support legacy clients (OpenVPN 2.3.x)
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305:AES-256-CBC

# TLS authentication digest
auth SHA512

Performance and scaling

Connection limits

# Limit concurrent clients
max-clients 100

# Limit routes per client (DoS protection)
max-routes-per-client 256

# Connection rate limiting
connect-freq 10 60  # Max 10 new connections per 60 seconds

# Initial connection rate limiting (UDP)
connect-freq-initial 100 10  # Max 100 initial packets per 10 seconds

Keepalive settings

# Ping every 10 seconds, assume down after 120 seconds
keepalive 10 120

# This is equivalent to:
# ping 10
# ping-restart 120

Data Channel Offload (DCO)

DCO improves performance by offloading data channel to the kernel:
# DCO is enabled by default in OpenVPN 2.6+
# To disable:
# disable-dco

Multi-homed server

# Server with multiple IP addresses (UDP only)
multihome

# Force same interface for replies
multihome same-interface

Client-specific configurations

Client Config Directory (CCD)

server.conf
# Enable per-client configuration
client-config-dir /etc/openvpn/ccd

# Require CCD file for all clients
ccd-exclusive
Create per-client configs in /etc/openvpn/ccd/:
# Static IP for john
ifconfig-push 10.8.0.10 255.255.255.0

# Custom routes for john
push "route 192.168.100.0 255.255.255.0"

# John's internal subnet
iroute 192.168.50.0 255.255.255.0

Push configuration options

Available options that can be pushed to clients:
# Routes
push "route 192.168.1.0 255.255.255.0"
push "route-gateway 10.8.0.1"

# DNS
push "dhcp-option DNS 8.8.8.8"
push "dns server 0 address 8.8.8.8"

# Timeouts
push "inactive 3600"
push "ping 10"
push "ping-restart 120"

# Redirect gateway
push "redirect-gateway def1 bypass-dhcp"

# Compression (not recommended)
# push "comp-lzo"

Push filtering

Remove or modify pushed options per client:
/etc/openvpn/ccd/limited-client
# Remove all global push options
push-reset

# Add only specific routes
push "route 10.8.0.0 255.255.255.0"

# Or selectively remove options
push-remove "redirect-gateway"
push-remove "route 192.168.10"

Ethernet bridging

For Layer 2 VPN (TAP mode):
# Use TAP device
dev tap

# Configure bridging with DHCP
server-bridge

# Or specify IP pool
server-bridge 10.8.0.4 255.255.255.0 10.8.0.100 10.8.0.200

# Don't push gateway
server-bridge nogw
1

Create bridge interface

# Linux
sudo apt-get install bridge-utils
sudo brctl addbr br0
sudo brctl addif br0 eth0
sudo brctl addif br0 tap0
2

Configure bridge IP

sudo ip addr add 10.8.0.4/24 dev br0
sudo ip link set br0 up
3

Start OpenVPN

OpenVPN will add tap0 to the bridge automatically if configured correctly.

Advanced features

VLAN tagging

# Enable VLAN support (TAP mode only)
vlan-tagging

# Configure VLAN acceptance
vlan-accept all  # tagged, untagged, or all (default)

# Server TAP VLAN ID
vlan-pvid 1
Assign clients to VLANs:
/etc/openvpn/ccd/vlan10-client
vlan-pvid 10

Duplicate Common Names

# Allow multiple clients with same certificate
duplicate-cn
Only use duplicate-cn for testing. In production, each client should have a unique certificate.

Learn address script

# Execute script when client connects/disconnects
learn-address /etc/openvpn/learn-address.sh
script-security 2

Port sharing

Share OpenVPN TCP port with HTTPS:
proto tcp
port 443

# Forward non-OpenVPN traffic to web server
port-share localhost 8443

Logging and monitoring

Status file

# Write status every 60 seconds
status /var/log/openvpn-status.log 60

# Status format version
status-version 3  # Tab-separated for easy parsing

Log configuration

# Verbosity (0=silent, 3=normal, 6=debug, 9=extremely verbose)
verb 3

# Suppress duplicate messages
mute 20

# Write to log file
log /var/log/openvpn.log

# Or append to existing log
log-append /var/log/openvpn.log

Management interface

# Enable management interface
management localhost 7505

# Or on Unix socket
management /var/run/openvpn-mgmt.sock unix
Connect to management interface:
telnet localhost 7505
# Then use commands: status, kill, etc.

Complete example configurations

Production server (routed)

# OpenVPN 2.6 Production Server
port 1194
proto udp
dev tun

# Certificates
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
dh /etc/openvpn/server/dh2048.pem

# Network
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt

# Routes
push "route 192.168.1.0 255.255.255.0"
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

# Security
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
auth SHA512
tls-auth /etc/openvpn/server/ta.key 0
remote-cert-tls client

# Client configs
client-config-dir /etc/openvpn/ccd
client-to-client

# Connection
keepalive 10 120
max-clients 100
connect-freq 10 60

# Performance
persist-tun
persist-key

# Privileges
user openvpn
group openvpn

# Logging
status /var/log/openvpn/status.log 60
log-append /var/log/openvpn/openvpn.log
verb 3
mute 20

# Notify clients on restart
explicit-exit-notify 1

High-security server

port 443
proto tcp
dev tun

ca ca.crt
cert server.crt  
key server.key

topology subnet
server 10.8.0.0 255.255.255.0

# Strong authentication
auth-user-pass-verify /etc/openvpn/auth.sh via-file
script-security 2
verify-client-cert require
auth-gen-token 43200
auth-gen-token-secret /etc/openvpn/token.key

# Strong ciphers only
data-ciphers AES-256-GCM:CHACHA20-POLY1305
tls-version-min 1.3
auth SHA512
tls-auth ta.key 0

# Strict limits
max-clients 50
max-routes-per-client 100
connect-freq 5 60

# CCD required
client-config-dir /etc/openvpn/ccd
ccd-exclusive

keepalive 10 120
persist-tun

user openvpn
group openvpn

status /var/log/openvpn-status.log 30
log-append /var/log/openvpn.log  
verb 3

Troubleshooting

Enable detailed logging

verb 6  # Debug level
log /var/log/openvpn-debug.log

Check server status

# View status file
cat /var/log/openvpn-status.log

# Check connected clients
sudo systemctl status openvpn-server@server

# View logs
sudo journalctl -u openvpn-server@server -f

Common issues

IssueCauseSolution
Clients can’t connectFirewall blockingCheck firewall rules and port forwarding
No internet through VPNNAT not configuredEnable IP forwarding and configure NAT
Clients can’t see each otherclient-to-client disabledEnable client-to-client
”TLS handshake failed”Certificate issuesVerify all certificates are valid and match

Next steps

Build docs developers (and LLMs) love