22
0
Fork 0
wiki/HowtoVRRP.md

245 lines
9.8 KiB
Markdown
Raw Permalink Normal View History

2017-05-05 12:09:19 +02:00
---
categories: network
title: Howto VRRP
...
2016-12-29 11:25:39 +01:00
2017-05-05 12:09:19 +02:00
Le protocole [VRRP](https://www.ietf.org/rfc/rfc3768.txt) permet à plusieurs équipements, sur un même segment réseau, de partager une même adresse IP en gérant des états *master*/*slave*. Lobjectif principal est de permettre une bascule réseau sur un équipement secondaire en cas dincident. Sous OpenBSD, on utilise un dérivé de ce protocole : [CARP](HowtoOpenBSD/CARP). Sous Linux, il existe plusieurs implémentations d'un démon _vrrpd_.
2016-12-29 11:25:39 +01:00
2017-05-05 12:09:19 +02:00
## Installation
2016-12-29 11:25:39 +01:00
2017-09-13 15:47:36 +02:00
Le [paquet officiel vrrpd](https://packages.debian.org/jessie/vrrpd) pose différents soucis, nous utilisons à la place un [paquet avec plusieurs patchs](#patchs-sur-paquet-patchés) disponible sur le [dépôt Evolix](http://pub.evolix.net/jessie/) :
2016-12-29 11:25:39 +01:00
2017-05-05 12:09:19 +02:00
~~~
# apt install vrrpd=1.0-2.evolix
~~~
2017-05-05 12:38:12 +02:00
> *Note* : Nous avons entrepris la ré-écriture d'un démon _vrrpd_ : [uvrrpd](https://forge.evolix.org/projects/uvrrpd) mais nous ne l'utilisons pas encore en production.
2017-05-05 12:09:19 +02:00
2017-09-13 15:47:36 +02:00
### Patchs sur le paquet Debian
2017-05-05 12:09:19 +02:00
2017-09-13 15:47:36 +02:00
Notre paquet *vrrpd* intègre différents patches, notamment un script permettant d'utiliser les *macvlan* :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
- 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
~~~
2017-05-05 12:09:19 +02:00
L'utilisation des *macvlans* permet d'avoir des adresses MAC spécifiques à VRRP. Pour cela, il faut :
2016-12-29 11:25:39 +01:00
2017-05-05 12:09:19 +02:00
* utiliser le script `/etc/vrrpd/vrrp_switch` (installé par défaut)
2023-11-17 16:35:54 +01:00
* 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_/_backup_
2017-05-05 12:09:19 +02:00
* ne pas utiliser l'option `-n`
2016-12-29 11:25:39 +01:00
2017-05-05 12:09:19 +02:00
## Utilisation
2016-12-29 11:25:39 +01:00
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`) :
2017-01-03 11:20:35 +01:00
2016-12-29 11:25:39 +01:00
~~~
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
2023-11-17 16:35:54 +01:00
# Pouvoir écouter sur une adresse IP non présente localement (lorsque la machine est _backup_)
2021-07-15 15:25:31 +02:00
net.ipv4.ip_nonlocal_bind=1
2016-12-29 11:25:39 +01:00
~~~
2023-11-17 16:35:54 +01:00
### minifirewall
2023-11-17 16:35:54 +01:00
Si l'on utilise [minifirewall](https://gitea.evolix.org/evolix/minifirewall) comme pare-feu, il y a des actions à réaliser en fonction de la version de minifirewall.
Vérifier votre version de minifirewall avec la commande suivante : `/etc/init.d/minifirewall version`.
2023-11-17 16:35:54 +01:00
#### Version 22.03 ou ultérieure
Il faut simplement avoir `SYSCTL_RP_FILTER='0'` dans `/etc/default/minifirewall`.
Ajouter une autorisation dans `/etc/minifirewall.d/vrrpd` :
~~~
iptables -A INPUT -i <interface> -s <adresse IP du pair> -d 224.0.0.0/8 -j ACCEPT
iptables -A OUTPUT -o <interface> -p 112 -j ACCEPT
~~~
Il est possible de ne pas restreindre à l'interface ou à l'IP du(des) pair(s), mais on acceptera alors des paquets d'origines moins ciblées.
Si des paquets CARP sont reçus par un processus vrrpd, on aura des messages d'erreurs `vrrp invalid checksum` dans les logs pou chaque paquet.
2023-11-17 16:35:54 +01:00
#### Version inconnue ou antérieure
2023-11-17 16:35:54 +01:00
* 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 les mêmes règles (entrée et sortie) que pour la version 22.03 ou ultérieure de minifirewall.
2017-09-13 15:47:36 +02:00
2023-11-17 16:35:54 +01:00
### Exécution
#### Manuelle
On peut démarrer un processus VRRP (manuellement ou au boot via `/etc/rc.local`) avec cette commande:
2017-05-05 12:09:19 +02:00
~~~
2023-11-17 16:35:54 +01:00
# vrrpd -i eno0 -x -D -d 10 -v 42 -p 100 -a pw/0xPASSWORD -l foo 192.0.2.10/27
2017-05-05 12:09:19 +02:00
~~~
2016-12-29 11:25:39 +01:00
2017-05-05 12:09:19 +02:00
Détails des options utilisées :
2016-12-29 11:25:39 +01:00
2023-11-17 16:35:54 +01:00
* `-i eno0` : se binder sur l'interface _eno0_
2017-05-05 12:09:19 +02:00
* `-x` : ne pas manipuler d'interface mais déléguer au script `vrrp_switch`
* `-D` : lancer en mode démon
* `-d 10` : intervalle d'annonce en seconde (défaut : 1)
2017-05-05 12:09:19 +02:00
* `-v 42` : identifiant VRID (il doit être unique sur un même segment réseau)
2020-12-01 15:33:49 +01:00
* `-p 100` : priorité entre 1 et 255 (défaut : 100) ; le plus élevé est master
2017-05-05 14:44:04 +02:00
* `-l foo` : nom de l'instance
2017-09-13 15:47:36 +02:00
* `-a pw/OxPASSWORD` : mot de passe en hexadécimal
2016-12-29 11:25:39 +01:00
Au bout de 3 fois l'intervalle d'annonce, vrrpd va passer dans l'état _master_ et créer l'interface `vrrp_${vrid}_${interface}` avec l'adresse IP voulue. L'adresse MAC sera de la forme `00:00:5E:00:01:<XX>``<XX>` est le `VRID` encodé en hexadécimal.
2017-05-05 12:09:19 +02:00
~~~
2023-11-17 16:35:54 +01:00
$ ifconfig vrrp_42_eno0
vrrp_42_eno0 Link encap:Ethernet HWaddr 00:00:5e:00:01:2a
inet adr:192.0.2.10 Bcast:0.0.0.0 Masque:255.255.255.224
2017-05-05 12:09:19 +02:00
adr inet6: fe80::200:5eff:fe00:102/64 Scope:Lien
[...]
~~~
2017-09-13 15:47:36 +02:00
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)
2023-11-17 16:35:54 +01:00
Apr 23 18:26:28 lb01 vrrpd->lan[57143]: VRRP ID 42 on eno0 (prio: 100) : we are now a backup router.
Apr 23 18:26:59 lb01 vrrpd->lan[57143]: VRRP ID 42 on eno0 (prio: 100): we are now the master router.
2017-09-13 15:47:36 +02:00
~~~
2017-05-05 14:44:04 +02:00
Sur une autre machine, après avoir également ajusté les paramètres _sysctl_, on lance la même commande avec une priorité plus faible :
~~~
2023-11-17 16:35:54 +01:00
# vrrpd -i eth0 -x -D -d 10 -v 42 -p 90 -a pw/0xPASSWORD -l foo 192.0.2.10/27
2017-05-05 14:44:04 +02:00
~~~
Cette machine va rester en état _slave_ tant qu'elle capte des messages d'annonce de la machine _master_ :
2017-09-13 15:47:36 +02:00
~~~
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.
~~~
2017-05-05 14:44:04 +02:00
2023-11-17 16:35:54 +01:00
Pour changer la priorité du processus il suffit de tuer l'actuel et de relancer la commande avec la nouvelle priorité. Si ça doit être persistent, il faut modifier
#### systemd
On pourra utiliser une unité systemd pour gérer VRRP. On conseille d'avoir une unité pour chaque IP gérée, en utilisant le **VRID** comme élément différenciant.
2019-07-23 10:07:11 +02:00
~~~
2023-11-17 16:35:54 +01:00
# systemctl cat vrrp-42.service
# /etc/systemd/system/vrrp-42.service
2019-07-23 10:07:11 +02:00
[Unit]
2023-11-17 16:35:54 +01:00
Description=VRRP Daemon for IP 192.0.2.10/27 on eno0
2019-07-23 10:07:11 +02:00
After=network.target
[Service]
2023-11-17 16:35:54 +01:00
ExecStart=/usr/sbin/vrrpd -i eno0 -x -D -d 10 -v 42 -p 50 -a pw/0x6574432874316975 -l lan-2-10 192.0.2.10/27
# PIDFile=/var/run/vrrpd_lan-2-10_42.pid
2022-08-19 10:15:27 +02:00
Restart=on-failure
2022-08-19 11:27:57 +02:00
Type=forking
IgnoreSIGPIPE=no
KillMode=process
RemainAfterExit=yes
2019-07-23 10:07:11 +02:00
[Install]
WantedBy=default.target
~~~
2017-05-05 14:44:04 +02:00
2023-11-17 16:35:54 +01:00
Vous pouvez consulter l'état de l'IP :
~~~
# systemctl status vrrp-42
● vrrp-42.service - VRRP Daemon for IP 192.0.2.10/27 on eno0
Loaded: loaded (/etc/systemd/system/vrrp-42.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2023-11-09 22:43:03 CET; 1 weeks 0 days ago
Main PID: 542166 (vrrpd)
Tasks: 1 (limit: 76863)
Memory: 452.0K
CPU: 21.909s
CGroup: /system.slice/vrrp-42.service
└─542166 /usr/sbin/vrrpd -i eno0 -x -D -d 10 -v 42 -p 2 -a XXXXX -l lan-2-10 192.0.2.10 27
~~~
Vous pouvez gérer avec les commandes habituelles `start` et `stop`.
Vous pouvez consulter les logs via journald : `journalctl -u vrrp-42`
Pour avoir une vue instantanée d'une IP :
~~~
# cat /var/run/vrrpd/vrrp-lan-2-10
VRRP - lan-2-10
Group 42
State is slave
Virtual IP address is 192.0.2.10/27
~~~
Pour changer la priorité du processus il faut modifier l'unité systemd (généralement dans `/etc/systemd/system/vrrp-42.service`), puis `systemctl daemon-reload`, puis `systemctl restart vrrp-42.service`.
## Plomberie
Des paquets IP vont être émis sur l'interface choisie pour annoncer à intervalle régulier que l'on est en état *master*.
Par défaut ces paquets sont envoyés sur l'adresse IP de Multicast 224.0.0.18.
> Note : il est donc indispensable que l'interface sous-jacente ait une configuration IP valide.
Si une interface en état *slave* ne reçoit pas cette notification dans l'intervalle défini, elle va décider de passer *master*.
Sortie TCPDUMP d'un paquet VRRP émis par le *master* :
~~~
23:00:50.868137 IP (tos 0x0, ttl 255, id 3328, offset 0, flags [none], proto VRRP (112), length 40)
2023-11-17 16:35:54 +01:00
198.51.100.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 42, prio 90, authtype simple, intvl 10s, length 20, addrs: 192.0.2.10 auth "PASSWORD"
~~~
2017-05-05 12:09:19 +02:00
## Logs
2016-12-29 11:25:39 +01:00
2017-05-05 12:09:19 +02:00
* Des logs sont envoyés à syslog
2023-11-17 16:35:54 +01:00
* L'historique des changements d'états dans `/var/log/vrrpd/state.${vrid}`
* L'état courant se trouve dans `/var/run/vrrpd/vrrp-${instance_name}`
2017-05-05 12:09:19 +02:00
* Un fichier PID est dans `/var/run/vrrpd_${instance_name}_${vrid}.pid`
2017-09-13 15:47:36 +02:00
## Bascule d'un serveur à l'autre
2023-11-17 16:35:54 +01:00
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.
2022-09-07 11:36:53 +02:00
## 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)
2023-01-18 14:53:27 +01:00
```