2

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

2
  • Does this network namespace already exist before you started openvpn, or did you create it in a post-up script? – Michael Hampton Oct 9 '16 at 10:21
  • It already exists. – Valentin Lorentz Oct 9 '16 at 14:34
4

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.

5
  • 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 9 '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 9 '16 at 14:34
  • @ValentinLorentz, look at openvpn@.service. Adding CapabilityBoundingSet probably won't help. Removing it might. – ysdx Oct 9 '16 at 20:47
  • I commented out the three lines you mentionned, no change. – Valentin Lorentz Oct 9 '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 9 '16 at 22:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.