[SOLVED] OpenVPN in unprivileged container

marianh

Active Member
Sep 11, 2017
17
1
43
50
Hi,

is it possible to run OpenVPN server in unprivileged container?
I could not get the /dev/net/tun working. I tried some hints from google search but I did not succeed...
(all works fine in privileged container)
 
But that thread is not about unprivileged container right?
As I wrote, it works for me in privileged one (incl. after reboot, I re-create the tun device)

But reading that thread I tried:
lxc.cgroup.devices.allow: c 200:* rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,optional,create=file

Is that ok or a is it a bad practice for some reason?
 
Hi,

Yes it works but you have to bring your tun up manual after the container is running.

https://forum.proxmox.com/threads/turnkey-linux-openvpn-template-issues.31668/#post-157372

ur shure about this ?
i do nothing iwth lcx at all but a regular linux you can set a tun as a static interface in interfaces
like

Code:
auto tun0
iface tun0 inet static
    address                     192.168.15.1
    netmask                     255.255.255.255
    network                     192.168.15.2
    pre-up                      openvpn --mktun --dev tun0

so maybe if you can set it up as a nic like this you may not need the manual thing
what this does is it will create you a simple network interface regarless if openvpn runs or not
openvpn will simply use it at start if its there

this way openvpn does nto need to create that interface and also iptables do not need a reload after it is up

then again i have no clue about lcx, i only run full virt, im just curious if you could setup at statical inface in lcx
 
OpenVPN in unprivileged container working fine with Debian 9, but I still have an issue about the TUN device. I made a service to create the TUN device when the system booting up. (The TUN device successful creating!) But unfortunately the OpenVPN software can't see. If you check, you will find everything is fine but not works. If you stop the OpenVPN demon and create manually a second TUN device and start to use in OpenVPN program then the second TUN device is working fine.
Any idea please?

Best regards,
zuliasro
 
I have this working (OpenVPN, unprivileged) with only:

Code:
lxc.mount.entry = /dev/net dev/net none bind,create=dir

in:

Code:
/etc/pve/lxc/102.conf

From inside the container, I see:

Code:
# ls -l /dev/net/
total 0
crw-rw-rw- 1 nobody nogroup 10, 200 Sep 13 02:14 tun

OpenVPN complains about this:

Code:
 openvpn[176]: Note: Cannot set tx queue length on tun0: Operation not permitted (errno=1)

but it works anyway. I read elsewhere that the default is 100 and it's trying to set 100, so nothing to worry about.

For systemd, you need to :

Code:
cp /lib/systemd/system/openvpn-client\@.service /etc/systemd/system/

and comment out the line from the copy in /etc/:

Code:
LimitNPROC=10

then:

Code:
 systemctl daemon-reload

because unprivileged containers can't do that. I suppose one could create an overrides directory instead, but this was easy for me to deploy.

There are also other systemd complaints:

Code:
systemd[1]: openvpn.service: Failed to reset devices.list: Operation not permitted 
systemd[1]: openvpn.service: Failed to set invocation ID on control group /system.slice/openvpn.service,

that do not seem to prevent correct operation. I am curious what they mean to cut down on inefficient work, but operationally they're OK.

I am currently routing via one container to another site, with routes on other containers in place to get them connectivity as well and it's working fine now.

Future work should be getting openvpn root-free with a little bit of sudo for the essential bits. There is some documentation on openvpn.net on how to do this, though the Debian package is still defaulting to running as root.
 
  • Like
Reactions: grin and hvisage
Sorry to bring up this old thread, but I've been trying to run an openvpn server in an unprivileged container. Previously I was able to do this just fine in a Debian 9 container. But lately it hasn't been working.

I've tried Bill's steps above and added
Code:
lxc.mount.entry = /dev/net dev/net none bind,create=dir
to my LXC config file. But when I try
Code:
chmod 0666 /dev/net/tun
it complains of:
Code:
chmod: changing permissions of '/dev/net/tun': Operation not permitted`

Of course if I change it to a privileged container, then the chmod command works fine.

Previously I used to add these two lines to my container's conf file, but these don't seem to work anymore:
Code:
lxc.cgroup.devices.allow = c 10:200 rwm
lxc.hook.autodev = sh -c "modprobe tun; cd ${LXC_ROOTFS_MOUNT}/dev; mkdir net; mknod net/tun c 10 200; chmod 0666 net/tun"


If I update my conf file to include the following lines, the OpenVPN server works... But I cannot ssh into the container (Debian10 template):

Code:
unprivileged: 0
lxc.apparmor.profile: unconfined
lxc.mount.entry = /dev/net dev/net none bind,create=dir

I'm just wondering if anyone out there has successfully enabled tun on an unprivileged container. Using the Debian10 template seems to yield the same result. I've tried this on a PVE 5 and PVE 6 host.

Thank you so much.
 
Last edited:
The autodev hook isn't really usable with unprivileged containers. Neither the `modprobe` nor `mknod` will work.
The `lxc.mount.entry` line is correct, but you the permissions will have to be updated on the host side (since you're using device nodes from the host). So you either `chown` it to `100000:100000` or add ACLs:
Code:
# setfacl -m u:100000:rw -m g:100000:rw /dev/net/tun
After this, openvpn should be usable in an unprivileged container.
You can use an udev rule to automate this when the host boots, or:
A somewhat "cleaner" solution more separated from the host is to create a separate container-dev directory dedicated to pass devices to unprivileged containers, which you use for the `lxc.mount.entry` line instead of `/dev`, where you can give them the right ownership (`100000:100000`) without affecting the host `/dev` entries, and where you can in theory just have the files stay there persistently instead of using a tmpfs, so you don't need to worry about creating them on boot (though filling a tmpfs on boot is way less annoying to do than writing udev rules, so... ;-) )

As a side node, `/dev/net/tun` is something we will likely add a feature flag for (like we have for fuse) in the future.
 
  • Like
Reactions: rkk2025
Hi Wolfgang,

Thank you so much for your thoughtful reply. I had to spend some time researching the items you referred to.

It looks like I have a couple options. Let me see if I have understood you correctly.

I could set the permissions using the classic `chown` way or by adding the appropriate ACLs to `/dev/net/tun`. But both types of permissions would be reset upon reboot of the host (since /dev is recreated at boot time).

So to automatically have the system set the proper permissions at boot time, I could write a udev rule. (Or I suppose I could add a `/bin/chown 100000:100000 /dev/net/tun` in the crontab?)

But you're suggesting that rather than set the permissions on the host's /dev and simultaneously achieve more separation between host and container(s), I could create the `tun` device in a new location like `/devcontainer` on the host. Since /devcontainer would not be recreated upon host boot, the permissions would be persistent and I wouldn't need to write the udev rule.

If I wanted to go with the latter solution, would it be a simple matter of just this?
Code:
mkdir -p /devcontainer/net
mknod /devcontainer/net/tun c 10 200
chown 100000:100000 /devcontainer/net/tun

Thank you again!
 
Last edited:
That should do (unless for some reason your / is mounted with the `nodev` option).
You also have to adapt the `lxc.mount.entry` lines to bind this new file instead.
lxc.mount.entry = /devcontainer/net/tun dev/net/tun none bind,create=dir
 
  • Like
Reactions: johnha
Hi Wolfgang, I just wanted to followup with you and say that I've got OpenVPN server working just fine in an unprivileged LXC container (Debian 10 template) after incorporating your guidance. Thank you so very much for your help :)
 
  • Like
Reactions: Stoiko Ivanov
Hello guys,

i have followed the "devcontainer" way and sorted out the permission, i can see my "softether" created TAP interface in the container. but it doesnt solve my previous problem as in my previous post:
https://forum.proxmox.com/threads/s...tainer-not-passing-to-host.54346/#post-276242

the problem is, im not seeing the TAP interface on my proxmox host, and the TAP interface doesnt seem bridging to any other interface. can you please help?
 
That should do (unless for some reason your / is mounted with the `nodev` option).
You also have to adapt the `lxc.mount.entry` lines to bind this new file instead.
lxc.mount.entry = /devcontainer/net/tun dev/net/tun none bind,create=dir
I"m having this same issue trying to get OpenVPN to work on Ubunbu and CentOS LXC containers.

I ran the following on the host
Code:
mkdir -p /devcontainer/net
mknod /devcontainer/net/tun c 10 200
chown 100000:100000 /devcontainer/net/tun

Then updated /etc/pve/lxc/102.conf with
Code:
lxc.mount.entry = /devcontainer/net/tun dev/net/tun none bind,create=dir

When I try to restart the container it it fails. This is the same behavior for both the Ubunbu and CentOS containers. If I delete the
Code:
lxc.mount.entry = /devcontainer/net/tun dev/net/tun none bind,create=dir
it the containers start fine.
 
I"m having this same issue trying to get OpenVPN to work on Ubunbu and CentOS LXC containers.

I ran the following on the host
Code:
mkdir -p /devcontainer/net
mknod /devcontainer/net/tun c 10 200
chown 100000:100000 /devcontainer/net/tun

Then updated /etc/pve/lxc/102.conf with
Code:
lxc.mount.entry = /devcontainer/net/tun dev/net/tun none bind,create=dir

When I try to restart the container it it fails. This is the same behavior for both the Ubunbu and CentOS containers. If I delete the
Code:
lxc.mount.entry = /devcontainer/net/tun dev/net/tun none bind,create=dir
it the containers start fine.


try like: lxc.mount.entry: /dev/net dev/net none bind,create=dir
 
try like: lxc.mount.entry: /dev/net dev/net none bind,create=dir
Thanks for the quick reply. When I use that line the container starts fine but it doesn't resolve the "Cannot open TUN/TAP dev /dev/net/tun: error." This is what I'm getting when I try to start OpenVPN in the docker container. This in a Ubuntu 18.04.4 LXC and CentOS 7 LXC identically.

Code:
Using OpenVPN provider: PIA
Starting OpenVPN using config US West.ovpn
Setting OPENVPN credentials...
adding route to local network 192.168.1.0/24 via 172.17.0.1 dev eth0
Wed Jul 15 13:33:27 2020 OpenVPN 2.4.7 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Sep  5 2019
Wed Jul 15 13:33:27 2020 library versions: OpenSSL 1.1.1c  28 May 2019, LZO 2.10
Wed Jul 15 13:33:27 2020 NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
Wed Jul 15 13:33:27 2020 TCP/UDP: Preserving recently used remote address: [AF_INET]xxx.xxx.xx.xxx:1198
Wed Jul 15 13:33:27 2020 UDP link local: (not bound)
Wed Jul 15 13:33:27 2020 UDP link remote: [AF_INET]xxx.xxx.xxx.xxx:1198
Wed Jul 15 13:33:27 2020 WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
Wed Jul 15 13:33:28 2020 [11b9e54dc6eaeece62a2e146f9e1a74b] Peer Connection Initiated with [AF_INET]xxx,xxx,xx,xxx:1198
Wed Jul 15 13:33:29 2020 ERROR: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2)
Wed Jul 15 13:33:29 2020 Exiting due to fatal error
 
Last edited:
oh my bad, i guess since you ran mknod on /devcontainer/net/tun you need to pass that instead.

so it should be lxc.mount.entry: /devcontainer/net dev/net none bind,create=dir
 
oh my bad, i guess since you ran mknod on /devcontainer/net/tun you need to pass that instead.

so it should be lxc.mount.entry: /devcontainer/net dev/net none bind,create=dir

Container wont start with that line in /etc/pve/lxc/102.conf Here is the whole file:
Code:
#lxc.mount.entry%3A /dev/net/tun dev/net/tun none bind,create=dir
#lxc.mount.entry%3A /dev/net dev/net none bind,create=dir
arch: amd64
cores: 1
hostname: openvpn
memory: 1024
net0: name=Plex,bridge=vmbr0,firewall=1,hwaddr=BA:32:05:27:7C:89,ip=dhcp,type=v$
ostype: ubuntu
rootfs: local-zfs:subvol-102-disk-0,size=16G
swap: 512
unprivileged: 1
lxc.mount.entry: /storage/data storage none bind,create=dir, optional 0 0
lxc.apparmor.raw: mount,
lxc.mount.entry: /devcontainer/net dev/net none bind,create=dir

Starting In debug mode
Code:
lxc-start -n 102 -F -l DEBUG -o /tmp/lxc-102.log
I'm seeing this:
Code:
lxc-start 102 20200715143755.406 ERROR    conf - conf.c:mount_entry:1855 - No such file or directory - Failed to mount "/devcontainer/net" on "/usr/lib/x86_64-linux-gnu$
lxc-start 102 20200715143755.406 ERROR    conf - conf.c:lxc_setup:3329 - Failed to setup mount entries
lxc-start 102 20200715143755.406 ERROR    start - start.c:do_start:1231 - Failed to setup container "102"
lxc-start 102 20200715143755.406 ERROR    sync - sync.c:__sync_wait:41 - An error occurred in another process (expected sequence number 5)
lxc-start 102 20200715143755.406 DEBUG    network - network.c:lxc_delete_network:3693 - Deleted network devices
lxc-start 102 20200715143755.406 ERROR    start - start.c:__lxc_start:1957 - Failed to spawn container "102"

The file is there though on the host:
Code:
root@pharpe:/devcontainer/net# ls -al
total 2
drwxr-xr-x 2 root   root         3 Jul 14 22:02 .
drwxr-xr-x 3 root   root         3 Jul 14 22:02 ..
crw-r--r-- 1 100000 100000 10, 200 Jul 14 22:02 tun
 
Last edited:
I think I narrowed it down to a docker issue. I tried installing openvpn directly in the LXC rather in the Docker container and it's working.
 
great, i was wondering why it didn't work for you since i have a couple of containers with this same configuration.

glad your problem is solved!
 

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!