When OpenVPN runs with user nobody
and group nogroup
, it drops privileges after initialization. The persist-tun
option maintains the TUN/TAP device across connection disruptions. Here's why this matters:
# Without persist-tun (problem scenario)
1. OpenVPN starts as root → creates tun0
2. Drops privileges to nobody/nogroup
3. Network disruption occurs
4. OpenVPN (as nobody) cannot recreate tun0 → connection fails
Observe these behavioral contrasts in server configurations:
# Sample config WITH persist-tun
dev tun
persist-tun
user nobody
group nogroup
keepalive 10 60
# Sample config WITHOUT persist-tun
dev tun
user nobody
group nogroup
keepalive 10 60
The TUN device handling differs significantly:
- With persist-tun: Device remains open as file descriptor even when inactive
- Without persist-tun: Device closes completely on connection drop
Key permission requirements for recreation:
$ ls -l /dev/net/tun
crw-rw-rw- 1 root root 10, 200 Feb 15 09:00 /dev/net/tun
# Required capabilities:
CAP_NET_ADMIN - for network device operations
CAP_IPC_LOCK - for key persistence (when using persist-key)
The complete interaction flow with keepalive:
1. Initial connection: [root] creates tun0 → drops privileges
2. Network hiccup occurs
3. Keepalive timeout triggers reconnection
4. With persist-tun: Reuses existing tun0 (nobody can access)
5. Without persist-tun: Fails (nobody cannot create new tun0)
For different deployment scenarios:
# Secure production setup (recommended)
persist-tun
persist-key
user nobody
group nogroup
keepalive 10 60
tls-auth /etc/openvpn/ta.key 0
# Debugging setup (root required)
dev tun
keepalive 10 60
verb 4
Diagnostic commands for persistence problems:
# Check device persistence
ip link show tun0
# Verify running privileges
ps aux | grep openvpn
# Check capability retention
cat /proc/[PID]/status | grep Cap
The persist-tun
directive prevents OpenVPN from tearing down and recreating the TUN/TAP interface during connection flaps. When running as non-root (typically user nobody
and group nogroup
), OpenVPN loses the capability to recreate network interfaces after initial setup.
# Server configuration demonstrating critical options
user nobody
group nogroup
persist-tun
persist-key
keepalive 10 60
dev tun0
Without persist-tun
, OpenVPN's standard behavior would be:
- Create tun0 during initialization (requires root)
- Drop privileges to nobody/nogroup
- Destroy tun0 on connection termination
- Fail to recreate tun0 during reconnection (missing root privileges)
The visible effects in ifconfig
can be misleading. What matters is the interface's operational state:
# Shows interface exists regardless of persist-tun
$ ip link show tun0
8: tun0: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 100
Option | Relationship with persist-tun |
---|---|
persist-key | Maintains SSL/TLS key between reconnections |
keepalive | Triggers reconnection attempts where persist-tun enables success |
user/group | Creates the privilege boundary requiring persist-tun |
When troubleshooting, check these log patterns:
# Successful reconnection with persist-tun:
Thu Jul 20 10:15:23 2023 /sbin/ip link set dev tun0 up mtu 1500
# Failed reconnection without persist-tun:
Thu Jul 20 10:15:25 2023 Cannot allocate TUN/TAP dev dynamically
For production deployments, consider this enhanced configuration:
# Secure production setup
user nobody
group nogroup
persist-tun
persist-key
chroot /var/lib/openvpn
dev tun
topology subnet
keepalive 10 120
remote-cert-tls client
tls-auth /etc/openvpn/ta.key 0