OpenVPN Client-to-Client Communication Bypass: Why Disabled Setting Still Allows Peer Connectivity


1 views

During a recent OpenVPN deployment using TUN (layer 3) mode, I noticed an odd behavior where clients could still communicate with each other despite having client-to-client explicitly disabled in the server configuration. This contradicts OpenVPN's documentation which states:

"Uncomment out the client-to-client directive if you would like connecting clients to be able to reach each other over the VPN. By default, clients will only be able to reach the server."

The observed configuration contains these relevant parameters:

dev tun
topology subnet
server 10.10.201.0 255.255.255.128
ifconfig-pool-persist ipp.txt

The topology subnet directive combined with server network declaration creates a different routing behavior than classic point-to-point TUN setups.

When using topology subnet, OpenVPN creates a true subnet rather than individual point-to-point connections. In this mode:

  • The server acts as a gateway with its own IP (e.g., 10.10.201.1)
  • Clients receive IPs from the defined pool (e.g., 10.10.201.2-10.10.201.126)
  • The OS routing table sees this as a regular network segment

To properly isolate clients, consider these approaches:

1. Firewall Rules on Server

Add iptables rules to block inter-client traffic:

iptables -A FORWARD -i tun+ -o tun+ -j DROP
iptables -A FORWARD -i tun+ -d 10.10.201.0/25 -j DROP

2. Client-Specific Rules

Use OpenVPN's client-config-dir to push unique firewall rules:

# In server.conf
client-config-dir /etc/openvpn/ccd

# Example client file (/etc/openvpn/ccd/client1)
iroute 10.10.201.0 255.255.255.128
push "route 10.10.201.0 255.255.255.128"

3. Alternative Topology

Switch to point-to-point topology if strict isolation is required:

topology net30
server 10.10.201.0 255.255.255.252

To confirm client isolation:

# From Client A (10.10.201.2)
ping 10.10.201.3
traceroute 10.10.201.3

# Check routing tables
ip route show table all

Remember that complete isolation may require additional measures depending on your OS and network stack implementation.


When configuring an OpenVPN server with client-to-client disabled in TUN (layer 3) mode, administrators often expect complete client isolation. However, in certain configurations, clients can still communicate with each other despite this setting being disabled.

In your configuration:

server 10.10.201.0 255.255.255.128
topology subnet

This creates a bridged network environment where clients receive IP addresses from the same subnet (10.10.201.0/25). The Linux kernel's routing table automatically creates routes between these IPs at layer 3, bypassing OpenVPN's client-to-client restriction which primarily works at the VPN application layer.

The client-to-client directive mainly prevents OpenVPN from explicitly pushing client routes to other clients. However, with:

topology subnet
ifconfig-pool-persist ipp.txt

The system creates direct IP routes that don't require OpenVPN's involvement for client-to-client communication.

Solution 1: Implement Proper Firewall Rules

Add these iptables rules to your OpenVPN server configuration:

iptables -A FORWARD -i tun+ -o tun+ -j DROP
iptables -A FORWARD -i tun+ ! -o tun+ -j ACCEPT
iptables -A FORWARD -o tun+ -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

Solution 2: Modify Server Configuration

Update your server configuration with these additional parameters:

client-to-client
route 10.10.201.0 255.255.255.128
push "route 10.10.201.0 255.255.255.128"
client-config-dir /etc/openvpn/ccd

Then create individual client configuration files in /etc/openvpn/ccd/ that specify allowed routes.

To confirm your isolation is working:

# From Client A:
ping 10.10.201.2
traceroute 10.10.201.2

# Check routing tables:
ip route show table all

# Verify firewall rules:
iptables -L -n -v

For strict isolation, consider using:

topology net30
server 10.10.201.0 255.255.255.252

This allocates /30 networks to each client pair, providing better isolation but reducing the total number of available client IPs.