-
-
Save Sn4kY/b741478b5c302fd221a8bc314921d7a2 to your computer and use it in GitHub Desktop.
A failover script for dual WAN with dual interfaces, using a ping healthcheck and managing default routes appropriately, with antiflap and back to normal state availability
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 | |
# Set defaults if not provided by environment | |
CHECK_DELAY=${CHECK_DELAY:-5} | |
CHECK_LOOPS_FAIL=${CHECK_LOOPS_FAIL:-3} | |
CHECK_LOOPS_REVERT=${CHECK_LOOPS_REVERT:-5} | |
CHECK_IP=${CHECK_IP:-8.8.8.8} | |
PRIMARY_IF=${PRIMARY_IF:-enp0s17} | |
PRIMARY_GW=${PRIMARY_GW:-192.168.1.252} | |
BACKUP_IF=${BACKUP_IF:-enp0s18} | |
BACKUP_GW=${BACKUP_GW:-192.168.100.1} | |
# Compare arg with current default gateway interface for route to healthcheck IP | |
gateway_if() { | |
[[ "$1" = "$(ip r g "$CHECK_IP" | sed -rn 's/^.*dev ([^ ]*).*$/\1/p')" ]] | |
} | |
ip route del ${CHECK_IP} via ${PRIMARY_GW} | |
LOOP_FAIL=0 | |
LOOP_REVERT=0 | |
# Cycle healthcheck continuously with specified delay | |
while sleep "$CHECK_DELAY" | |
do | |
# If healthcheck succeeds from primary interface | |
ip route add ${CHECK_IP} via ${PRIMARY_GW} | |
if ping -I "$PRIMARY_IF" -c1 "$CHECK_IP" &>/dev/null | |
then | |
ip route del ${CHECK_IP} via ${PRIMARY_GW} | |
# Are we using the backup? | |
if gateway_if "$BACKUP_IF" | |
then # anti-flap | |
LOOP_REVERT=$(( $LOOP_REVERT + 1 )) | |
if [[ $LOOP_REVERT -le $CHECK_LOOPS_REVERT ]] ; then echo $(date +'%Y-%m-%d %H:%M:%S') " : check successful ! (${LOOP_REVERT}/${CHECK_LOOPS_REVERT})" ; fi | |
if [[ $LOOP_REVERT -ge $CHECK_LOOPS_REVERT ]] | |
then # swith to primary | |
echo $(date +'%Y-%m-%d %H:%M:%S') " : reverting to primary after ${LOOP_REVERT} checks successful" | |
ip r d default via "$BACKUP_GW" dev "$BACKUP_IF" | |
ip r a default via "$PRIMARY_GW" dev "$PRIMARY_IF" | |
LOOP_FAIL=0 | |
fi | |
else LOOP_FAIL=0 | |
fi | |
else | |
ip route del ${CHECK_IP} via ${PRIMARY_GW} | |
LOOP_FAIL=$(( $LOOP_FAIL + 1 )) | |
if [[ $LOOP_FAIL -le $CHECK_LOOPS_FAIL ]] ; then echo $(date +'%Y-%m-%d %H:%M:%S') " : check ${LOOP_FAIL}/${CHECK_LOOPS_FAIL} failed" ; fi | |
if [[ $LOOP_FAIL -ge $CHECK_LOOPS_FAIL ]] | |
then | |
# Are we using the primary? | |
if gateway_if "$PRIMARY_IF" | |
then # Switch to backup | |
echo $(date +'%Y-%m-%d %H:%M:%S') " : switching to backup" | |
ip r d default via "$PRIMARY_GW" dev "$PRIMARY_IF" | |
ip r a default via "$BACKUP_GW" dev "$BACKUP_IF" | |
LOOP_REVERT=0 | |
else LOOP_REVERT=0 | |
fi | |
fi | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment