How to Fix “No TUN Device in LXC Container” Error for OpenVPN Setup


10 views

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:

  1. Missing device node (/dev/net/tun)
  2. 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