Ucarp
UCARP allows a couple of hosts to share common virtual IP addresses in order to provide automatic failover. It is a portable userland implementation of the secure and patent-free Common Address Redundancy Protocol (CARP, OpenBSD’s alternative to the patents-bloated VRRP).
Simple UCARP configuration
iface eth2 inet static address 172.16.1.2 netmask 255.255.255.252 up ucarp -i eth2 -s 172.16.1.2 -v 99 -p password -a 192.168.10.1 -u /etc/ucarp/carp99-up.sh -d /etc/ucarp/carp99-down.sh -P -z -k 10 --daemonize
-i => interace -s => static IP address -v => ucarp ID -p => password -a => floating IP address -u => script to run to set up the floating IP -d => script to run to set up the IP down -P => Preentive -z => Run the -d script when shutting down -k => delay to adverise (the greater delay would be the backup)
more /etc/ucarp/carp99-down.sh
#!/bin/bash /sbin/ip addr del 192.168.10.1/24 dev "$1"
more /etc/ucarp/carp99-up.sh
#!/bin/bash /sbin/ip addr add 192.168.10.1/24 dev "$1"
Advance configuration with watchdog for the ucarp
In the simple configuration, when the primary host looses the link to the switch. It is still master and sometimes this can cause problems. Imagine that we are announcing via BGP or OSPF the connected routers. So via OSPF we will be announcing the virtual IP but actually this is wrong, because the host is isolated.
We will start everything from the ucarp by running an script when the interface goes up. In the /etc/network/interfaces
iface eth2 inet static address 172.16.1.1 netmask 255.255.255.252 up /etc/network/eth2-up.sh down /etc/network/eth2-down.sh
On the up scrip we have to set up the physical IP's, Virtual IP, Ucarp ID.
more /etc/network/eth2-up.sh
# ------------------------------------------------- # UCARP 1 # ------------------------------------------------- # Physical IP of the interface to ucarp IPP=172.16.1.1 # Physical IP of the ucarp Peer (the backup router) EXTERNAL=172.16.1.2 # Virtual IP of the ucarp IPV=192.168.10.1 # Isolation Host (any host in the network to ping to check if we are isolated) HOST=192.168.10.254 # Internal Heartbeat to the second router INTERNAL=172.31.0.130 # Ucarp ID UCARPID=99 # Interface to configure the ucarp INTERFACE=eth2 start-stop-daemon --start --pidfile /var/run/watchdogucarp.$UCARPID.pid --make-pidfile --background --exec /etc/ucarp/ucarp-watchdog.sh -- \ $UCARPID $INTERFACE $IPP $IPV $HOST $INTERNAL $EXTERNAL
The down script just kills the processes related to ucarp:
more /etc/network/eth2-down.sh
#!/bin/bash UCARPID=99 ps -edaf | grep "ucarp-watchdog.sh $UCARPID" | grep -v grep | awk '{ print $2 }' | while read LINE; do kill $LINE; done ps -edaf | grep ucarp | grep -v grep | grep "\-v $UCARPID" | grep -v watchdog | awk '{ print $2 }' | while read LINE; do kill $LINE; done
UCARP watchdog
This ucarp script basically check if we are isolated and if so, we remove the virtual IP in order to route the traffic to the peer router.
Sometimes is possible to have link in the box, but we don't have layer 2 networking. So we can not route traffic. But the thing, is that the IP address is still set up in the box and all the traffic will be tried to be routed throw the link but it goes nowhere. So if this is the case, we will disable the virtual IP until we can get to the isolated host.
So basically this is what the script does:
1. Set up the ucarp if is not already set up
2. Check if the external peer ip is not answering, the heartbit is answering and we don't get to the isolation host, then we are probably ISOLATED, remove the virtual IP if we reach the hold limit and set up as isolated state.
3. Then, once we are in ISOLATED state, we keep trying to get response from the external peer, if so we go back to NON ISOLATED state and we set up back the ip address.
more /etc/ucarp/ucarp-watchdog.sh
#!/bin/bash # Written by Gerard Forns (gforns@gmail.com) February 2009. # Watchdog for ucarp and check if we are isolated # How many times do we require to check if we are isolated to make sure that we really are? HOLDLIMIT=2 # Internal variables, do not touch DOWN=0 HOLD=0 # Checking if parameters are correct if [ $# -ne 7 ] then echo "Usage: $0 ucarpid interface ip_physical ip_virtual isolation_host peer_heartbeat peer_ucarp" exit 65 fi UCARPID=$1 INTERFACE=$2 IPP=$3 IPV=$4 HOST=$5 INTERNAL=$6 EXTERNAL=$7 # # Functions # function start_ucarp { logger "watchdog-ucarp: Starting ucarp $UCARPID: $IPV" start-stop-daemon --start --pidfile /var/run/ucarp.$UCARPID.pid --make-pidfile --background --exec /usr/sbin/ucarp -- \ -i $INTERFACE -s $IPP -v $UCARPID -p password -P -a $IPV -z -u /etc/ucarp/carp$UCARPID-up.sh -d /etc/ucarp/carp$UCARPID-down.sh } function stop_ucarp { logger "watchdog-ucarp: Stopping ucarp $UCARPID: $IPV" ps -edaf | grep ucarp | grep -v grep | grep "\-v $UCARPID" | grep -v watchdog | awk '{ print $2 }' | while read LINE do kill $LINE; done } # # MAIN # # # If ucarp is not up, then we need to start it # UP=$(ps -edaf | grep ucarp | grep -v grep | grep -v watchdog | grep "\-v $UCARPID" | wc -l) if test $UP = 0 then start_ucarp fi # # This is a DAEMON # while [ 1 ] do # We are not ISOLATED if test $DOWN = 0 then ping -c 1 $EXTERNAL FE=$? ping -c 1 $INTERNAL FIN=$? ping -c 1 $HOST FH=$? # # if the external peer ip is not answering, the heartbit is answering and we don't get to the # isolation host, then we are probably ISOLATED, remove the virtual IP if we reach the hold limit # if [ $FE -eq 1 -a $FH -eq 1 -a $FIN -eq 0 ] then HOLD=$(expr $HOLD + 1) if [ $HOLD -eq $HOLDLIMIT ] then stop_ucarp DOWN=1 HOLD=0 fi # # else, we just reset the hold # else HOLD=0 fi # # We are now ISOLATED # else ping -c 1 $EXTERNAL FE=$? # # If our peer answer, means that we are not ISOLATED anymore, then we just set up the virtual IP again # if [ $FE -eq 0 ] then UP=$(ps -edaf | grep ucarp | grep -v grep | grep -v watchdog | grep "\-v $UCARPID" | wc -l) if test $UP = 0 then start_ucarp DOWN=0 fi fi fi # # We wait 30 seconds to poll againg # sleep 30 done
We also need to set up the scripts about what to do when when bringint the virtual address up and down:
more /etc/ucarp/carp99-down.sh
#!/bin/bash /sbin/ip addr del 192.168.10.1/24 dev "$1"
more /etc/ucarp/carp99-up.sh
#!/bin/bash /sbin/ip addr add 192.168.10.1/24 dev "$1"
Finally remember to chmod 755 all the scripts:
chmod 755 /etc/ucarp/carp* chmod 755 /etc/ucarp/watchdog-ucarp.sh chmod 755 /etc/network/eth2*