2

I'm trying to run openvpn server within podman unprivileged container.

Openvpn needs to be able to manage network interfaces (i.e. create tun interface, assign IP address to it, bring it up). On my system (arch linux) within openvpn-server.service I noticed CapabilityBoundingSet and this made me to experiment and create my own service which instead of running openvpn will run podman run.

First I created my openvpn container, below is Dockerfile (I used archlinux as base for convenience):

FROM archlinux
RUN pacman -Sy --noconfirm openvpn

I then build this container (being logged in as my_unprivileged_user)

podman build \
--force-rm \
--no-cache \
--rm \
--device=/dev/net/tun \
-t openvpn .

Then I created my_custom_openvpn.service:

Description=OpenVPN in Podman container
After=syslog.target network-online.target
Wants=network-online.target

[Service]
User=my_unprivileged_user
Group=my_unprivileged_group
WorkingDirectory=/etc/openvpn
ExecStart=/usr/bin/podman run --rm --name openvpn -v ./server:/server --device /dev/net/tun --network "host" --cap-add CAP_IPC_LOCK,CAP_NET_ADMIN,CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_SETGID,CAP_SETUID,CAP_SYS_CHROOT,CAP_DAC_OVERRIDE,CAP_AUDIT_WRITE localhost/openvpn:latest /usr/bin/openvpn --config /server/my_config.conf
ExecStop=/usr/bin/podman stop -t 0 openvpn
Capabilities=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE CAP_AUDIT_WRITE
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw
#ProtectSystem=true
#ProtectHome=true
RestartSec=5s
Restart=on-failure
TimeoutSec=5s

[Install]
WantedBy=multi-user.target

So I thought systemd will pass capabilities to podman, which in turn will pass them further down to openvpn.

But openvpn fails to start complaining it cannot create tun0 interface. Even if I create tun0 myself like this openvpn --mktun --dev tun0 I get another error that openvpn cannot set this tun0 interface up.

I thought maybe I need to do setcap within the container, so I have podman exec into it and executed below:

setcap CAP_IPC_LOCK,CAP_NET_ADMIN,CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_SETGID,CAP_SETUID,CAP_SYS_CHROOT,CAP_DAC_OVERRIDE,CAP_AUDIT_WRITE=+ep /usr/bin/openvpn

But this did not help. I keep getting this error:

Tue Jan 28 13:34:31 2020 /usr/bin/ip link set dev tun0 up mtu 1500
RTNETLINK answers: Operation not permitted

Maybe trying to use capabilities like this does not make sense?

1 Answer 1

1

I managed to get openvpn working by replacing ip within the container with bash script that always returns 0. I figured the only thing that openvpn tries to do is to set up tun0 and then assign it the ip address and bring it up. I decided to do this manually from the outside of container (as root) and so openvpn does not have to do that. I described the procedure on openvpn wiki here

1
  • This approach does not work anymore since recent builds of OpenCV do not use external ip command.
    – Greg0ry
    Dec 8, 2021 at 23:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .