openvpn--ERROR: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2) [SOLVED]


#1

LXC 2.0.7 on Debian stretch

I cannot create /dev/net/tun in my unprivileged container. The container is running a systemd-less Debian distro called Devuan.

I have done much Googling and haven’t found a solution. Could this be a result of running an unpriviledged container needing a privileged capability? If so, is there a work-around? Any help appreciated…

Starting openvpn from the container commandline gives:

ERROR: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2)

Trying to make the tun device manually throws an Operation not permitted error:

$ mkdir -p /dev/net
$ mknod /dev/net/tun c 10 200
mknod: ‘/dev/net/tun’: Operation not permitted

(Stéphane Graber) #2

Unprivileged containers can’t create device nodes, that’s a kernel enforced policy for those.
Instead what you should do is bind-mount that device node from the host.

Something like:

lxc.mount.entry = /dev/net/tun dev/net/tun none bind create=file

Should do the trick.


#3

In LXD 3.0, I created an unprivileged 18.04 container and set up openvpn.
It then managed to create the tun device,

root@openvpn:~# ip route
default via 10.52.252.1 dev eth0 proto dhcp src 10.52.252.109 metric 100 
10.10.10.0/24 via 10.10.14.1 dev tun0 
10.10.14.0/23 dev tun0 proto kernel scope link src 10.10.15.55 
10.52.252.0/24 dev eth0 proto kernel scope link src 10.52.252.109 
10.52.252.1 dev eth0 proto dhcp scope link src 10.52.252.109 metric 100 
root@openvpn:~# ping 10.10.14.1
PING 10.10.14.1 (10.10.14.1) 56(84) bytes of data.
64 bytes from 10.10.14.1: icmp_seq=1 ttl=64 time=80.4 ms
64 bytes from 10.10.14.1: icmp_seq=2 ttl=64 time=78.3 ms
^C
--- 10.10.14.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 78.375/79.422/80.470/1.084 ms
root@openvpn:~# ls -l /dev/net/tun 
crw-rw-rw- 1 nobody nogroup 10, 200 Apr 23 07:35 /dev/net/tun
root@openvpn:~#

The only thing that did not work, was for openvpn to create a default route to the VPN, using a smaller metric so that it takes precedence,


#4

Thanks for the response stgraber. I had to add a comma before the create=file part, or else it would through an error.

lxc.mount.entry = /dev/net/tun dev/net/tun none bind,create=file

Now I have the /dev/net/tun device being created within the container but when I start the openvpn I get the following error:

$ openvpn --config config_file.ovpn
... 
ERROR: Cannot open TUN/TAP dev /dev/net/tun: Permission denied (errno=13)
...

tun module loading on host:

$ lsmod | grep tun
tun                    28672  0

tunctl output on host:

$ tunctl
Set 'tap0' persistent and owned by uid 0

from within the container (Is this the problem?):

$ ls -l /dev/net/tun
crw------- 1 nobody nogroup 10, 200 Apr 22 00:15 /dev/net/tun

#5

simos, I have looked into LXD, but unfortunately it is not ready for Debian yet, from what I have gleaned.


(Stéphane Graber) #6

The permissions could be a problem if you’re running openvpn as non-root.
It’s odd though as the file on the host /dev/net/tun should have been 666 not 600, at least that’s how I see it on my system.


#7

stgraber, [SOLVED]

Using your original suggestion and running the following on the host fixed the problem.
chmod 666 /dev/net/tun

Thanks for your assistance…

So for a recap for anyone else having this problem:
Add the following to your container config file in /var/lib/lxc/[container]/config

lxc.mount.entry = /dev/net/tun dev/net/tun none bind,create=file

Then start the container and check the host /dev/net/tun permissions:

$ ls -l /dev/net/tun
crw-rw-rw- 1 root root 10, 200 Apr 21 20:15 /dev/net/tun

NOTE: I didn’t need this step on a second container host I am running. The permissions were correct. However, if they are not 666 as above run (on the host):

chmod 666 /dev/net/tun


#8

Great discussion, I just wanted to share what I did to fix the problem:

lxc.hook.autodev = sh -c "modprobe tun"
lxc.mount.entry=/dev/net/tun /var/lib/lxc/<Container Name>/rootfs/dev/net/tun none bind,create=file
lxc.hook.autodev = sh -c "chmod 0666 /var/lib/lxc/<Container Name>/rootfs/dev/net/tun"