A better version with a stolen online check, simplified function for adding the route to the wireguard server and loading the wireguard module:
#!/bin/sh # Copyright (c) 2021 Karol Babioch <karol@babioch.de> # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # LSBInitScript for Wireguard: This is a leightweight init script for # Wireguard. While Wireguard itself requires only minimal overhead to setup and # start, it still requires some script invocations (e.g. during boot). # # Most distributions are using systemd by now, and as such can use # wg-quick@.service. However some distributions / images / Linux appliances # are not (yet) using systemd. In such cases, this init script could be used # to (re)start and/or stop Wireguard. # # It can handle all configured Wireguard interfaces (within /etc/wireguard) # globally and/or individual interfaces, e.g. (/etc/init.d/wireguard start wg0). # # It relies on wg(8) and wg-quick(8) in the background. ### BEGIN INIT INFO # Provides: wireguard # Required-Start: $network $syslog # Required-Stop: $network $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Starts Wireguard interfaces # Description: Sets up Wireguard interfaces (by means of wg-quick). ### END INIT INFO CONFIG_DIR=/etc/wireguard modprobe wireguard check_online() { count=0 while [ $count -lt 5 ] do sleep 0.5 if ping -4 -c 1 www.google.com >/dev/null 2>&1 || ping -6 -c 1 www.google.com >/dev/null 2>&1 then break fi count=$((count+1)) done } function get_active_wg_interfaces() { INTERFACES=$(wg | grep "interface:" | sed 's/interface: /\1/') echo "$INTERFACES" } function default_gw_for_endpoints() { ACTION="$1" GATEWAY="$(ip r | grep default | cut -d ' ' -f3)" if [ ! "${GATEWAY}" == "" ] then wg | sed -n -e '/\(0.0.0.0\/1, 128.0.0.0\/1\|128.0.0.0\/1, 0.0.0.0\/1\)/{x;p;d;}; x' | sed -e 's/^[ \t]*//' | cut -d' ' -f2 | cut -d':' -f1 | while read line do echo "${ACTION} default gateway: ${GATEWAY} for endpoint ${line}" ip route ${ACTION} ${line} via ${GATEWAY} done else echo "Could not determine default gateway on this system!" fi } # This is required for wg-quick(1) to work correctly, i.e. for process # substitution (`<()`) to work in Bash. If missing, wg-quick will fail with a # "fopen: No such file or directory" error. [ -e /dev/fd ] || ln -sf /proc/self/fd /dev/fd case "$1" in start) check_online if [ -z "$2" ]; then echo "Starting all configured Wireguard interfaces" for CONFIG in $(cd $CONFIG_DIR; ls *.conf); do wg-quick up ${CONFIG%%.conf} done else echo "Starting Wireguard interface: $2" wg-quick up "$2" fi default_gw_for_endpoints add ;; stop) default_gw_for_endpoints del if [ -z "$2" ]; then echo "Stopping all active Wireguard interfaces" INTERFACES=$(get_active_wg_interfaces) for INTERFACE in $INTERFACES; do wg-quick down "$INTERFACE" done else echo "Stopping Wireguard interface: $2" wg-quick down "$2" fi ;; reload|force-reload) default_gw_for_endpoints del check_online if [ -z "$2" ]; then echo "Reloading configuration for all active Wireguard interfaces" INTERFACES=$(get_active_wg_interfaces) for INTERFACE in $INTERFACES; do wg syncconf "$INTERFACE" <(wg-quick strip "$INTERFACE") done else echo "Reloading configuration for Wireguard interface: $2" wg syncconf "$2" <(wg-quick strip "$2") fi default_gw_for_endpoints add ;; restart) $0 stop "$2" sleep 1 $0 start "$2" ;; status) # TODO Check exit codes and align them with LSB requirements if [ -z "$2" ]; then INTERFACES=$(get_active_wg_interfaces) for INTERFACE in $INTERFACES; do wg show $INTERFACE done else wg show "$2" fi ;; *) echo "Usage: $0 { start | stop | restart | reload | force-reload | status } [INTERFACE]" exit 1 ;; esac