Je hebt een netwerk met twee routers met beide toegang tot het internet. Je clients krijgen typisch maar één default route toegekend via DHCP, ze gebruiken dus maar één van de twee routers.
Vereiste voorkennis voor maximaal genot: basis netwerken.

Abstract

Bovenstaande situatie kan je op meerdere manieren oplossen maar met VRRP wordt er een virtueel IP adres gedeeld door de routers. Het virtuele IP adres wordt doorgegeven zoals een estafette stokje en wordt ook altijd beantwoord door dezelfde machine zolang de situatie niet veranderd. De routers houden elkaar in de gaten om te zien of het tijd is om actie te ondernemen en zichzelf te promoveren tot nieuwe eigenaar van het virtuele adres.

HSRP/VRRP/CARP: WTF?

HSRP komt uit de Cisco stallen in 1998; de deelnemers bespioneren elkaar via een multicast netwerk waarop ze zich in- en uitschrijven. Rond dezelfde tijd is de IETF werkgroep begonnen met VRRP welke gebruik maakt van RAND patenten. Een bizarre wending later claimt Cisco VRRP eigen en wordt er vanuit de BSD hoek CARP ontwikkeld om een patentloze oplossing te bieden. CARP maakt niet gebruik van een multicast oplossing en gebruikt TCP gesprekken om uit te vissen who is boss.

CARP HSRPv0 VRRPv2
IPv6 support Yes No In draft v3
Message Authentication SHA-1 HMAC Clear-text password, MD5 HMAC (v2 only) Clear-text password, MD5 HMAC
Patented No Yes Patent claim

bron: CARP The Free Fail-over Protocol, Sans Institute. De betekenis wanneer ik VRRP gebruik is dus een beetje afhankelijk van de context. Over het algemeen zal ik er VRRP en gelijkaardige technieken mee bedoelen zoals CARP en HSRP.

Meer

In RFC2338, RFC3768 en RFC5789 wordt VRRP voornamelijk omschreven als een fail-over mechanisme voor een default-gateway. Het jammere is dat dit teveel mensen niet laat realiseren dat je deze techniek ook kan gebruiken voor DNS servers of andere stateless IP services zoals NTP.

Zonder kosten?

Er zijn een paar kleine nadelen aan VRRP: het vereist dat de verleende dienst stateless is wat zelden het geval is. Zo zal een MySQL client het niet fijn vinden als hij ontdekt dat zijn sessie eruit ligt omdat hij plots pakketten stuurt naar een andere MySQL server. Een algemeen probleem is als een IP client die het internet bereikt met behulp van een VRRP gateway. Beide gateways gebruiken echter NAT en hebben ieder aparte NAT tabellen (overzicht van connecties tussen LAN en WAN). Als tijdens de IP sessie het virtuele adres van router wisselt bestaat de netwerk sessie niet in de NAT tabel van de andere router. Hierdoor moet de connectie opnieuw geïnitieerd worden. Voor de meeste services is dit echter geen probleem omdat deze automatisch opnieuw proberen na een kleine time-out of bijvoorbeeld de gebruiker in een HTTP client op refresh duwt. Tevens zijn er protocollen voor het synchroniseren van NAT tabellen ;)

Voorbeelden

Het eerste voorbeeld maakt gebruik van Vyatta en realiseert een redundante default gateway. Vyatta maakt gebruik van keepalived welke VRRP versie 1 implementeert. Het tweede voorbeeld voorziet Windows clients van een betere DNS fail-over functionaliteit op Debian met behulp van ucarp (maw CARP 8)7).

Vyatta

http://tweakers.net/ext/f/IFfC8Se91TTCyR0YcmKLmNdQ/full.jpg Ik heb besloten voor het code voorbeeld een deel van mijn actieve configuratie te gebruiken. Kort samengevat eth1 op jeff is verbonden met hetzelfde segment als eth0.1 op louise (Vyatta 6.5R1). Voor de geïnteresseerden, de lange uitleg: jeff is een gevirtualiseerde Vyatta 6.3 instantie op VMware ESXi (britta). Britta verbind vlan 1: het client lan segment met de virtuele netwerk interface: eth1 van Jeff. Louise bereikt dezelfde VLAN via virtuele interface eth0.1. Het kleine Vyatta versie verschil is waarom show vrrp (summary) lichtjes verschilt.

vyatta@jeff# set interfaces ethernet eth1 vrrp vrrp-group 2 virtual-address 192.168.1.1/25
vyatta@jeff# set interfaces ethernet eth1 vrrp vrrp-group 2 authentication type ah
vyatta@jeff# set interfaces ethernet eth1 vrrp vrrp-group 2 authentication password mypass
vyatta@jeff# set interfaces ethernet eth1 vrrp vrrp-group 2 preempt true
vyatta@jeff# set interfaces ethernet eth1 vrrp vrrp-group 2 priority 20
vyatta@jeff# commit
vyatta@jeff# run show vrrp summary
VRRP Addr Interface VRRP
Interface Group Type Address State State
--------- ----- ---- ------- ----- -----
eth1 2 vip 192.168.1.1/25 up master
vyatta@louise# set interfaces ethernet eth0 vif 1 vrrp vrrp-group 2 virtual-address 192.168.1.1/25
vyatta@louise# set interfaces ethernet eth0 vif 1 vrrp vrrp-group 2 authentication type ah
vyatta@louise# set interfaces ethernet eth0 vif 1 vrrp vrrp-group 2 authentication password mypass
vyatta@louise# set interfaces ethernet eth0 vif 1 vrrp vrrp-group 2 preempt true
vyatta@louise# set interfaces ethernet eth0 vif 1 vrrp vrrp-group 2 priority 10
vyatta@louise# commit
vyatta@louise# run show vrrp
RFC Addr Last Sync
Interface Group State Compliant Owner Transition Group
--------- ----- ----- --------- ----- ---------- -----
eth0.1 2 BACKUP no no 2m35s 

In eerste instantie gaan we de interface eth1 op jeff uitschakelen om te zien of louise de taken overneemt. Nadat dit lukt brengen we jeff terug online en zien we het effect van de pre-empt vlag. Indien deze niet ingesteld was of op false stond zou het gedeelde IP adres niet automatisch terug gaan maar pas als louise het zelfstandig opgeeft (of onbereikbaar wordt).

vyatta@jeff# set interfaces ethernet eth1 disable
vyatta@jeff# commit
vyatta@jeff# run show vrrp summary
                VRRP    Addr                    Interface       VRRP
Interface       Group   Type    Address         State           State
---------       -----   ----    -------         -----           -----
eth1            2       vip     192.168.1.1/25  down            fault

vyatta@louise# run show vrrp
                                 RFC        Addr   Last        Sync
Interface         Group  State   Compliant  Owner  Transition  Group
---------         -----  -----   ---------  -----  ----------  -----
eth0.1            2      MASTER  no         no     2m37s       

vyatta@jeff# delete interfaces ethernet eth1 disable
vyatta@jeff# commit
vyatta@jeff# run show vrrp summary
                VRRP    Addr                    Interface       VRRP
Interface       Group   Type    Address         State           State
---------       -----   ----    -------         -----           -----
eth1            2       vip     192.168.1.1/25  up              master

vyatta@louise# run show vrrp
                                 RFC        Addr   Last        Sync
Interface         Group  State   Compliant  Owner  Transition  Group
---------         -----  -----   ---------  -----  ----------  -----
eth0.1            2      BACKUP  no         no     4s          

Let goed op de hostnames in het voorbeeld.

Debian

http://tweakers.net/ext/f/wsRslR0JCIUKlX7TO8VEjU5a/full.jpg Het is toevallig dat ik ook sample code voor Debian heb, ik heb een paar weken geleden een redundante DNS server opgezet voor lokale domeinen (zie toekomstige blog entry). Community.lan draait op bob en linda (uit Bob’s Burgers. Bob en linda verzorgen de DNS infrastructuur van mijn netwerk met bind (wiki[en]). Microsoft Windows clients schakelen te traag over tussen primaire en secondaire DNS server indien onbereikbaar. Daarom heb ik ervoor gekozen om ze één IP adres met VRRP te laten delen. Dit adres wordt via DHCP uitgedeeld aan de clients als zijnde de primaire DNS server (met bob en linda respectievelijk als secondair en tertiair). In eerste instantie installeren we de ucarp package uit de standaard Debian repositories. Debian being Debian heeft natuurlijk de configuratie geïntegreerd in /etc/network/interfaces. De exacte specificatie vinden we terug in /usr/share/doc/ucarp/README.Debian (pastebin). Wat de verschillende ucarp switches doen kan je in de man ucarp vinden..

root@bob:~# apt-get install ucarp
root@bob:~# cat nano /etc/network/interfaces
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug eth0
iface eth0 inet static
    address 192.168.1.25
    netmask 255.255.255.128
    gateway 192.168.1.1
    ucarp-vid 5
    ucarp-vip 192.168.1.2
    ucarp-password mypass
    ucarp-master yes

iface eth0:ucarp inet static
    address 192.168.1.2
    netmask 255.255.255.128

root@bob:~# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:0c:29:a0:7d:d2  
          inet addr:192.168.1.25  Bcast:192.168.1.127  Mask:255.255.255.128
          inet6 addr: 2001:6f8:14a3:1::25/64 Scope:Global
          inet6 addr: 2001:6f8:14a3:1:20c:29ff:fea0:7dd2/64 Scope:Global
          inet6 addr: fe80::20c:29ff:fea0:7dd2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:403319 errors:0 dropped:0 overruns:0 frame:0
          TX packets:363332 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:33873493 (32.3 MiB)  TX bytes:25367750 (24.1 MiB)
eth0:ucarp Link encap:Ethernet  HWaddr 00:0c:29:a0:7d:d2  
          inet addr:192.168.1.2  Bcast:192.168.1.127  Mask:255.255.255.128
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
root@linda:~# apt-get install ucarp
root@linda:~# cat /etc/network/interfaces
auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet static
        address 192.168.1.26
        netmask 255.255.255.128
        gateway 192.168.1.1
        ucarp-vid 5
        ucarp-vip 192.168.1.2
        ucarp-password blaat345
        ucarp-master no

iface eth0:ucarp inet static
        address 192.168.1.2
        netmask 255.255.255.128

root@linda:~# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:0c:29:eb:dd:9a
          inet addr:192.168.1.26  Bcast:192.168.1.127  Mask:255.255.255.128
          inet6 addr: 2001:6f8:14a3:1:20c:29ff:feeb:dd9a/64 Scope:Global
          inet6 addr: fe80::20c:29ff:feeb:dd9a/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:24 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2042 (1.9 KiB)  TX bytes:532 (532.0 B)

In principe werkt alles nu, we kunnen testen door de interface tijdelijk uit te schakelen. Bijvoorbeeld met ifup en ifdown. In het voorbeeld is bob master en lezen we in de logfiles dat hij nu backup is. In de logfile van linda horen we de andere kant van het verhaal.

root@bob:~# ifconfig eth0:ucarp
eth0:ucarp Link encap:Ethernet  HWaddr 00:0c:29:a0:7d:d2
          inet addr:192.168.1.2  Bcast:192.168.1.127  Mask:255.255.255.128
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
root@bob:~# ifdown eth0 && ifup eth0
root@bob:~# cat /var/log/syslog| grep ucarp
Feb 24 04:25:12 bob ucarp[9959]: [ERROR] exiting: pfds[0].revents = 8
Feb 24 04:25:12 bob ucarp[9959]: [WARNING] Spawning [/usr/share/ucarp/vip-down eth0 192.168.1.2]
Feb 24 04:25:12 bob ucarp[10183]: [INFO] Local advertised ethernet address is [00:0c:29:a0:7d:d2]
Feb 24 04:25:12 bob ucarp[10183]: [WARNING] Switching to state: BACKUP
Feb 24 04:25:12 bob ucarp[10183]: [WARNING] Spawning [/usr/share/ucarp/vip-down eth0 192.168.1.2]
root@linda:~# cat /var/log/syslog| grep ucarp
Feb 24 04:25:15 linda ucarp[1849]: [WARNING] Switching to state: MASTER
Feb 24 04:25:15 linda ucarp[1849]: [WARNING] Spawning [/usr/share/ucarp/vip-up eth0 192.168.1.2]
root@linda:~# ifconfig eth0:ucarp
eth0:ucarp Link encap:Ethernet  HWaddr 00:0c:29:eb:dd:9a
          inet addr:192.168.1.2  Bcast:192.168.1.127  Mask:255.255.255.128
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

Conclusie

VRRP is handig, gemakkelijk en liev <3

Referentielijst