WireGuard SysV Init Script

Most Linux distributions these days use systemd for their init process; and the WireGuard package for those distros will include a WireGuard systemd service definition that you can use to start up a WireGuard interface on system boot. However, there are still many older (or trimmed-down) Linux systems that use traditional SysV-style init scripts to start up the system and manage processes. This article will show you how to set up a SysV init script that you can use on those systems to start up WireGuard automatically on system boot.

With Systemd Init

If you are using systemd, and have a WireGuard interface defined at /etc/wireguard/wg0.conf, you can use systemd’s systemctl utility to start and stop the interface, as well as enable it to start up on system boot:

$ sudo -s
# cat <<EOF >/etc/wireguard/wg0.conf
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1/32
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
AllowedIPs = 10.0.0.2/32
EOF
# systemctl start wg-quick@wg0.service
# journalctl -u wg-quick@wg0.service
-- Logs begin at Thu Jun 10 01:02:03 UTC 2021, end at Thu Jun 10 01:02:04 UTC 2021 UTC. --
Jun 10 01:02:03 systemd[1]: Starting WireGuard via wg-quick(8) for wg0...
Jun 10 01:02:03 wg-quick[271288]: [#] ip link add wg0 type wireguard
Jun 10 01:02:03 wg-quick[271288]: [#] wg setconf wg0 /dev/fd/63
Jun 10 01:02:03 wg-quick[271288]: [#] ip -4 route add 10.0.0.1/32 dev wg0
Jun 10 01:02:03 wg-quick[271288]: [#] ip link set mtu 1420 up dev wg0
Jun 10 01:02:03 wg-quick[271288]: [#] ip -4 address add 10.0.0.2/32 dev wg0
Jun 10 01:02:04 systemd[1]: Finished WireGuard via wg-quick(8) for wg0.
# systemctl stop wg-quick@wg0.service
# systemctl enable wg-quick@wg0.service
Created symlink /etc/systemd/system/multi-user.target.wants/wg-quick@wg0.service → /lib/systemd/system/wg-quick@.service.

With SysV Init

But if you aren’t using systemd, you can do the same thing with a simple SysV init script, like the following:

#!/bin/sh -eu
# checkconfig: 2345 30 70
# description: set up a WireGuard interface simply
### BEGIN INIT INFO
# Provides: wg-quick
# Required-Start: $local-fs $network
# Required-Stop: $local-fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: set up a WireGuard interface simply
### END INIT INFO

command=/usr/bin/wg-quick
interface=wg0
description="wg-quick on $interface"
logfile=/var/log/$interface

status() {
    /usr/bin/wg show $interface
}

start() {
    touch $logfile && date >>$logfile
    echo "starting $description ..." | tee -a $logfile
    $command up $interface >>$logfile 2>&1
    echo "... started $description" | tee -a $logfile
}

stop() {
    touch $logfile && date >>$logfile
    echo "stopping $description ..." | tee -a $logfile
    $command down $interface >>$logfile 2>&1
    echo "... stopped $description" | tee -a $logfile
}

case "${1-}" in
    status) status ;;
    start) start ;;
    restart) stop || true; start ;;
    stop) stop ;;
    *) echo "usage: $0 {status|start|restart|stop}" ;;
esac

Save the above script as /etc/init.d/wg0. Make it executable, and link it to the appropriate runlevels, like the following:

# chmod 755 /etc/init.d/wg0
# ln -s /etc/init.d/wg0 /etc/rc0.d/K70wg0
# ln -s /etc/init.d/wg0 /etc/rc1.d/K70wg0
# ln -s /etc/init.d/wg0 /etc/rc2.d/S30wg0
# ln -s /etc/init.d/wg0 /etc/rc3.d/S30wg0
# ln -s /etc/init.d/wg0 /etc/rc4.d/S30wg0
# ln -s /etc/init.d/wg0 /etc/rc5.d/S30wg0
# ln -s /etc/init.d/wg0 /etc/rc6.d/K70wg0

Now if you boot into a networked console (runlevel 3) or GUI (runlevel 5), the system’s init process will automatically start up your wg0 WireGuard interface. And if you halt (runlevel 0) or reboot (runlevel 6), the system will shut down your interface cleanly (running any PreDown or PostDown scripts you have configured in /etc/wireguard/wg0.conf).

Debian-based distros will include an update-rc.d utility to help with linking to runlevels; and Fedora-related distros include a chkconfig utility with similar functionality. Many distros also include a service utility to start and stop services. Additionally, you can start or stop the wg0 service directly through the init script, like the following:

# /etc/init.d/wg0 start
starting wg-quick on wg0 ...
... started wg-quick on wg0
# cat /var/log/wg0
Thu Jun 10 01:02:03 UTC 2021
starting wg-quick on wg0 ...
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 route add 10.0.0.1/32 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] ip -4 address add 10.0.0.2/32 dev wg0
... started wg-quick on wg0
# /etc/init.d/wg0 stop
stopping wg-quick on wg0 ...
... stopped wg-quick on wg0