OpenVPN in unprivileged container

marianh

New Member
Sep 11, 2017
5
0
1
45
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)
 

marianh

New Member
Sep 11, 2017
5
0
1
45
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?
 

bofh

Member
Nov 7, 2017
53
7
8
39
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
 

zuliasro

New Member
Dec 25, 2017
1
0
1
68
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
 

Bill McGonigle

New Member
Sep 13, 2018
1
2
1
46
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

johnha

New Member
Jan 1, 2018
7
1
3
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:

wbumiller

Proxmox Staff Member
Staff member
Jun 23, 2015
645
84
28
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

johnha

New Member
Jan 1, 2018
7
1
3
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:

wbumiller

Proxmox Staff Member
Staff member
Jun 23, 2015
645
84
28
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

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE 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 your own in 60 seconds.

Buy now!