VRRP et Linux, un peu de bricolage…
On reprend l’article précédent en mettant un peu les mains dans le camboui.
Un petit patch
Un patch (peut-être pas très propre ni très abouti) est disponible ici http://aandre.evolix.net/files/vrrpd/vrrpd-1.0-ebtables.diff. Il permet d’utiliser la méthode décrite précédemment tout en améliorant l’affichage du statut de vrrpd pendant son exécution.
Le script /etc/vrrpd/vrrp_switch sera exécuté lors des changements d’états avec des arguments supplémentaires:
- l’IP virtuelle VRRP,
- l’interface sur laquelle l’instance VRRP tourne,
- la priorité actuelle de l’instance,
- l’advertisement interval VRRP
- la preemption VRRP
On récupère aussi l’adresse mac matérielle de l’interface du routeur, et l’adresse mac VRRP.
On va ainsi logger plus d’information sur l’état de notre routeur VRRP dans /var/vrrp/vrrp-$VRRP_NAME, mais surtout on aura à disposition les paramètres nécessaires pour le bon fonctionnement de nos règles ebtables gérant les états master et slave.
Il est prévu d’utiliser vrrpd avec l’option -n afin que ce dernier n’ait pas à gérer l’adresse mac virtuelle. Néanmoins cela entraîne aussi l’envoi des paquets d’échanges VRRP avec l’adresse mac matérielle. Le patch corrige cela.
On télécharge les sources de vrrpd ici http://ftp.de.debian.org/debian/pool/main/v/vrrpd/vrrpd_1.0-1exp1.tar.gz
$ wget http://ftp.de.debian.org/debian/pool/main/v/vrrpd/vrrpd_1.0-1exp1.tar.gz $ tar zxvf vrrpd_1.0-1exp1.tar.gz
On applique le patch et on compile:
$ wget http://aandre.evolix.net/files/vrrpd/vrrpd-1.0-ebtables.diff $ cd vrrpd-1.0 && patch -p1 < ../vrrpd-1.0-ebtables.diff $ make
On prépare l’environnement de vrrpd à la main:
En root
# mkdir /etc/vrrpd && cp debian/vrrp_switch /etc/vrrp # mkdir /var/vrrp
Voilà on est prêt à tester vrrpd, en utilisant la topologie classique suivante :
Dans cet article on se contentera de tester la bascule VRRP en pingant continuellement l’adresse ip virtuelle et on regardera si les adresses MAC sont correctes dans /proc/net/arp de la machine “client”.
Côté Cisco 800
On configure une instance VRRP avec un group ID de 10, une priorité de 110, un advertisement interval de 2s et l’adresse IP virtuelle 192.168.10.250, sur l’interface configurée avec l’adresse 192.168.10.2/24 :
conf t interface bla vrrp 10 ip 192.168.10.250 vrrp 10 priority 110 vrrp 10 timers advertise 2
Côté Linux
On prépare le bridge en y ajoutant la ou les interfaces que l’on souhaite, ici eth0.
# brctl addbr br0 # ifconfig eth0 up # brctl addif br0 eth0 # ifconfig br0 192.168.10.3
On lance vrrpd sur cette interface avec une priorité de 90 (donc backup par rapport au cisco).
# ./vrrpd -n -i br0 -v 10 -p 90 -d 2 -l demo 192.168.10.250 -D
L’état de la machine faisant tourner vrrpd est bien slave :
# cat /var/vrrp/state.10 slave # cat /var/vrrp/vrrp-demo VRRP - demo Group 10 State is slave Virtual IP address is 192.168.10.250 Virtual MAC address is 00:00:5E:00:01:a demo is running on br0 Priority is 90 Advertisement interval is 2 Preemption is true
Côté client
On peut lancer un tcpdump sur l’interface 192.168.10.12.
# tcpdump -vvv -xx -i eth0 -n vrrp 11:12:09.311568 IP (tos 0xc0, ttl 255, id 0, offset 0, flags [none], proto VRRP (112), length 40) 192.168.10.2 > 224.0.0.18: VRRPv2, Advertisement, vrid 10, prio 110, authtype none, intvl 2s, length 20, addrs: 192.168.10.250 0x0000: 0100 5e00 0012 0000 5e00 010a 0800 45c0 0x0010: 0028 0000 0000 ff70 0fe9 c0a8 0a02 e000 0x0020: 0012 210a 6e01 0002 a54f c0a8 0afa 0000 0x0030: 0000 0000 0000 0000 0000 0000
Et l’on voit défiler les paquets VRRP d’avertissement émis par le routeur master (le cisco 800) avec l’adresse mac virtuelle 0000 5e00 010a
Un coup d’oeil sur les résolutions arp à partir de la machine client:
$ ping -c 1 192.168.10.2 $ ping -c 1 192.168.10.3 $ ping -c 1 192.168.10.250 $ cat /proc/net/arp IP address HW type Flags HW address Mask Device 192.168.10.2 0x1 0x6 00:1e:7a:93:6f:21 * eth0 192.168.10.3 0x1 0x2 00:13:72:76:23:aa * eth0 192.168.10.250 0x1 0x2 00:00:5e:00:01:0a * eth0
Les deux routeurs sont toujours accessibles sur leur ip réelles avec les adresse mac matérielles correspondantes. La VMAC de l’instance VRRP est bien associée à 192.168.10.250.
Simulons grossièrement une “panne” du master en débranchant le cisco du lan et en pingant continuellement la VIP à partir du client:
$ ping 192.168.10.250 [...] 64 bytes from 192.168.10.250: icmp_seq=108 ttl=255 time=0.972 ms 64 bytes from 192.168.10.250: icmp_seq=109 ttl=255 time=0.959 ms 64 bytes from 192.168.10.250: icmp_seq=117 ttl=64 time=0.195 ms 64 bytes from 192.168.10.250: icmp_seq=118 ttl=64 time=0.171 ms [...]
La convergence vers le nouveau master s’est faite en quelques secondes, on l’observe sur le ping (ah regardez la ttl par exemple et /proc/sys/net/ipv4/ip_default_ttl sur la machine faisant tourner vrrpd…).
$ cat /var/vrrp/state.10 master $ cat /var/vrrp/vrrp-demo VRRP - demo Group 10 State is master Virtual IP address is 192.168.10.250 Virtual MAC address is 00:00:5E:00:01:a vrrpd- is running on br0 Priority is 90 Advertisement interval is 2 Preemption is true
Dans notre tcpdump, on voit que c’est vrrpd qui génère à présent les avertissements VRRP.
11:43:51.714625 IP (tos 0x0, ttl 255, id 256, offset 0, flags [none], proto VRRP (112), length 40) 192.168.10.3 > 224.0.0.18: VRRPv2, Advertisement, vrid 10, prio 90, authtype none, intvl 2s, length 20, addrs: 192.168.10.250 0x0000: 0100 5e00 0012 0000 5e00 010a 0800 4500 0x0010: 0028 0100 0000 ff70 0fa8 c0a8 0a03 e000 0x0020: 0012 210a 5a01 0002 b94f c0a8 0afa 0000 0x0030: 0000 0000 0000 0000 0000 0000
L’interface br0 s’est bien appropriée la VIP 192.168.10.250:
$ ip addr show br0
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 00:13:72:76:23:aa brd ff:ff:ff:ff:ff:ff
inet 192.168.10.3/24 brd 192.168.10.255 scope global br0
inet 192.168.10.250/32 brd 192.168.10.250 scope global br0Vérifions à nouveau les adresses mac
$ ping -c 1 192.168.10.3 $ ping -c 1 192.168.10.250 $ cat /proc/net/arp IP address HW type Flags HW address Mask Device 192.168.10.3 0x1 0x2 00:13:72:76:23:aa * eth0 192.168.10.250 0x1 0x2 00:00:5e:00:01:0a * eth0
Tout est ok lorsque vrrpd est master.
On peut aussi vérifier les règles ebtables insérées lors du passage à l’état master :
navi:/var/vrrp# ebtables -t broute -L Bridge table: broute Bridge chain: BROUTING, entries: 1, policy: ACCEPT -p IPv4 -d 0:0:5e:0:1:a --logical-in br0 -j redirect navi:/var/vrrp# ebtables -L Bridge table: filter Bridge chain: INPUT, entries: 0, policy: ACCEPT Bridge chain: FORWARD, entries: 0, policy: ACCEPT Bridge chain: OUTPUT, entries: 1, policy: ACCEPT -p ARP -s 0:13:72:76:23:aa --logical-out br0 --arp-op Reply --arp-ip-src 192.168.10.250 -j DROP navi:/var/vrrp# ebtables -t nat -L Bridge table: nat Bridge chain: PREROUTING, entries: 1, policy: ACCEPT -p ARP --logical-in br0 --arp-op Request --arp-htype 1 --arp-ptype IPv4 --arp-ip-dst 192.168.10.250 -j arpreply --arpreply-mac 0:0:5e:0:1:a --arpreply-target ACCEPT Bridge chain: OUTPUT, entries: 0, policy: ACCEPT Bridge chain: POSTROUTING, entries: 1, policy: ACCEPT -p IPv4 --logical-out br0 --ip-src 192.168.10.250 -j snat --to-src 0:0:5e:0:1:a --snat-target ACCEPT
Conclusion
L’exemple porte sur une seule instance de VRRP, mais il sera possible d’en lancer plusieurs en parallèle sur la mêmes interfaces et conserver la même cohérence.
Un autre sujet intéressant sur vrrpd pourrait concerner la fonctionnalité de tracking d’interface, qui prend tout son sens dans le cas par exemple d’un backup de ligne adsl. Néanmoins le code en l’état ne permet pas de l’utiliser sur ppp0 (cf les fonctions monitorit() l.1984 et mido_read() l.2005).

