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
- How to debug Systemd problems
- Running Services After the Network is up
- Resume hook for systemd to restart VPN
- Auto-restart a crashed service in systemd
- Running scripts before and after suspend with systemd
- Solution to reconnecting ProtonVPN after suspend/sleep on Ubuntu
- Arch Wiki: Power Management
- systemd service automatic restart after StartLimitInterval