Manual Setup Steps

Before you can use keepalived it must be installed either via the gui or manually from the cli.
The cli command for this is:

pakfire install keepalived

This will (currently) just install the necessary binaries and a couple of sample configs to be found under /etc/keepalived.

For creating a mostly consistent setup its a good idea to have a subdirectory at /var/ipfire for keepalived configs and scripts. One side effect of this will be that at least parts of the config will be included in the already existing backup solution of ipfire.
Just do it with:

mkdir /var/ipfire/keepalived

Use Case VRRP

VRRP is the acronym for "Virtual Router Redundancy Protocol". Its defined in rfc5798.
Keepalived implements much more than this (see below). It works in a multi vendor environment as it is an open standard.

If you have at least two ipfires creating a high available gateway to the outside you probably want to have just one gateway to configure at the client side. This is exactly what VRRP is designed for.

This description will just show a real implementation of VRRP only (at the point in time) currently working somewhere.

Config File /etc/keepalived/keepalived.config

The green network is located at 172.20.32.0/24 where .1 is the exit router.
Two ipfires are setup as proxies for this network using these addresses:

  • 172.20.32.6 logical address
  • 172.20.32.7 real device address node1
  • 172.20.32.8 real device address node2

Master Router Config

! Configuration File for keepalived Master
global_defs {
 notification_email {
   root@local.lan
 }
 notification_email_from root@proxynode2.local.lan
 smtp_server 172.20.32.25
 smtp_connect_timeout 30
 router_id proxynode1
 static_routes { 172.16.0.0/12 via 172.20.32.1 dev green0 }
 static_routes { 10.0.0.0/16 via 172.20.32.1 dev green0 }
}
vrrp_instance VI_1 {
  state MASTER
  interface green0
  virtual_router_id 81
  priority 150
  advert_int 1
  authentication {
#        auth_type PASS
# AH 51/ip works encrypted
      auth_type AH
      auth_pass vrrp4lan
      ! password length max 8 characters and its clear text
  }
  virtual_ipaddress {
      172.20.32.6/24 brd 172.20.32.255 dev green0
  }
}

Slave Router Config

! Configuration File for keepalived for the Slave

global_defs {
 notification_email {
   root@local.lan
 }
 notification_email_from root@proxynode2.local.lan
 smtp_server 172.20.32.25
 smtp_connect_timeout 30
 router_id proxynode2
 static_routes { 172.16.0.0/12 via 172.20.32.1 dev green0 }
 static_routes { 10.0.0.0/16 via 172.20.32.1 dev green0 }
}

vrrp_instance VI_1 {
  state BACKUP
  interface green0
  virtual_router_id 81
  priority 100
  advert_int 1
  authentication {
#        auth_type PASS
      auth_type AH
      auth_pass vrrp4lan
  }
  virtual_ipaddress {
      172.20.32.6/24 brd 172.20.32.255 dev green0
  }
}

Start-Stop Script

#!/bin/bash
# start/stop script for ipfire's keepalived packet
# (w) Cisco Bob 2013
# History:
# 22.Aug 2013 CB initial version

DAEMON="/usr/sbin/keepalived"
VRRP="--vrrp"
CHECK="--check"
CFGFILE="-f /var/ipfire/keepalived/keepalived.conf"
#WDOG_VRRP="--wdog-vrrp 1" #not supported
WDOG_CHECK="--wdog-check 30"
DEFAULTS="/var/ipfire/keepalived/defaults"
PIDFILE="/var/run/keepalived.pid"
DEBUG=""

daemonName=${DAEMON##*/}

if [ -s $DEFAULTS ]
then
  . $DEFAULTS
fi

if [ ! -x $DAEMON ]
then
  echo "File $DAEMON is not executable - bailout"
  exit 3
fi

if [ ! $CFGFILE ]
then
  echo "sorry configile $CFGFILE must exist - bailout"
  exit 3
fi

function startProc () {
  $DAEMON $DEBUG $VRRP $CHECK $CFGFILE $WDOG_VRRP $WDOG_CHECK
    [ $? -eq 0 ] && echo "$!" >$PIDFILE
}
function stopProc () {
    if [ -f $PIDFILE ]
  then
      kill $(cat $PIDFILE)
      rm -f $PIDFILE
  else
      list=$(ps -ef | grep keepalived | grep -v grep)
       if [ -z $list ]
      then
          # no process found - exit silently
          exit 0
      fi
      pidOfDaemonRaw=$(ps -ef | grep $daemonName | awk '{ print $2 ","$3}')
      # returns 1555,1 if it is the daemon
        pidOfParent=${pidOfDaemonRaw#*,}
        pidOfDaemon=${pidOfDaemonRaw%,*}
        if [ $pidOfParent = "1" ]
      then
          #echo "OK - killing $DAEMON with PID=$pidOfDaemon"
          kill $pidOfDaemon
      fi
  fi
}

if [ $# -lt 1 ]
then
  echo "usage: $0 start|stop|restart"
  exit 3
fi

case $1 in
  start)
      startProc
      ;;
  stop)
      stopProc
      ;;
  restart)
      stopProc
      sleep 1
      startProc
      ;;`
    *)
      echo "unsupported paramter: $1 should be start,stop,restart"
      ;;
esac
exit 0

Defaults file /var/ipfire/keepalived/defaults

The purpose of the "defaults-file" is to keep all configurable parameters in one place easy to change and to adjust without the need to change the script itself.

# gets sourced by keepalived start/stop script
DAEMON="/usr/sbin/keepalived"
VRRP="--vrrp"
#CHECK="--check"
CHECK=""
CFGFILE="-f /var/ipfire/keepalived/keepalived.conf"
#WDOG_VRRP="--wdog-vrrp 1" #not supported
#WDOG_CHECK="--wdog-check 30"
WDOG_CHECK=""
PIDFILE="/var/run/keepalived.pid"
# for debugging set
#DEBUG="--dont-fork --log-console --log-detail"
#DEBUG="--log-detail"
DEBUG=""

Startup and Setup Helper

For setting all the necessary links in the filesystem the following script could be used.
All what it does is just linking the needed files to the corresponding startup directories so that keepalived will be executed during startup and shutdown properly.

#!/bin/bash
set +u
# setup for keepalived configuration
# (w) Cisco Bob
# History:
# 22.Aug 2013 CB initial version
#
script="keepalived"
cfg="/etc/$script/$script.conf"
srcDir="/var/ipfire/$script"
backupFile="/var/ipfire/backup/include"

if [ -f $cfg ]
then
  mv $cfg ${cfg}.orig
fi
ln -sf $srcDir/${script}.conf $cfg
ln -sf $srcDir/$script /etc/init.d/${script}
ln -sf $srcDir/$script /etc/rc.d/rc3.d/S70${script}
ln -sf $srcDir/$script /etc/rc.d/rc0.d/K01${script}
ln -sf $srcDir/$script /etc/rc.d/rc6.d/K01${script}
echo "links created"

# now add it to the backup def file (multi call capable)
# yes I know not very elegant :-( - but does the job
echo "filter backupfile"
grep -v $script $backupFile >/tmp/include
echo "add keepalived to backup file"
mv /tmp/include /var/ipfire/backup/include
echo "/var/ipfire/${script}/*" >>/var/ipfire/backup/include
echo "done"

Virtual Services

not started yet

Good to know

firewall blocks vrrp

Add this to /etc/sysconfig/firewall.local

iptables -I INPUT -i <INTERFACE> -d 224.0.0.0/8 -p vrrp -j ACCEPT

Show firewall.local

User case 2

I have two IPFire and wanted a hardware failover, but I only have one ISP. If one (the MASTER) has maintenance (or goes down) the other (BACKUP) takes over and EVERYONE can continue to surf (in my case a family of 3 and maybe a quest ;).

The services that will failover are:

  • Internet access
  • DHCP server

Otherwise they are similarly installed with IDS, Guardian and Blocklists.

I also use OpenVPN and though I took a backup from MASTER to BACKUP, I right now use different dynamic DNS names for the two IPFires to connect to them (both IPFires get different IPs from the ISP). When I know more, maybe also this will be failovered.

  • My MASTER IPFire has the IP 192.168.0.251
  • My BACKUP IPFire has the IP 192.168.0.252
  • The "virtual" IPFire failover firewall has the IP 192.168.0.254

These are the steps I used:

1/6. Install

Well, you just go to https://ipfire:444/cgi-bin/pakfire.cgi and install keepalived

2/6 Edit keepalived.conf

On both firewalls edit /etc/keepalived/keepalived.conf. For more info about keepalived parameters, see http://www.keepalived.org/manpage.html

MASTER

global_defs {
 notification_email {
   myemail@gmail.com
      }`
 notification_email_from ipfire@gmail.com
 smtp_server localhost
 smtp_connect_timeout 30

 # String identifying the machine (doesn't have to be hostname).
 # (default: local host name)
 router_id MAIN_ROUTER
}

vrrp_instance VI_1 {
  # Initial state
  state MASTER
  interface green0

  # Arbitary unique number 0..255
  # used to differentiate multiple instances of vrrpd
  virtual_router_id 22

  # For electing MASTER, highest priority wins.
  # To be MASTER, make 50 more than other machines.
  priority 100

  # VRRP Advert interval in seconds
  advert_int 1

  # Note: authentication was removed from the VRRPv2 specification by
  # RFC3768 in 2004.
  #   Use of this option is non-compliant and can cause problems; avoid
  #   using if possible, except when using unicast, where it can be helpful.
  authentication {
      auth_type PASS
      auth_pass secretpassword
  }
  virtual_ipaddress {
      192.168.0.254
  }
}

BACKUP

! Configuration File for keepalived

global_defs {
 notification_email {
   myemail@gmail.com
      }
 notification_email_from ipfire@gmail.com
 smtp_server localhost
 smtp_connect_timeout 30
 router_id LVS_DEVEL
}

vrrp_instance VI_1 {
  state BACKUP
  interface green0
  virtual_router_id 22
  priority 50
  advert_int 1
  authentication {
      auth_type PASS
      auth_pass secretpassword
  }
  virtual_ipaddress {
      192.168.0.254
  }
}

3/6 Add vrrp to Iptables

On both IPFires, add
iptables -I INPUT -i green0 -d 224.0.0.0/8 -p vrrp -j ACCEPT
to /etc/sysconfig/firewall.local (as standard the firewall blocks vrrp)

4/6 Make "same" DHCP work during failover

On both IPFires. Add the same "virtual" IPFire failover firewall IP to /var/ipfire/dhcp/dhcpd.conf.local (copy from /var/ipfire/dhcp/dhcpd.conf and edit)

E.g

subnet 192.168.0.0 netmask 255.255.255.0 #GREEN
{
      range 192.168.0.50 192.168.0.150;
      option subnet-mask 255.255.255.0;
      option domain-name "localdomain";
      option routers 192.168.0.254;
      option domain-name-servers 192.168.0.254, 8.8.8.8;
      option ntp-servers 192.168.0.254;
      default-lease-time 3600;
      max-lease-time 7200;
} #GREEN

On both IPFires, do
ln -s /etc/keepalived/ /var/ipfire/keepalived

6/6 Make keepalived run at boot

On both IPFires, edit /etc/sysconfig/rc.local and add /etc/init.d/keepalived start

If you are here, reboot both IPFires (or do 3 manually and run /etc/init.d/keepalived stop and /etc/init.d/keepalived start manually)

External Links/Documents

Keywords: vrrp first hop redundancy ha high availability