
Keepalived 2.4.0 introduit une extension d’authentification HMAC pour VRRP qui resout le maillon faible du protocole en unicast : l’absence de verification cryptographique des adverts. Le bloc auth_hmac ajoute un trailer HMAC-SHA256 (tronque a 128 bits) et un numero de sequence temporel a chaque advert. La cle est partagee entre les pairs (32 octets minimum, 64 max), et le mode anti_replay time necessite des horloges synchronisees (NTP). Le deploiement se fait en douceur via mode permissive puis enforce.
TL;DR
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 200
advert_int 1
unicast_src_ip 198.51.100.10
unicast_peer { 192.0.2.10 }
auth_hmac {
key 1 hex:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
active_key 1
anti_replay time
time_window 5
}
virtual_ipaddress { 192.0.2.100/32 }
}Langage du code : PHP (php)
VRRP HMAC Authentication : c’est quoi exactement ?
L’extension auth_hmac est un bloc de configuration propre a Keepalived, defini dans l’instance VRRP (vrrp_instance). Elle ajoute un trailer de 28 octets a chaque advert VRRP contenant :
- un HMAC-SHA256 tronque a 128 bits (16 octets) qui prouve que l’advert a ete emis par un detenteur de la cle partagee et n’a pas ete modifie
- un numero de sequence temporel (64 bits, horodatage dans les 48 bits hauts + compteur 16 bits) qui garantit la fraicheur et empeche le rejeu
- un identifiant de cle (
key_id) qui permet la rotation de cles sans interruption de service
Le HMAC lie dans son pseudo-header l’adresse source, la famille d’adresses, la version VRRP et le VRID. Cela empeche le rejeu d’un trailer valide sur une autre instance ou un autre expediteur. L’en-tete IP n’entre pas dans le calcul, ce qui rend le design independant du mode de transport (IPv4/IPv6, unicast/multicast).
Le code source de l’implementation se trouve dans le fichier keepalived/vrrp/vrrp_auth_hmac.c du depot officiel.
Le vrai probleme que VRRP HMAC resout
Le protocole VRRP standard (RFC 5798 pour v3) ne connait qu’une seule forme d’authentification : le TTL guard.
Un routeur actif envoie chaque advert avec un TTL (ou hop limit en IPv6) de 255. Le recepteur droppe tout paquet qui arrive avec un TTL inferieur, ce qui prouve que le paquet n’a jamais traverse de routeur. C’est le Generalized TTL Security Mechanism (GTSM, RFC 5082). Cette protection fonctionne tant que les adverts restent sur un seul segment L2.
Le probleme arrive avec l’unicast. Dans un cloud ou un overlay (VXLAN, VPN, etc.), le multicast n’est pas disponible. Keepalived envoie alors les adverts en unicast route vers une liste de peers configuree. Les paquets traversent des routeurs, leur TTL est decremente, et ils arrivent bien en dessous de 255. Le recepteur doit relacher le check TTL pour les accepter.
Une fois ce verrou tombe, n’importe quel attaquant capable d’envoyer un paquet spoofe vers le recepteur peut :
- injecter un advert avec une priorite plus elevee pour demouer le master
- injecter un advert priorite 0 pour forcer une election
- rejouer un advert capture pour maintenir un etat falsifie
Le bloc authentication { auth_type PASS } historique ne resout rien : le mot de passe circule en clair dans l’advert (c’est pourquoi la RFC 3768 l’a retire). L’option IPSEC-AH n’a jamais existe que pour VRRPv2.
L’extension auth_hmac ferme toutes ces failles : le HMAC prouve l’identite de l’emetteur, le numero de sequence prouve la fraicheur, et rien ne circule en clair.
ACTIVE --- advert (VRID 51, prio 200) ---> BACKUP
198.51.100.10 192.0.2.10
^
| spoofed advert: src = 192.0.2.10, prio 255
ATTACKER
203.0.113.9
Sans auth_hmac, un attaquant qui peut atteindre le backup peut usurper l’identite du master. Avec auth_hmac, l’advert spoofe est rejete car le HMAC ne correspond pas.
Le modele mental minimal
Pour comprendre auth_hmac, voici les 5 concepts a retenir :
- Cle partagee : tous les noeuds d’un meme routeur virtuel partagent les memes cles (construction symetrique). Il n’y a pas d’echange de cle sur le fil.
- HMAC-SHA256 tronque : le HMAC est calcule sur le pseudo-header + l’advert, tronque a 128 bits. Cela suffit pour la securite et minimise l’impact sur la taille du paquet.
- Sequence temporelle : le numero de sequence integre l’horodatage UNIX (secondes + fraction). Le recepteur verifie que l’advert est dans la fenetre de fraicheur configurable.
- Mode permissive/enforce :
permissiveaccepte les adverts sans trailer (pour la migration),enforceles rejette. Le defaut estenforce. - Rotation de cles : on peut definir plusieurs cles avec des IDs distincts. L’
active_keydesigne celle utilisee pour signer. Le recepteur accepte n’importe quelle cle configuree, ce qui permet une rotation sans coupure (make-before-break).
Ou auth_hmac brille vraiment
| Contexte | Pourquoi auth_hmac est pertinent |
|---|---|
| Cloud public (AWS, GCP, Azure, Infomaniak) | Le multicast n’est pas disponible, unicast obligatoire |
| Overlay VXLAN / VPN / Wireguard | Les adverts traversent des tunnels, TTL decremente |
| Datacenter multi-sites | Les noeuds VRRP sont separes par des routeurs L3 |
| Clusters Kubernetes (kubeadm + HAProxy + Keepalived) | Les adverts passent par le reseau overlay |
| Environnements multi-locations | Protection contre les attaquants sur le meme hyperviseur |
Dans tous ces cas, sans auth_hmac, un attaquant local peut declencher une election et prendre le role master. Avec auth_hmac, il faudrait posseder la cle partagee (32 octets aleatoires generes par openssl rand -hex 32).
Commandes et premier setup
Generer une cle
openssl rand -hex 32
Cette commande produit 32 octets aleatoires (64 caracteres hex), ce qui donne une marge de 128 bits meme contre une recherche quantique (la recherche quantique ne divise que la force effective par 2).
Configuration minimale
Sur le master (198.51.100.10) :
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 200
advert_int 1
unicast_src_ip 198.51.100.10
unicast_peer {
192.0.2.10
}
auth_hmac {
key 1 hex:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
active_key 1
anti_replay time
time_window 5
}
virtual_ipaddress {
192.0.2.100/32
}
}Langage du code : PHP (php)
Sur le backup (192.0.2.10), meme auth_hmac mais state BACKUP, priority 100 et adresses inversees.
Cle depuis un fichier
Pour eviter que la cle ne soit visible dans keepalived.conf :
key 1 file:/etc/keepalived/keys/vrrp51Langage du code : JavaScript (javascript)
Le fichier doit etre root:root et mode 0600. Keepalived emet un avertissement si le fichier est lisible par le groupe ou les autres.
Cle depuis une credential systemd chiffree
La methode la plus robuste consiste a utiliser systemd-creds pour chiffrer la cle avec le TPM ou la cle de la machine :
umask 077
install -d /etc/keepalived/creds
printf 'hex:%s' "$(openssl rand -hex 32)" > /run/vrrp51.plain
systemd-creds encrypt --name=vrrp51 \
/run/vrrp51.plain /etc/keepalived/creds/vrrp51.cred
shred -u /run/vrrp51.plainLangage du code : JavaScript (javascript)
Ajouter un drop-in systemd (/etc/systemd/system/keepalived.service.d/auth_hmac.conf) :
[Service]
LoadCredentialEncrypted=vrrp51:/etc/keepalived/creds/vrrp51.credLangage du code : JavaScript (javascript)
Dans keepalived.conf :
auth_hmac {
key 1 file:${_ENV CREDENTIALS_DIRECTORY}/vrrp51
active_key 1
}
Un exemple complet est fourni dans le depot officiel : doc/samples/keepalived.service.d.auth_hmac.conf.
Migration sans interruption
- Mettre a jour le binaire Keepalived sur tous les noeuds (sans changer la config)
- Ajouter
auth_hmac { }avecmode permissivepartout, reloader en vague rapide - Verifier que les adverts signes circulent (logs)
- Passer
mode enforcepartout et reloader
Rotation de cle
key 1 file:/etc/keepalived/keys/vrrp51
key 2 file:/etc/keepalived/keys/vrrp51.new
active_key 1Langage du code : JavaScript (javascript)
- Ajouter la cle 2 sur tous les noeuds, reloader (la cle 1 reste active)
- Basculer
active_key 2sur tous les noeuds, reloader - Supprimer la cle 1, reloader
Tableau de reference de la configuration
| Mot-cle | Valeurs | Defaut | Notes |
|---|---|---|---|
key <id> <value> | id 1-255; hex:, ASCII, file: | requis | 32 a 64 octets |
active_key <id> | 1-255 | requis | ID utilise pour signer |
anti_replay | time ou monotonic | time | time necessite NTP |
time_window <sec> | 1-300 | max(3 x advert_int, 5) | fenetre de fraicheur |
mode | enforce ou permissive | enforce | permissive pour migration |
Liens utiles
- Article officiel sur keepalived.org : VRRP HMAC Authentication
- Depot GitHub Keepalived : https://github.com/acassen/keepalived
- Code source de l’extension :
keepalived/vrrp/vrrp_auth_hmac.c - Configuration sample :
doc/samples/keepalived.conf.vrrp - Drop-in systemd pour credentials :
doc/samples/keepalived.service.d.auth_hmac.conf keepalived.conf(5): https://www.keepalived.org/documentation/keepalived-conf/- IETF Internet-Draft : draft-cassen-vrrp-auth-hmac
- Groupe d’utilisateurs Keepalived : https://groups.io/g/keepalived-users
- RFC 5798 (VRRPv3) : https://datatracker.ietf.org/doc/rfc5798/
- RFC 5082 (GTSM) : https://datatracker.ietf.org/doc/rfc5082/
FAQ
auth_hmac est-il compatible avec VRRPv2 et VRRPv3 ?
Oui. L’extension fonctionne avec VRRPv2 et v3, IPv4 et IPv6, unicast et multicast.
Quelle taille de cle choisir ?
32 octets (256 bits) est le bon defaut. La recherche quantique de Grover ne divise la force effective que par 2, donc 32 octets conservent une marge de 128 bits.
Le bloc auth_hmac et le bloc authentication sont-ils compatibles ?
Non, ils sont mutuellement exclusifs. Si les deux apparaissent, Keepalived ignore le bloc legacy authentication.
Que se passe-t-il si les horloges ne sont pas synchronisees ?
Avec anti_replay time, les adverts peuvent etre rejetes comme stales si le decalage depasse time_window. Keepalived emet un avertissement de clock skew quand le decalage depasse la moitie de la fenetre. Solution : utiliser NTP ou passer en anti_replay monotonic (qui ne necessite pas d’horloge commune).
Le trailer augmente-t-il la taille des adverts ?
Oui, 28 octets par advert. Keepalived reserve cet espace et peut deplacer quelques adresses virtuelles vers l’ensemble exclu si l’instance est proche de la MTU.
auth_hmac chiffre-t-il les adverts ?
Non. Les adverts VRRP ne sont pas secrets. L’extension ne fait que signer et dater : le HMAC prouve l’integrite et l’identite, la sequence prouve la fraicheur.
Peut-on utiliser plusieurs cles pour la rotation ?
Oui, jusqu’a 255 IDs de cle. Toutes sont acceptees en reception, une seule (active_key) est utilisee pour la signature. Cela permet une rotation make-before-break.
Que disent les logs en cas d’echec ?
Keepalived logue et compte chaque resultat d’authentification par instance : missing trailer (permis en permissive), invalid HMAC (cle differente ou falsification), stale trailer (rejeu ou clock skew). Les messages sont rates limites.
Conclusion
L’extension auth_hmac de Keepalived comble un trou de securite majeur du protocole VRRP en unicast. La configuration est simple, le deploiement peut etre progressif via mode permissive, et la rotation de cles se fait sans interruption. Dans un monde ou le cloud et les overlays sont la norme, il n’y a plus de raison de deployer Keepalived en unicast sans cette protection. La documentation officielle et le depot fournissent tous les elements pour une mise en oeuvre en production, y compris l’integration avec les credentials systemd chiffrees.