You inherit a cron job that restarts OpenVPN at 04:10 every day, and it has been keeping things stable for a year. It has also been disconnecting a healthy tunnel at a fixed hour and doing nothing for the outage that actually happens at lunch. A calendar restart is a maintenance decision. Recovery is a different design with a specific trigger.

Three failure shapes need three different owners. Pick the failure first, and the mechanism follows.

Three failures, three owners

A tunnel can be up while its peer is gone: the process runs, the interface exists, and nothing useful crosses it. A process can be dead while the peer is fine, in which case only whatever started it can bring it back. An application behind the tunnel can be broken while both the tunnel and the peer are healthy, and restarting the client then widens the outage without touching the cause. Separating those three cases is the whole decision.

Each has its own signal and its own owner. Liveness belongs to the VPN protocol, process lifecycle belongs to the service manager, and application health belongs to monitoring with a narrow mandate.

What a liveness option can and cannot do

keepalive is a helper that expands into a ping and a ping-restart pair, as the link-option reference describes, and the timeouts it produces are not identical on the server and the client. Values pushed by a server can also override what a client configured locally, which is why a timeout that looks right in a local file may not be the one in force.

That makes it the right tool for a lost peer and the wrong tool for a dead process, since an exited process cannot run its own timers. It also says nothing about whether an application behind the tunnel answers, because the exchange happens between the two VPN endpoints. Copying a timeout pair from another deployment without checking role, expected interruptions and reauthentication behaviour is how a stable tunnel starts flapping.

What the service manager owns

If the daemon exits, the manager that started it decides what happens next. A restart policy keyed to failure, with a delay and a start-rate limit, handles a crash loop without turning it into a fork bomb. Those settings respond to process outcomes and timeouts, and they do not detect a process that is alive but useless. That is not a gap to patch with a broader policy; it is the boundary between lifecycle and liveness.

Ownership matters as much as the settings. A connection started by a desktop network manager should keep that manager's recovery arrangement, and adding a competing service unit for the same interface gives one tunnel two owners. Pick one and write down which one it is.

When a scheduled restart is legitimate

A timed restart can be a reasonable maintenance action: it has an owner, a window, a named instance and an independent way in. What it cannot be is a general reliability policy that also disconnects everyone at a fixed hour.

If the restart exists to work around a known leak or a stuck state, say so in the unit's description, because otherwise the next person keeps it forever.

Test the cases that matter: the peer vanishes while the process stays up, the process exits, a retry needs fresh credentials, and the tunnel returns while the application stays broken. Watch which component reacts and what state it leaves behind.

The right question is not how often to restart, but what should notice the failure first.

Zvinyorwa zvakafanana