Debian Systemd Openvpn – Not Sure What Starts This Systemd Unit File

debianopenvpnsystemd

So I've been looking at the openvpn configuration on my Debian 9 based server and found something that I cannot explain in the systemd unit files for the openvpn daemon. The daemon itself is starting and working without problems, but I can't figure out why… Let me explain 🙂

So I've got openvpn installed and have a proper configuration in the /etc/openvpn/server.conf file. Nothing wrong so far.

However, apparently two systemd units are running for openvpn, namely openvpn.service and openvpn@server.service. The latter seems to be the one that actually accepts the incomming vpn connections and such, the former one does't appear to do much at all. It apparently just runs to start the latter, I suppose…

Checking the /etc/systemd/system/multi-user.target.wants/ directory for openvpn related files shows only the openvpn.service file, which of source is a symlink to a similar named file in /lib/systemd/system. The contents of this file is:

# This service is actually a systemd target,
# but we are using a service since targets cannot be reloaded.

[Unit]
Description=OpenVPN service
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/true
ExecReload=/bin/true
WorkingDirectory=/etc/openvpn

[Install]
WantedBy=multi-user.target

Ok, cool. So this only runs /bin/true. Then what exactly starts the openvpn@server daemon? I know that the unit file for this is /lib/systemd/openvpn@.service but I cannot find any clue whatsoever on my system to what exactly runs this unit file. (I was expecting to find a symlink for this under /etc/systemd/system somwhere, but there isn't.) The content of this file is:

[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

So this unit file has a lot more substance than the openvpn.service file. But what kicks it off? I've noticed the PartOf=openvpn.service part in the above file, but looking up the meaning of this in the man pages hasn't made me much wiser.

I'll continue searching because I just want to know what makes this thing tick!

If any one you have any clue about how this specific unit file is run, or what starts it, please let me know 🙂

Best Answer

You need to know two things:

  • There are several more undocumented directories where systemd keeps unit files.
  • Debian and Ubuntu supply a generator in /lib/systemd/system-generators/openvpn-generator that puts "wants" symbolic links into one of those undocumented directories, one for every *.conf file in /etc/openvpn.

The symbolic links cause openvpn.service to behave like a target and "want" all of your various template instantiations; as the commentary at the start of the service unit explains.

Note that Debian and Ubuntu are not aligned with what the OpenVPN people themselves supply for systemd, which is what is used on Arch, CentOS, Fedora, and suchlike. Debian and Ubuntu entirely supplant what is supplied in OpenVPN itself for all this, with their own stuff for systemd. So at the very least beware when reading doco what operating system that doco is assuming you to have.

The OpenVPN people used to supply a openvpn@.service template unit but no generator nor openvpn.service target-as-a-service. One had to explicitly enable and disable openvpn@name onesself with the ordinary systemd mechanisms for doing so, and they were "wanted" directly by multi-user.target, rather than by an intermediary target-as-a-service.

The OpenVPN people nowadays supply distinct openvpn-service@.service and openvpn-client@.service templates, continue to not supply a generator or an openvpn.service target-as-a-service, and expect you to explicitly enable and disable openvpn-service@name and openvpn-client@name yourself with the ordinary systemd mechanisms for doing so. The *.conf files have moved out of /etc/openvpn and into /etc/openvpn/client and /etc/openvpn/server, too.

Further reading