Mastodon hachyterm.io

I’m running a VPN service via systemd on my machine.

The service provides a systemd script for me. I can query the service with the standard commands, for example:

sudo systemctl status strongswan.service

This works fine, except when the computer went to sleep (suspend or hibernate).
My machine also stops the wi-fi connection on sleep. When I wake up the machine, the wi-fi connection automatically starts again.

My VPN service does not resume. The problem seems to be that strongswan.service tries to restart before the network is up.

Let’s write two scripts that manage how to send the service to suspend and how to resume.

I’m using an Arch-based Linux distro. These instructions might work for other distributions as well if they use systemd.

First, we need a suspend script (/etc/systemd/system/strongswan-suspend.service). The script will stop strongswan.service.

# /etc/systemd/system/strongswan-suspend.service
[Unit]
Description=Strongswan suspend actions
Before=sleep.target

[Service]
Type=simple
ExecStart=-/usr/bin/systemctl stop strongswan.service
ExecStartPost=/usr/bin/sleep 5

[Install]
WantedBy=sleep.target

The line ExecStartPost=/usr/bin/sleep 5 prevents a flash on resuming from suspend. This happens when a screen locker returns before the screen is “locked”.

Now, a resume hook (/etc/systemd/system/strongswan-resume.service):

# /etc/systemd/system/strongswan-suspend.service

[Unit]
Description=Strongswan resume action
Requires=network-online.target
After=network-online.target
Wants=network-online.target NetworkManager-wait-online.service
StartLimitInterval=300
StartLimitBurst=5

[Service]
Type=simple
ExecStart=/usr/bin/systemctl restart strongswan.service
Restart=on-failure
RestartSec=30

[Install]
WantedBy=suspend.target
WantedBy=hibernate.target
WantedBy=hybrid-sleep.target

In the [Unit] section, we set up some requirements to make sure that the network is online.

We also make sure that the service tries a restart for a certain interval. Even if the service rashes after wakeup, the machine will retry to start it.

The StartLimitIntervalSec and StartLimitBurst and RestartSec define how long and how often retries happen. If you don’t define these, systemd stops restarting your service if it fails to start more than 5 times within 10 seconds.

Finally, we need to enable these two services:

sudo systemctl enable strongswan-suspend.service
sudo systemctl enable strongswan-resume.service

I hope this blog post has helped you in setting up a service that restarts after sleep. It seems to be tricky to achieve when your service relies on the network.

Further Reading