Skip to content

Instantly share code, notes, and snippets.

@Strykar
Forked from Apsu/failover.sh
Last active November 3, 2022 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Strykar/fce98ce7fcf0e3cc02dbc8db53ab513c to your computer and use it in GitHub Desktop.
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
#!/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
@revoltown
Copy link

it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment