3

I have this post-up script that is run by openvpn:

#!/bin/bash
echo "I am: `whoami`"
echo "Moving interface into the netns"
ip link set dev "$1" up netns hydrogenvpn mtu "$2"
echo "Listing"
ip netns ls
echo "test"
ip netns exec hydrogenvpn cat /tmp/foobar

If I run openvpn with any of these commands: service openvpn start, /etc/init.d/openvpn start, systemctl start openvpn@hydrogen.service, I get this in my logs:

Sun Oct  9 11:19:15 2016 us=851109 /sbin/ip link set dev tun-hyd2 up mtu 1500
Sun Oct  9 11:19:15 2016 us=858267 /sbin/ip addr add dev tun-hyd2 10.43.43.3/24 broadcast 10.43.43.255
Sun Oct  9 11:19:15 2016 us=872474 /etc/openvpn/hydrogen_postup.sh tun-hyd2 1500 1542 10.43.43.3 255.255.255.0 init
I am: root
Moving interface into the netns
Listing
novpn (id: 1)
hydrogenvpn (id: 0)
test
setting the network namespace "hydrogenvpn" failed: Operation not permitted

However, if I run openvpn with the exact same command as systemd uses, it works:

# systemctl status openvpn@hydrogen.service | grep Process
  Process: 7722 ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --config /etc/openvpn/%i.conf --writepid /run/openvpn/%i.pid (code=exited, status=0/SUCCESS)
# /usr/sbin/openvpn --daemon ovpn-hydrogen --status /run/openvpn/hydrogen.status 10 --cd /etc/openvpn --config /etc/openvpn/hydrogen.conf --writepid /run/openvpn/hydrogen.pid
# tail /var/log/openvpn.log
Sun Oct  9 11:25:28 2016 us=762617 /sbin/ip addr add dev tun-hyd2 10.43.43.3/24 broadcast 10.43.43.255
Sun Oct  9 11:25:28 2016 us=767131 /etc/openvpn/hydrogen_postup.sh tun-hyd2 1500 1542 10.43.43.3 255.255.255.0 init
I am: root
Moving interface into the netns
Listing
novpn (id: 1)
hydrogenvpn (id: 0)
test
<content of /tmp/foobar>
Sun Oct  9 11:25:28 2016 us=952737 Initialization Sequence Completed

I also tried starting openvpn with systemd and then run the script manually, it works too.

Why is there a difference between the two runs? And how can I make the script work when run by openvpn started with systemd?

Versions: Debian testing, openvpn 2.3.11-2, systemd 231-9

Valentin Lorentz
  • 197
  • 2
  • 14

1 Answers1

5

This is the service file for OpenVPN (/lib/systemd/system/openvpn@.service):

[Unit]
Description=OpenVPN connection to %i
PartOf=openvpn.service
ReloadPropagatedFrom=openvpn.service
Before=systemd-user-sessions.service
Documentation=man:openvpn(8)
Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
Documentation=https://community.openvpn.net/openvpn/wiki/HOWTO

[Service]
PrivateTmp=true
KillMode=mixed
Type=forking
ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --config /etc/openvpn/%i.conf --writepid /run/openvpn/%i.pid
PIDFile=/run/openvpn/%i.pid
ExecReload=/bin/kill -HUP $MAINPID
WorkingDirectory=/etc/openvpn
ProtectSystem=yes
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH CAP_AUDIT_WRITE
LimitNPROC=10
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw

[Install]
WantedBy=multi-user.target

There are three things which limit what can be done:

  • CapabilityBoundingSet limits the things that this unit can do. There ar probably some apabilities needed by "ip netns" which is not in there. For example ip netns does a bind mount --bind which requires CAP_SYS_ADMIN.

  • ProtectSystem prevents the unit to modify the file system (I don't think it prevents the bind mount);

  • LimitNPROC limit the number of processes in the unit. It's probably the source of your problem but it could be a problem for complex scripts.

ysdx
  • 1,653
  • 12
  • 13
  • My service file (`/lib/systemd/system/openvpn.service`) has none of these limitations. However, using strace on `/sbin/ip`, I noticed this just before it reports the error: `open("/var/run/netns/hydrogenvpn", O_RDONLY|O_CLOEXEC) = 5` `setns(5, CLONE_NEWNET) = -1 EPERM (Operation not permitted)`, so it could that `CapabilityBoundingSet` has a default value that excludes `CAP_SYS_ADMIN` – Valentin Lorentz Oct 09 '16 at 14:25
  • I added your `CapabilityBoundingSet` line to my service file, with `CAP_SYS_ADMIN` at the end; no change. – Valentin Lorentz Oct 09 '16 at 14:34
  • @ValentinLorentz, look at openvpn@.service. Adding `CapabilityBoundingSet` probably won't help. Removing it might. – ysdx Oct 09 '16 at 20:47
  • I commented out the three lines you mentionned, no change. – Valentin Lorentz Oct 09 '16 at 21:51
  • 1
    Nevermind, I forgot `systemctl daemon-reload`. The problem was indeed caused by `CAP_SYS_ADMIN` missing from `CapabilityBoundingSet`. Thanks for your help! – Valentin Lorentz Oct 09 '16 at 22:01