Most guides present the choice as cosmetic: either let NetworkManager bring the tunnel up, or enable a systemd instance and be done. The two paths differ in one thing that decides the outcome on a headless box, and it has nothing to do with which tool is newer. NetworkManager unlocks secrets through a session; a systemd instance has no session to unlock. Pick the one whose secret handling matches the machine in front of you.

Everything else, from route installation to reconnect behaviour, follows from that first decision.

A keyring is the difference nobody mentions

When NetworkManager owns a VPN profile, the password can live in the login keyring, which is unlocked when a user signs in. That works well on a laptop: the person is present, the keyring opens, the tunnel comes up. On a server that boots unattended there is nobody to unlock anything, so the profile waits for a secret that never arrives. The connection looks configured and never activates.

The systemd instance avoids that problem by reading a credential file from disk, which makes the file the thing you protect. chmod 400 plus ownership by root is the minimum, and the file should stay out of backups and image templates you do not control.

Attaching the VPN to a connection is not a boot guarantee

In nm-connection-editor, select the wired or wireless connection rather than the VPN, open the General tab, tick the option to connect to a VPN automatically and name the profile. NetworkManager then activates the VPN as a secondary connection when the primary one reaches a connected state. That is a dependency, not a firewall rule. Packets can still leave during the seconds before the tunnel is up, and a stored secret that fails to unlock leaves the machine online without it.

If the requirement is that nothing leaves without the tunnel, say so and build a kill switch, because this setting will not provide one. Test suspend and resume as well, since the secondary connection is re-evaluated on the way back up.

The systemd instance needs a file name that matches

Drop the profile in the client directory the package expects, such as /etc/openvpn/client/office.conf, and reference the credential file from inside it with auth-user-pass office.cred. The instance name is the file name without the suffix, so openvpn-client@office reads office.conf. Enable it with sudo systemctl enable --now openvpn-client@office and confirm the mapping with systemctl cat openvpn-client@office instead of trusting an example from a blog.

Paths inside the profile resolve relative to the unit's working directory, not to the profile itself, so a relative ca or auth-user-pass line can fail at boot while working when you test it by hand. Use absolute paths for anything the unit must find. Then read journalctl -u openvpn-client@office -b after a real boot; a unit that reports active with no tunnel usually names a missing file in that log.

Older packages ship a different template name, so systemctl list-unit-files 'openvpn*' settles which one exists on this host.

Reconnect behaviour is a separate decision

A profile with ping-restart rebuilds the tunnel after it drops, and a unit with a restart directive does something similar at the service level. Those are policies you choose, not defaults you inherit. If the connection should only come up on demand, remove the restart behaviour deliberately and write down why. If the unit starts before the network is usable, it needs a retry policy, because one failed attempt at boot does not repeat by itself.

Stopping is equally literal: sudo systemctl disable --now openvpn-client@office stops the running instance and removes the boot link. Disabling alone leaves the tunnel running until the next reboot, which surprises anyone who tests by disabling and watching the interface stay up.

Reboot, then check four things in order

Restarting the service tests the service; rebooting tests the boot path. After the reboot, confirm the unit came up, then that a route exists for the remote subnet, then which address the machine presents to the internet, and finally that names resolve through the tunnel. Those four checks fail in that order when something is wrong, which makes the first failure the useful one.

A unit that is active with no route usually means the profile connected but the server pushed no route, or the route was installed on an interface that later disappeared. A route with no working name lookup points at DNS configuration rather than at the tunnel itself.

Decide in advance what should happen when the tunnel cannot come up. Falling back to plain connectivity is a policy, and it should be written down rather than left to whichever manager started first.

Artaigilean co-cheangailte