When running OpenVPN in an LXC container, you might encounter the following error indicating missing TUN/TAP device support:
Tue Sep 18 13:04:18 2012 Note: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2)
Tue Sep 18 13:04:18 2012 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Tue Sep 18 13:04:18 2012 /sbin/ifconfig 10.6.0.1 pointopoint 10.6.0.2 mtu 1500
LXC containers by default don't have access to kernel modules or special devices like /dev/net/tun. The error suggests two distinct issues:
- Missing device node (/dev/net/tun)
- Insufficient container permissions
First, ensure your container configuration includes both device permission and creation:
# Allow TUN device
lxc.cgroup.devices.allow = c 10:200 rwm
# Create device node
lxc.mount.entry = /dev/net/tun dev/net/tun none bind,create=file
The modprobe error indicates missing kernel headers. For Ubuntu/Debian containers, run:
apt-get update
apt-get install linux-headers-$(uname -r) module-init-tools
For CentOS/RHEL:
yum install kernel-headers-$(uname -r)
Here's a verified working LXC configuration for OpenVPN:
# Network configuration
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
# TUN/TAP configuration
lxc.cgroup.devices.allow = c 10:200 rwm
lxc.mount.entry = /dev/net/tun dev/net/tun none bind,create=file
lxc.cap.drop =
lxc.cap.keep = net_admin
After restarting the container, verify device availability:
ls -l /dev/net/tun
# Expected output: crw-rw-rw- 1 root root 10, 200 Sep 18 14:00 /dev/net/tun
test -c /dev/net/tun && echo "TUN device exists" || echo "TUN missing"
For development environments, you can use privileged containers as a temporary solution:
lxc launch ubuntu:20.04 mycontainer --config security.privileged=true
However, this isn't recommended for production due to security implications.
When running OpenVPN inside an LXC container, you'll encounter the "No such file or directory" error for /dev/net/tun
because:
- Containers by default don't have access to TUN/TAP devices
- The device node isn't automatically created in the container
- Missing kernel modules in the container environment
First, modify your LXC container configuration. The correct device permission should be:
# Enable TUN device
lxc.cgroup.devices.allow = c 10:200 rwm
But this alone isn't sufficient - you need to create the device node inside the container:
mkdir -p /dev/net
mknod /dev/net/tun c 10 200
chmod 0666 /dev/net/tun
The error about missing /lib/modules
indicates the container lacks kernel headers. You have two approaches:
Option 1: Share host modules (recommended)
# On host:
mount --bind /lib/modules /var/lib/lxc/YOUR_CONTAINER/rootfs/lib/modules
# In container config:
lxc.mount.entry = /lib/modules lib/modules none bind,ro 0 0
Option 2: Minimal module installation
# For Debian/Ubuntu containers:
apt-get install linux-modules-extra-$(uname -r)
After making these changes, test the TUN device:
# Check device existence:
ls -l /dev/net/tun
# Test device functionality:
openvpn --mktun --dev tun0
ip link show tun0
To make these changes permanent, create a startup script in the container:
#!/bin/sh
mkdir -p /dev/net
[ -c /dev/net/tun ] || mknod /dev/net/tun c 10 200
chmod 0666 /dev/net/tun
And add it to your container's rc.local
or equivalent startup mechanism.
- If you see "Operation not permitted" errors, verify your LXC version supports cgroup2
- For unprivileged containers, additional user namespace configuration may be needed
- Some distributions require the
tun
module to be loaded on the host first