-
-
Save Strykar/fce98ce7fcf0e3cc02dbc8db53ab513c to your computer and use it in GitHub Desktop.
An example failover script for dual WAN, using a ping healthcheck and managing default routes appropriately
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -x | |
set -euf -o pipefail | |
# Test if sudo exists, comment out if sudo isn't installed | |
command -v sudo >/dev/null 2>&1 || { printf 'I require to be run as root, or sudo to be installed. Aborting. \n' >&2; exit 1; } | |
# Setting gateway's needs root privileges, elevate with sudo, tested on kernel 5.8.5-arch1-1. | |
# Comment out if script is called as root | |
if [ "$EUID" != 0 ]; then | |
sudo "${BASH_SOURCE[0]}" "$@" | |
exit $? | |
fi | |
## Start user config | |
# Define network interfaces | |
wan0='enp2s0' # Primary WAN interface | |
wan1='enp0s29u1u2u1' # Backup WAN interface | |
# Grok gateway addresses, this assumes both gateway's defined above are up | |
wan0_gw=$( route -n | awk -v wan0="$wan0" '$4 == "UG" && $NF ~ wan0 { print $2 }' ) | |
wan1_gw=$( route -n | awk -v wan1="$wan1" '$4 == "UG" && $NF ~ wan1 { print $2 }' ) | |
# Set defaults if not provided by environment | |
CHECK_DELAY='5' # in seconds | |
CHECK_IP0='1.1.1.1' | |
CHECK_IP1='8.8.8.8' | |
PRIMARY_IF=$wan0 | |
PRIMARY_GW=$wan0_gw | |
BACKUP_IF=$wan1 | |
BACKUP_GW=$wan1_gw | |
## End user config | |
# Compare arg with current default gateway interface for route to healthcheck IP | |
gateway_if() { | |
[[ "$1" == "$(ip r g "$CHECK_IP1" | sed -rn 's/^.dev ([^ ]).*$/\1/p')" ]] | |
} | |
ip r d "$CHECK_IP0/32" | |
ip r a "$CHECK_IP0/32" via "$PRIMARY_GW" dev "$PRIMARY_IF" | |
# Cycle healthcheck continuously with specified delay | |
while sleep "$CHECK_DELAY" | |
do | |
# If healthcheck succeeds from primary interface | |
if ping -I "$PRIMARY_IF" -c1 "$CHECK_IP0" &>/dev/null | |
then | |
# Are we using the backup? | |
if gateway_if "$BACKUP_IF" | |
then # Switch to primary | |
ip r d default via "$BACKUP_GW" dev "$BACKUP_IF" | |
ip r a default via "$PRIMARY_GW" dev "$PRIMARY_IF" | |
fi | |
else | |
# Are we using the primary? | |
if gateway_if "$PRIMARY_IF" | |
then # Switch to backup | |
ip r d default via "$PRIMARY_GW" dev "$PRIMARY_IF" | |
ip r a default via "$BACKUP_GW" dev "$BACKUP_IF" | |
fi | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
it works.