Router redundancy scripts
This commit is contained in:
parent
1cb97260ba
commit
7b0b2087b3
8 changed files with 356 additions and 0 deletions
66
routers/README
Normal file
66
routers/README
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
Redundant routers control
|
||||||
|
==========================
|
||||||
|
|
||||||
|
I'm using two Linux routers at home, along with a manageable switch and an ADSL
|
||||||
|
modem.
|
||||||
|
|
||||||
|
Both routers have their own address, and so does the switch. When one of the
|
||||||
|
routers is active, it uses an additional address which serves as the default
|
||||||
|
gateway for the rest of the boxes.
|
||||||
|
|
||||||
|
One of the routers is an old box; it's rather slow, doesn't have much memory,
|
||||||
|
and more importantly, it's dying. Obviously, it should only be used when the
|
||||||
|
other one is down. However, if the connection has been established by that
|
||||||
|
secondary router, the primary should not take over until the DSL link goes down
|
||||||
|
on its own.
|
||||||
|
|
||||||
|
The scripts in this directory are used to control which router is active.
|
||||||
|
|
||||||
|
|
||||||
|
Checks on the primary router
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
When the primary router is the active router:
|
||||||
|
|
||||||
|
1/ Check the switch
|
||||||
|
2/ If the switch is down, deactivate.
|
||||||
|
|
||||||
|
When the primary router is inactive:
|
||||||
|
|
||||||
|
1/ Check the switch and the main router address
|
||||||
|
2/ If the switch is up and the main router does not exist, activate.
|
||||||
|
|
||||||
|
|
||||||
|
Checks on the secondary router
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
When the secondary router is the active router:
|
||||||
|
|
||||||
|
1/ Check the switch, the primary router, and a remote server
|
||||||
|
2/ If the remote server is reachable, do nothing
|
||||||
|
3/ If the switch is down, or if the primary router is up, deactivate.
|
||||||
|
|
||||||
|
When the secondary router is inactive:
|
||||||
|
|
||||||
|
1/ Check the switch, the primary router, and the main router address
|
||||||
|
2/ If the switch is up, and both the primary router and the main router
|
||||||
|
address are down, activate.
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
1/ Copy router-checks.conf to /etc, modify it however you want.
|
||||||
|
|
||||||
|
2/ Copy share/ to /usr/local/share/router-checks (or to whatever you set the
|
||||||
|
LIB_DIR configuration variable to).
|
||||||
|
|
||||||
|
3/ Modify activate.sh and deactivate.sh; they determine how a router becomes
|
||||||
|
the primary router and how a router releases primary routing control,
|
||||||
|
respectively.
|
||||||
|
|
||||||
|
4/ Copy primary-router.sh or secondary-router.sh to
|
||||||
|
/usr/local/sbin/router-checks
|
||||||
|
|
||||||
|
5/ If necessary (and if it will work on whatever distribution you use), use
|
||||||
|
the provided init script to start the checks on boot.
|
67
routers/init-script
Normal file
67
routers/init-script
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: router-checks
|
||||||
|
# Required-Start: $local_fs networking
|
||||||
|
# Required-Stop: $local_fs networking
|
||||||
|
# Should-Start: iptables-persistent ip6tables-persistent
|
||||||
|
# Should-Stop: iptables-persistent ip6tables-persistent
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: Router control
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
. /lib/lsb/init-functions
|
||||||
|
. /etc/router-checks.conf
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
log_daemon_msg "Starting router control..." "router-checks"
|
||||||
|
if [ -f $PID_FILE ]; then
|
||||||
|
log_action_msg "PID file exists"
|
||||||
|
log_end_msg 1
|
||||||
|
fi
|
||||||
|
/usr/local/sbin/router-checks </dev/null >/dev/null 2>&1
|
||||||
|
sleep 1
|
||||||
|
if [ -f $PID_FILE ]; then
|
||||||
|
log_end_msg 0
|
||||||
|
else
|
||||||
|
log_end_msg 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
stop)
|
||||||
|
log_daemon_msg "Stopping router control..." "router-checks"
|
||||||
|
if ! [ -f $PID_FILE ]; then
|
||||||
|
log_action_msg "PID file not found"
|
||||||
|
log_end_msg 1
|
||||||
|
fi
|
||||||
|
rm -f $PID_FILE.`cat $PID_FILE`
|
||||||
|
sleep 2
|
||||||
|
if [ -f "$PID_FILE" ]; then
|
||||||
|
count=18
|
||||||
|
log_action_begin_msg " Waiting"
|
||||||
|
while [ $count -gt 0 ] && [ -f "$PID_FILE" ]; do
|
||||||
|
sleep 5
|
||||||
|
log_action_cont_msg ""
|
||||||
|
count=$(( count - 1 ))
|
||||||
|
done
|
||||||
|
if [ -f "$PID_FILE" ]; then
|
||||||
|
log_end_msg 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
log_end_msg 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
restart)
|
||||||
|
$0 stop
|
||||||
|
$0 start
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
63
routers/primary-router.sh
Normal file
63
routers/primary-router.sh
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#!/bin/bash
|
||||||
|
(
|
||||||
|
|
||||||
|
. /etc/router-checks.conf
|
||||||
|
|
||||||
|
exec >>$LOG_FILE 2>&1
|
||||||
|
date
|
||||||
|
echo "... STARTING"
|
||||||
|
. "$LIB_DIR/pings"
|
||||||
|
|
||||||
|
echo $$ > $PID_FILE
|
||||||
|
stop_file="$PID_FILE.$$"
|
||||||
|
trap "rm -f $stop_file" SIGINT SIGTERM
|
||||||
|
touch $stop_file
|
||||||
|
SLEEP_TIME=60
|
||||||
|
while [ -f "$stop_file" ]; do
|
||||||
|
sleep $SLEEP_TIME
|
||||||
|
SLEEP_TIME=1
|
||||||
|
|
||||||
|
pr_switch=`mktemp`
|
||||||
|
if [ -f "$ACTIVATION_FILE" ]; then
|
||||||
|
|
||||||
|
# When the primary router is active, disable it if the switch
|
||||||
|
# is off-line
|
||||||
|
|
||||||
|
wait_pings `try_ping $SWITCH_ADDR $pr_switch`
|
||||||
|
if [ -f "$pr_switch" ]; then
|
||||||
|
date
|
||||||
|
echo "de-activating connection"
|
||||||
|
$LIB_DIR/deactivate.sh
|
||||||
|
rm -f "$ACTIVATION_FILE"
|
||||||
|
SLEEP_TIME=10
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# When the primary router is inactive, enable it if the switch
|
||||||
|
# is up and the main router IP does not exist
|
||||||
|
|
||||||
|
pr_main=`mktemp`
|
||||||
|
wait_pings `try_ping $SWITCH_ADDR $pr_switch` \
|
||||||
|
`try_ping $MAIN_ADDR $pr_main`
|
||||||
|
if [ -f "$pr_main" ] && ! [ -f "$pr_switch" ]; then
|
||||||
|
date
|
||||||
|
echo "activating connection"
|
||||||
|
$LIB_DIR/activate.sh
|
||||||
|
touch "$ACTIVATION_FILE"
|
||||||
|
SLEEP_TIME=20
|
||||||
|
fi
|
||||||
|
rm -f "$pr_main"
|
||||||
|
|
||||||
|
fi
|
||||||
|
rm -f "$pr_switch"
|
||||||
|
done
|
||||||
|
if [ -f "$ACTIVATION_FILE" ]; then
|
||||||
|
$LIB_DIR/deactivate.sh
|
||||||
|
rm -f "$ACTIVATION_FILE"
|
||||||
|
fi
|
||||||
|
date
|
||||||
|
echo "... EXITING"
|
||||||
|
rm "$PID_FILE"
|
||||||
|
|
||||||
|
) &
|
25
routers/router-checks.conf
Normal file
25
routers/router-checks.conf
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# Router checks configuration
|
||||||
|
|
||||||
|
# Some remote address to ping
|
||||||
|
INTERNET_ADDR="173.194.34.1"
|
||||||
|
|
||||||
|
# Main router address
|
||||||
|
MAIN_ADDR="192.168.1.1"
|
||||||
|
|
||||||
|
# Primary router's own address
|
||||||
|
PRIMARY_ADDR="192.168.1.1"
|
||||||
|
|
||||||
|
# Address of the switch
|
||||||
|
SWITCH_ADDR="192.168.1.4"
|
||||||
|
|
||||||
|
# PID files
|
||||||
|
PID_FILE="/var/run/router-check"
|
||||||
|
|
||||||
|
# Activation file, used to keep track of state
|
||||||
|
ACTIVATION_FILE="/var/run/router-active"
|
||||||
|
|
||||||
|
# Library directory - where scripts reside
|
||||||
|
LIB_DIR="/usr/local/share/router-checks"
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
LOG_FILE="/var/log/router-checks.log"
|
73
routers/secondary-router.sh
Normal file
73
routers/secondary-router.sh
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#!/bin/bash
|
||||||
|
(
|
||||||
|
|
||||||
|
. /etc/router-checks.conf
|
||||||
|
|
||||||
|
exec >>$LOG_FILE 2>&1
|
||||||
|
date
|
||||||
|
echo "... STARTING"
|
||||||
|
. "$LIB_DIR/pings"
|
||||||
|
|
||||||
|
echo $$ > $PID_FILE
|
||||||
|
stop_file="$PID_FILE.$$"
|
||||||
|
trap "rm -f $stop_file" SIGINT SIGTERM
|
||||||
|
touch $stop_file
|
||||||
|
SLEEP_TIME=60
|
||||||
|
while [ -f "$stop_file" ]; do
|
||||||
|
sleep $SLEEP_TIME
|
||||||
|
SLEEP_TIME=1
|
||||||
|
|
||||||
|
pr_switch=`mktemp`
|
||||||
|
pr_peer=`mktemp`
|
||||||
|
if [ -f "$ACTIVATION_FILE" ]; then
|
||||||
|
|
||||||
|
# When the secondary router is active, disable it if the
|
||||||
|
# internet is not reachable and either the primary router is
|
||||||
|
# up or the switch is down
|
||||||
|
|
||||||
|
pr_internet=`mktemp`
|
||||||
|
wait_pings `try_ping $INTERNET_ADDR $pr_internet` \
|
||||||
|
`try_ping $PRIMARY_ADDR $pr_peer` \
|
||||||
|
`try_ping $SWITCH_ADDR $pr_switch`
|
||||||
|
if [ -f "$pr_internet" ]; then
|
||||||
|
if [ -f "$pr_switch" ] || ! [ -f "$pr_peer" ]; then
|
||||||
|
date
|
||||||
|
echo "de-activating connection"
|
||||||
|
$LIB_DIR/deactivate.sh
|
||||||
|
rm -f "$ACTIVATION_FILE"
|
||||||
|
SLEEP_TIME=10
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
rm -f "$pr_internet"
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# When the secondary router is inactive, enable it if the
|
||||||
|
# switch is up and both the primary router and the main address
|
||||||
|
# are unreachable
|
||||||
|
|
||||||
|
pr_main=`mktemp`
|
||||||
|
wait_pings `try_ping $SWITCH_ADDR $pr_switch` \
|
||||||
|
`try_ping $PRIMARY_ADDR $pr_peer` \
|
||||||
|
`try_ping $MAIN_ADDR $pr_main`
|
||||||
|
if [ -f "$pr_main" ] && [ -f "$pr_peer" ] && ! [ -f "$pr_switch" ]; then
|
||||||
|
date
|
||||||
|
echo "activating connection"
|
||||||
|
$LIB_DIR/activate.sh
|
||||||
|
touch "$ACTIVATION_FILE"
|
||||||
|
SLEEP_TIME=20
|
||||||
|
fi
|
||||||
|
rm -f "$pr_main"
|
||||||
|
|
||||||
|
fi
|
||||||
|
rm -f "$pr_peer" "$pr_switch"
|
||||||
|
done
|
||||||
|
if [ -f "$ACTIVATION_FILE" ]; then
|
||||||
|
$LIB_DIR/deactivate.sh
|
||||||
|
rm -f "$ACTIVATION_FILE"
|
||||||
|
fi
|
||||||
|
date
|
||||||
|
echo "... EXITING"
|
||||||
|
rm "$PID_FILE"
|
||||||
|
|
||||||
|
) &
|
15
routers/share/activate.sh
Normal file
15
routers/share/activate.sh
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# Example router activation script
|
||||||
|
#
|
||||||
|
# 1/ Remove default route through peer
|
||||||
|
# 2/ Take active router address
|
||||||
|
# 3/ Activate PPP link
|
||||||
|
# 4/ Wait for a few seconds
|
||||||
|
#
|
||||||
|
|
||||||
|
ip route del default via 192.168.1.1 dev eth0
|
||||||
|
ip addr add 192.168.1.1/24 dev eth0
|
||||||
|
ifup ppp0
|
||||||
|
sleep 10
|
18
routers/share/deactivate.sh
Normal file
18
routers/share/deactivate.sh
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# Example router de-activation script
|
||||||
|
#
|
||||||
|
# 1/ Kill internet link
|
||||||
|
# 2/ Nuke them from orbit, it's the only way to be sure
|
||||||
|
# 3/ Release main router address
|
||||||
|
# 4/ Add default route through peer
|
||||||
|
#
|
||||||
|
|
||||||
|
ifdown --force ppp0
|
||||||
|
sleep 2
|
||||||
|
killall -9 pppd
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
ip addr del 192.168.1.1 dev eth0
|
||||||
|
ip route add default via 192.168.1.1 dev eth0
|
29
routers/share/pings
Normal file
29
routers/share/pings
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
try_ping()
|
||||||
|
{
|
||||||
|
export target="$1"
|
||||||
|
export prfile="$2"
|
||||||
|
export endfile=`mktemp`
|
||||||
|
(
|
||||||
|
if ping -c1 $target >/dev/null 2>&1; then
|
||||||
|
rm -f $prfile
|
||||||
|
fi
|
||||||
|
rm -f $endfile
|
||||||
|
) >/dev/null 2>&1 &
|
||||||
|
echo $endfile
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_pings()
|
||||||
|
{
|
||||||
|
local ok=0
|
||||||
|
while [ "$ok" = "0" ]; do
|
||||||
|
sleep 1
|
||||||
|
ok=1
|
||||||
|
for file in $*; do
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
ok=0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
Loading…
Reference in a new issue