Skip to main content
OpenVPN supports two primary operational modes that determine how tunnels are established and managed. Understanding these modes is essential for configuring OpenVPN correctly for your use case.

Operational modes overview

OpenVPN can operate in two distinct modes defined in src/openvpn/openvpn.c:303:
/* run tunnel depending on mode */
switch (c.options.mode)
{
    case MODE_POINT_TO_POINT:
        tunnel_point_to_point(&c);
        break;

    case MODE_SERVER:
        tunnel_server(&c);
        break;

    default:
        ASSERT(0);
}
Each mode uses a different event loop implementation optimized for its specific use case.

Point-to-point mode

Point-to-point (P2P) mode creates a single tunnel between two peers. This is the simpler of the two modes and is ideal for connecting two specific endpoints.

Characteristics

Best suited for:
  • Site-to-site VPN connections
  • Simple two-endpoint tunnels
  • Scenarios where the tunnel should not interfere with overall routing
  • “Dumb” tunnel behavior similar to GRE
P2P mode is useful when you want the OpenVPN tunnel to behave more like a traditional point-to-point link without complex routing interactions.

P2P mode with TLS

When using TLS in P2P mode, both peers perform mutual authentication:
  • Each peer verifies the other’s certificate
  • Session keys are derived using the TLS handshake
  • Renegotiation can occur based on time or traffic limits
  • No central authority managing the connection
In TLS P2P mode, both peers are essentially equal - there’s no inherent client/server relationship at the OpenVPN protocol level, though the TLS handshake still has a client and server role.

P2P mode with static keys

Static key mode is the simplest OpenVPN configuration:
  • Single pre-shared secret key file
  • No TLS handshake overhead
  • No perfect forward secrecy
  • Includes timestamp for replay protection
Static key mode does not provide perfect forward secrecy. If the key is compromised, all past and future traffic can be decrypted. Use TLS mode for better security.

P2P mode with DCO

Data Channel Offload is available in P2P mode with some requirements:
DCO requires DATA_V2 format, which is available for P2P mode only in OpenVPN 2.6 and later.
From README.dco.md:66:
DCO is also available when running OpenVPN in P2P mode without `--pull` /
`--client` option. P2P mode is useful for scenarios when the OpenVPN tunnel
should not interfere with overall routing and behave more like a "dumb" tunnel,
like GRE.

However, DCO requires DATA_V2 to be enabled, which is available for P2P mode
only in OpenVPN 2.6 and later.
Check your logs for:
P2P mode NCP negotiation result: TLS_export=1, DATA_v2=1, 
  peer-id 9484735, cipher=AES-256-GCM
Verify DATA_v2=1 and an AEAD cipher (AES-XXX-GCM or CHACHA20POLY1305).

Client-server mode

Client-server mode allows a single OpenVPN server to manage multiple client connections simultaneously. This is the most common deployment model for VPN services.

Characteristics

  • Scalable: Support for hundreds or thousands of concurrent clients
  • Centralized: Server controls routing, addressing, and policies
  • Dynamic: Clients can connect and disconnect without server restart
  • Flexible: Push configuration options to clients

Server responsibilities

The server performs several critical functions:
Virtual IP assignment
  • Assigns unique virtual IP addresses to each client
  • Maintains an address pool
  • Can use static assignments based on common name
  • Supports both IPv4 and IPv6
server 10.8.0.0 255.255.255.0
topology subnet
Pushing options to clients
  • Routes to add on the client
  • DNS server addresses
  • DHCP options
  • Custom client options
push "route 192.168.1.0 255.255.255.0"
push "dhcp-option DNS 10.8.0.1"
Inter-client routing
  • Routes traffic between clients (client-to-client)
  • Routes traffic from clients to internal networks (iroutes)
  • Consults kernel routing tables for forwarding decisions (with DCO)
From README.dco.md:85:
The ovpn-dco kernel module implements a more transparent approach to
configuring routes to clients (aka "iroutes") and consults the main kernel
routing tables for forwarding decisions.

Multi-instance management

The server maintains separate state for each connected client:
  • Separate TLS sessions per client
  • Per-client encryption keys
  • Individual statistics and accounting
  • Client-specific access controls

Topology options

Server mode supports different network topologies:

Protocol differences

The two modes use different packet formats and protocols:

Control channel

Both modes use the same control channel protocol for:
  • TLS handshake
  • Key exchange
  • Authentication
  • Keep-alive messages
The control channel is managed by functions in src/openvpn/ssl.h.

Data channel packets

Data packet format version 1Basic data packet format:
  • 1-byte opcode with key ID
  • HMAC (optional)
  • Cipher IV
  • Packet ID
  • Encrypted payload
From src/openvpn/ssl.h:336:
/**
 * Prepend a one-byte OpenVPN data channel P_DATA_V1 opcode 
 * to the packet.
 *
 * The opcode identifies the packet as a V1 data channel packet 
 * and gives the low-permutation version of the key-id to the 
 * recipient, so it knows which decrypt key to use.
 */
void tls_prepend_opcode_v1(const struct tls_multi *multi, 
                           struct buffer *buf);

Mode selection guidelines

Use point-to-point mode when:
  • Connecting exactly two endpoints
  • Building site-to-site VPNs
  • You need maximum simplicity
  • Static configuration is acceptable
  • No need for dynamic routing
  • Want minimal overhead

Configuration examples

Basic P2P configuration

# peer1.conf
dev tun
ifconfig 10.8.0.1 10.8.0.2
secret static.key
remote peer2.example.com
port 1194
proto udp

Basic client-server configuration

# server.conf
mode server
dev tun
server 10.8.0.0 255.255.255.0
topology subnet

ca ca.crt
cert server.crt
key server.key
dh dh2048.pem

push "route 192.168.1.0 255.255.255.0"
push "dhcp-option DNS 10.8.0.1"

keepalive 10 120
cipher AES-256-GCM