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


2 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