Howto VRRP
Le protocole VRRP permet à plusieurs équipements, sur un même segment réseau, de partager une même adresse IP en gérant des états master/slave. L’objectif principal est de permettre une bascule réseau sur un équipement secondaire en cas d’incident. Sous OpenBSD, on utilise un dérivé de ce protocole : CARP. Sous Linux, il existe plusieurs implémentations d’un démon vrrpd.
Installation
Le paquet officiel vrrpd pose différents soucis, nous utilisons à la place un paquet avec plusieurs patchs disponible sur le dépôt Evolix :
# apt install vrrpd=1.0-2.evolix
Note : Nous avons entrepris la ré-écriture d’un démon vrrpd : uvrrpd mais nous ne l’utilisons pas encore en production.
Patchs sur le paquet Debian
Notre paquet vrrpd intègre différents patches, notamment un script permettant d’utiliser les macvlan :
- debian/patches/010-vrrpd-1.0_to_1.0-1exp1
- debian/patches/120-orig_prio.patch
- debian/patches/150-fix_vrid_check.patch
- debian/patches/series
- debian/patches/100-external_script_enhanced.patch
- debian/patches/170-log_format.patch
- debian/patches/130-receive_multicast.patch
- debian/patches/140-vrrp_switch_macvlan.patch
- debian/patches/011-fix_compile_warnings.patch
- debian/patches/012-typo_help_auth_pw.patch
- debian/patches/110-slave_init_state.patch
- debian/patches/160-dont_handle_virtual_ip.patch
- [...]
- debian/vrrp_switch_macvlan
- debian/sysctl.vrrpd
- debian/README.macvlan
L’utilisation des macvlans permet d’avoir des adresses MAC spécifiques à VRRP. Pour cela, il faut :
- utiliser le script
/etc/vrrpd/vrrp_switch
(installé par défaut) - utiliser l’option
-x
pour interdire à vrrpd de manipuler les interfaces en déléguant cette opération au script. Dans ce mode, vrrpd reçoit et émet des paquets VRRP et appelle /etc/vrrpd/vrrp_switch lors des changements d’états master/slave - ne pas utiliser l’option
-n
Utilisation
Il faut au préalable ajuster des paramètres sysctl, par exemple dans /etc/sysctl.d/vrrpd.conf
(voir /usr/share/doc/vrrpd/sysctl.vrrpd
) :
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
# Pouvoir écouter sur une adresse IP non présente localement (lorsque la machine est slave)
net.ipv4.ip_nonlocal_bind=1
Si l’on utilise minifirewall comme pare-feu, 2 actions supplémentaires sont nécessaires :
- Il faut ajouter la commande suivante dans sa configuration
/etc/default/minifirewall
, pour s’assurer que les paramètres soient gardés après redémarrage de minifirewall :
sysctl -p /etc/sysctl.d/vrrpd.conf --quiet
- Et il faut également commenter l’activation du rp_filter dans
/etc/init.d/minifirewall
, et ajouter sa désactivation totale :
# Enable Reverse Path filtering : verify if responses use same network interface
#for i in /proc/sys/net/ipv4/conf/*/rp_filter; do
#echo 1 > $i
#done
# Disable Reverse Path filtering for vrrp
for i in /proc/sys/net/ipv4/conf/*/rp_filter; do
echo 0 > $i
done
Attention : ne pas simplement commenter le bloc ou modifier le “echo 1” de l’activation en “echo 0”, mais bien commenter le premier bloc et ajouter le second bloc pour bien expliciter le changement de configuration.
Au niveau du pare-feu, il faut ajouter la règle suivante :
# iptables -A INPUT -s <adresse IP du pair> -d 224.0.0.18 -j ACCEPT
Puis, on lance par exemple la commande suivante :
# vrrpd -i eth0 -x -D -d 10 -v 42 -p 100 -a pw/0xPASSWORD -l foo 192.0.2.42/27
Détails des options utilisées :
-i eth0
: se binder sur l’interface eth0-x
: ne pas manipuler d’interface mais déléguer au scriptvrrp_switch
-D
: lancer en mode démon-d 10
: intervalle d’avertissement en seconde (défaut : 1)-v 42
: identifiant VRID (il doit être unique sur un même segment réseau)-p 100
: priorité entre 1 et 255 (défaut : 100) ; le plus élevé est master-l foo
: nom de l’instance-a pw/OxPASSWORD
: mot de passe en hexadécimal
Au bout de quelques dizaines de secondes, vrrpd va passer dans l’état master et créer l’interface vrrp_${vrid}_${interface}
avec l’adresse IP et l’adresse MAC 00:00:5e:00:01:${vrid}
:
$ ifconfig vrrp_2_eth0
vrrp_2_eth0 Link encap:Ethernet HWaddr 00:00:5e:00:01:2a
inet adr:192.0.2.42 Bcast:0.0.0.0 Masque:255.255.255.224
adr inet6: fe80::200:5eff:fe00:102/64 Scope:Lien
[...]
On devrait voir cela dans les logs (syslog) :
Apr 23 18:26:28 lb01 vrrpd->lan[57143]: Starting (adver_int: 10000000, vrid: 42, use virtual mac: yes)
Apr 23 18:26:28 lb01 vrrpd->lan[57143]: VRRP ID 42 on eth0 (prio: 100) : we are now a backup router.
Apr 23 18:26:59 lb01 vrrpd->lan[57143]: VRRP ID 42 on eth0 (prio: 100): we are now the master router.
Sur une autre machine, après avoir également ajusté les paramètres sysctl, on lance la même commande avec une priorité plus faible :
# vrrpd -i eth0 -x -D -d 10 -v 42 -p 90 -a pw/0xPASSWORD -l foo 192.0.2.42/27
Cette machine va rester en état slave tant qu’elle capte des messages d’avertissement de la machine master :
Apr 23 18:26:28 lb02 vrrpd->lan[57143]: Starting (adver_int: 10000000, vrid: 42, use virtual mac: yes)
Apr 23 18:26:28 lb02 vrrpd->lan[57143]: VRRP ID 42 on eth0 (prio: 90) : we are now a backup router.
On pourra utiliser une unité systemd pour start/stop le démon.
[Unit]
Description=VRRP Daemon
After=network.target
[Service]
ExecStart=/usr/sbin/vrrpd -i eth0 -x -D -d 10 -v 42 -p 90 -a pw/0xPASSWORD -l foo 192.0.2.42/27
Restart=on-failure
Type=forking
IgnoreSIGPIPE=no
KillMode=process
RemainAfterExit=yes
[Install]
WantedBy=default.target
Logs
- Des logs sont envoyés à syslog
- L’historique des changements d’états dans
/var/log/vrrpd/state.$vrid
- L’état courant se trouve dans /var/run/vrrpd/vrrp-${instance_name}
- Un fichier PID est dans
/var/run/vrrpd_${instance_name}_${vrid}.pid
Bascule d’un serveur à l’autre
Pour faire en sorte que l’adresse IP bascule sur le serveur slave, il suffit de couper vrrpd sur la machine master. La machine slave détectera alors qu’il est tout seul et prendra l’adresse IP.
Générer un mot de passe
Pour générer un mot de passe VRRP de 6 octets :
printf "pw/0x%s\n" $(openssl rand -hex 6)