Failover BGP et multihoming depuis deux VPS
Annoncez le même préfixe depuis deux emplacements avec BGP pour un failover automatique. Couvre LOCAL_PREF, MED, AS-path prepending, BFD et l'arrêt gracieux avec des configurations complètes BIRD2 et FRR.
Ce tutoriel explique comment annoncer le même préfixe IP depuis deux VPS distincts via BGP. Vous configurerez la préférence primaire/backup avec LOCAL_PREF et MED, activerez BFD pour une détection de panne en moins d'une seconde, et mettrez en place l'arrêt gracieux pour la maintenance planifiée. Tous les exemples présentent BIRD2 et FRR côte à côte.
Prérequis :
- Une session BGP fonctionnelle sur au moins un VPS (Configuration BGP avec BIRD2 sur un VPS Linux ou Configuration BGP avec FRRouting sur un VPS Linux)
- Votre propre ASN et au moins un préfixe /24 (IPv4) ou /48 (IPv6)
- Compréhension de base des communautés BGP (Communautés BGP : standard, large et extended)
Qu'est-ce que le multihoming BGP et pourquoi l'utiliser sur un VPS ?
Le multihoming BGP consiste à annoncer le même préfixe IP depuis deux emplacements ou plus via eBGP. Chaque emplacement maintient une session BGP indépendante avec son fournisseur en amont. Si un emplacement tombe en panne, l'autre continue d'annoncer le préfixe et absorbe automatiquement tout le trafic. Le temps de convergence dépend des hold timers (généralement 180 à 240 secondes avec les paramètres par défaut) ou de BFD (moins d'une seconde avec une configuration adaptée).
Sur un VPS, le multihoming offre de la redondance sans dépendre d'un seul centre de données. Vous faites tourner deux instances VPS dans des emplacements différents, les deux annonçant votre préfixe. L'une agit comme primaire, l'autre comme backup. Les attributs d'ingénierie de trafic (LOCAL_PREF, MED, AS-path prepending) contrôlent quel chemin gère le trafic en conditions normales.
Comment architecturer le failover BGP entre deux emplacements ?
Le dispositif utilise deux VPS Virtua dans des emplacements européens différents, chacun maintenant une session eBGP avec le routeur amont local. Les deux annoncent le même /24 et /48.
Internet
/ \
Upstream A Upstream B
(Frankfurt) (Amsterdam)
| |
eBGP session eBGP session
| |
+-----------+ +-----------+
| VPS-PRI | | VPS-BKP |
| AS 64500 | | AS 64500 |
| BIRD2/FRR | | BIRD2/FRR |
+-----------+ +-----------+
announces announces
198.51.100.0/24 198.51.100.0/24
2001:db8::/48 2001:db8::/48
Les deux nœuds appartiennent à votre AS (AS 64500 dans ces exemples). Remplacez l'ASN, les préfixes et les IP de peering par vos valeurs réelles.
Règles de pare-feu pour les deux nœuds :
BGP utilise le port TCP 179. BFD utilise les ports UDP 3784 et 3785. Ouvrez ces ports entre votre VPS et le pair amont avant de continuer.
# nftables example - adjust PEER_IP to your upstream
nft add rule inet filter input ip saddr PEER_IP tcp dport 179 accept
nft add rule inet filter input ip saddr PEER_IP udp dport { 3784, 3785 } accept
Comment contrôler la préférence de chemin BGP ?
Trois attributs permettent d'influencer le chemin emprunté par le trafic. Chacun opère à un niveau différent.
| Attribut | Direction | Portée | Envoyé aux pairs ? | Quand l'utiliser |
|---|---|---|---|---|
| LOCAL_PREF | Sortant (votre sortie) | Au sein de votre AS | Non (iBGP uniquement) | Contrôler quel nœud envoie le trafic sortant |
| MED | Entrant (depuis l'amont) | Entre vous et un AS amont | Oui (au voisin direct) | Indiquer à un amont quel point d'entrée préférer |
| AS-path prepending | Entrant (global) | Tous les AS du chemin | Oui (propagé) | Rendre un chemin plus long pour tout Internet |
LOCAL_PREF et MED sont précis. L'AS-path prepending est un outil grossier mais fonctionne quand vos emplacements sont connectés à des amonts différents.
Comment configurer LOCAL_PREF pour les chemins primaire et backup ?
LOCAL_PREF détermine quel chemin de sortie votre AS préfère pour le trafic sortant. La valeur la plus élevée gagne. La valeur par défaut est 100. Mettez 200 sur le nœud primaire et laissez 100 sur le backup. Cela n'affecte que le trafic quittant votre réseau.
Configuration LOCAL_PREF avec BIRD2
Sur le nœud primaire (VPS-PRI), créez ou modifiez le filtre d'import :
# /etc/bird/bird.conf - Primary node
filter upstream_import_primary {
bgp_local_pref = 200;
accept;
}
protocol bgp upstream_v4 {
local 192.0.2.2 as 64500;
neighbor 192.0.2.1 as 64496;
ipv4 {
import filter upstream_import_primary;
export where net = 198.51.100.0/24;
};
}
protocol bgp upstream_v6 {
local 2001:db8:1::2 as 64500;
neighbor 2001:db8:1::1 as 64496;
ipv6 {
import filter upstream_import_primary;
export where net = 2001:db8::/48;
};
}
Sur le nœud backup (VPS-BKP), gardez le LOCAL_PREF par défaut :
# /etc/bird/bird.conf - Backup node
filter upstream_import_backup {
bgp_local_pref = 100;
accept;
}
protocol bgp upstream_v4 {
local 203.0.113.2 as 64500;
neighbor 203.0.113.1 as 64497;
ipv4 {
import filter upstream_import_backup;
export where net = 198.51.100.0/24;
};
}
Rechargez BIRD2 et vérifiez les routes :
birdc configure
birdc show route for 0.0.0.0/0 all
0.0.0.0/0 unicast [upstream_v4 12:00:00] * (100/?) [AS64496i]
via 192.0.2.1 on eth0
Type: BGP univ
BGP.origin: IGP
BGP.as_path: 64496
BGP.local_pref: 200
La valeur BGP.local_pref: 200 sur le nœud primaire signifie qu'il sera préféré pour le trafic sortant.
Configuration LOCAL_PREF avec FRR
Sur le nœud primaire :
vtysh -c "configure terminal
route-map UPSTREAM-IN permit 10
set local-preference 200
exit
router bgp 64500
neighbor 192.0.2.1 remote-as 64496
address-family ipv4 unicast
neighbor 192.0.2.1 route-map UPSTREAM-IN in
network 198.51.100.0/24
exit-address-family
neighbor 2001:db8:1::1 remote-as 64496
address-family ipv6 unicast
neighbor 2001:db8:1::1 route-map UPSTREAM-IN in
network 2001:db8::/48
exit-address-family
exit
exit"
Sur le nœud backup, mettez set local-preference 100 (ou omettez la route-map puisque 100 est la valeur par défaut).
Vérifiez la table de routage :
vtysh -c "show ip bgp"
Network Next Hop Metric LocPrf Weight Path
*> 0.0.0.0/0 192.0.2.1 200 0 64496 i
Comment utiliser MED pour contrôler le trafic entrant ?
MED (Multi-Exit Discriminator) indique à votre amont quel point d'entrée préférer. La valeur la plus basse gagne. Mettez MED 0 sur le primaire et MED 100 sur le backup. MED n'est comparé qu'entre les chemins reçus du même AS voisin, il fonctionne donc mieux quand les deux emplacements sont connectés au même fournisseur amont.
Configuration MED avec BIRD2
Sur le nœud primaire, définissez MED dans le filtre d'export :
filter upstream_export_primary {
if net = 198.51.100.0/24 || net = 2001:db8::/48 then {
bgp_med = 0;
accept;
}
reject;
}
protocol bgp upstream_v4 {
local 192.0.2.2 as 64500;
neighbor 192.0.2.1 as 64496;
ipv4 {
import filter upstream_import_primary;
export filter upstream_export_primary;
};
}
Sur le nœud backup :
filter upstream_export_backup {
if net = 198.51.100.0/24 || net = 2001:db8::/48 then {
bgp_med = 100;
accept;
}
reject;
}
Configuration MED avec FRR
Sur le nœud primaire :
vtysh -c "configure terminal
route-map UPSTREAM-OUT permit 10
set metric 0
exit
router bgp 64500
address-family ipv4 unicast
neighbor 192.0.2.1 route-map UPSTREAM-OUT out
exit-address-family
exit
exit"
Sur le nœud backup, utilisez set metric 100.
Vérifiez les routes exportées :
vtysh -c "show ip bgp neighbors 192.0.2.1 advertised-routes"
Network Next Hop Metric LocPrf Weight Path
*> 198.51.100.0/24 0.0.0.0 0 32768 i
La colonne Metric affiche 0 sur le primaire. Le backup affichera 100.
Quand utiliser l'AS-path prepending au lieu de MED ?
Utilisez l'AS-path prepending quand vos deux emplacements sont connectés à des fournisseurs amont différents. MED n'est comparé qu'entre les chemins du même AS, il n'a donc aucun effet si vos amonts sont des AS différents. Le prepending allonge artificiellement le chemin du backup, orientant les décisions de routage globales vers le primaire.
Ajoutez votre propre ASN 1 à 3 fois sur le nœud backup. Plus de 3 prepends change rarement les décisions de routage et ne fait qu'ajouter du bruit.
BIRD2 (filtre d'export du nœud backup) :
filter upstream_export_backup_prepend {
if net = 198.51.100.0/24 || net = 2001:db8::/48 then {
bgp_path.prepend(64500);
bgp_path.prepend(64500);
accept;
}
reject;
}
FRR (nœud backup) :
vtysh -c "configure terminal
route-map UPSTREAM-OUT permit 10
set as-path prepend 64500 64500
exit
exit"
Après application, vérifiez l'AS path depuis un looking glass ou une machine distante :
# From an external machine
traceroute -A 198.51.100.1
Le chemin backup affiche maintenant 64500 64500 64500 (votre ASN apparait trois fois : une fois réel, deux fois ajouté) tandis que le primaire affiche 64500 une seule fois.
Comment activer BFD pour une détection rapide des pannes ?
Sans BFD, BGP repose sur les hold timers pour détecter une panne du pair. Le hold time par défaut est de 240 secondes dans BIRD2 et 180 secondes dans FRR. Avec BFD, la détection passe en dessous de la seconde sur les liens à faible latence.
| Paramètre | Par défaut | Recommandé pour VPS |
|---|---|---|
| Intervalle d'émission | 300 ms | 300 ms |
| Intervalle de réception | 300 ms | 300 ms |
| Multiplicateur de détection | 3 | 3 |
| Temps de détection effectif | 900 ms | 900 ms |
Pour les environnements VPS sur le même backbone, des intervalles de 300 ms avec un multiplicateur de 3 offrent une détection fiable en moins d'une seconde sans faux positifs. Ne descendez pas en dessous de 100 ms sur des instances VPS. La gigue de virtualisation peut provoquer du flapping.
Configuration BFD avec BIRD2
Ajoutez un protocole BFD et activez-le sur la session BGP :
protocol bfd {
interface "*" {
min rx interval 300 ms;
min tx interval 300 ms;
multiplier 3;
};
}
protocol bgp upstream_v4 {
local 192.0.2.2 as 64500;
neighbor 192.0.2.1 as 64496;
bfd graceful;
ipv4 {
import filter upstream_import_primary;
export filter upstream_export_primary;
};
}
L'option bfd graceful signifie que BIRD2 déclenchera un redémarrage gracieux (en conservant les routes obsolètes) plutôt qu'une réinitialisation brutale de la session quand BFD détecte une panne. Si le pair n'utilise pas BFD, la session s'établit normalement.
Après le rechargement, vérifiez l'état BFD :
birdc show bfd sessions
BFD sessions:
IP address Interface State Since Interval Timeout
192.0.2.1 eth0 Up 12:00:00 300 ms 900 ms
Configuration BFD avec FRR
vtysh -c "configure terminal
bfd
profile vps-detect
receive-interval 300
transmit-interval 300
detect-multiplier 3
exit
exit
router bgp 64500
neighbor 192.0.2.1 bfd profile vps-detect
neighbor 2001:db8:1::1 bfd profile vps-detect
exit
exit"
Vérifiez l'état du pair BFD :
vtysh -c "show bfd peers"
BFD Peers:
peer 192.0.2.1 vrf default
ID: 1
Remote ID: 2
Status: up
Uptime: 5 minute(s)
Diagnostics: ok
Remote diagnostics: ok
Peer Type: configured
Local timers:
Receive interval: 300ms
Transmission interval: 300ms
Echo receive interval: disabled
Echo transmission interval: disabled
Peer timers:
Receive interval: 300ms
Transmission interval: 300ms
Echo receive interval: disabled
BFD nécessite que les ports UDP 3784 et 3785 soient ouverts entre les pairs. Si vous avez sauté l'étape du pare-feu, les sessions BFD resteront à l'état Down.
Comment effectuer un arrêt gracieux pour la maintenance ?
La RFC 8326 définit la communauté bien connue GRACEFUL_SHUTDOWN (65535:0). Avant une maintenance planifiée, vous marquez toutes les routes avec cette communauté. Les pairs qui la respectent fixent la local-preference à 0 pour ces routes, ce qui redirige le trafic vers les chemins alternatifs avant l'arrêt de la session. Cela évite le trou noir de trafic qui survient pendant la convergence BGP normale.
La procédure d'arrêt gracieux :
- Marquez les routes avec la communauté GRACEFUL_SHUTDOWN sur le nœud que vous allez arrêter
- Attendez la convergence (30 à 60 secondes pour qu'Internet reroute le trafic)
- Vérifiez que le trafic a basculé via un looking glass ou des compteurs de trafic
- Arrêtez la session BGP
- Effectuez la maintenance
- Rétablissez la session et retirez la communauté
- Confirmez la re-convergence
Arrêt gracieux avec BIRD2
Pour initier l'arrêt gracieux sur le nœud primaire avant la maintenance, modifiez le filtre d'export :
# Temporary export filter for graceful shutdown
filter upstream_export_shutdown {
if net = 198.51.100.0/24 || net = 2001:db8::/48 then {
bgp_community.add((65535, 0));
bgp_med = 65535;
accept;
}
reject;
}
Appliquez-le en changeant le filtre d'export dans le protocole BGP et en rechargeant :
# Edit bird.conf: change export filter to upstream_export_shutdown
# Then reload
birdc configure
Pour honorer l'arrêt gracieux des pairs (appliquez ceci sur les deux nœuds), ajoutez une vérification dans le filtre d'import. L'ordre est important : la vérification de l'arrêt gracieux doit appeler accept dans le bloc if, sinon une assignation ultérieure de bgp_local_pref l'écrasera.
filter upstream_import_backup {
if (65535, 0) ~ bgp_community then {
bgp_local_pref = 0;
accept;
}
bgp_local_pref = 100;
accept;
}
Arrêt gracieux avec FRR
FRR fournit une commande unique qui gère le marquage automatiquement :
vtysh -c "configure terminal
router bgp 64500
bgp graceful-shutdown
exit
exit"
Cela ajoute la communauté GRACEFUL_SHUTDOWN (65535:0) à toutes les routes et fixe la local-preference à 0. Un rafraichissement des routes est déclenché vers tous les pairs.
Pour confirmer que la communauté est envoyée :
vtysh -c "show ip bgp neighbors 192.0.2.1 advertised-routes"
Network Next Hop Metric LocPrf Weight Path
*> 198.51.100.0/24 0.0.0.0 0 0 32768 i
Community: graceful-shutdown
Après la maintenance, retirez-la :
vtysh -c "configure terminal
router bgp 64500
no bgp graceful-shutdown
exit
exit"
Pour que FRR honore l'arrêt gracieux des pairs, configurez une route-map en entrée :
vtysh -c "configure terminal
bgp community-list standard GRACEFUL_SHUTDOWN permit graceful-shutdown
route-map UPSTREAM-IN permit 5
match community GRACEFUL_SHUTDOWN
set local-preference 0
exit
route-map UPSTREAM-IN permit 10
set local-preference 200
exit
exit"
La séquence 5 correspond aux routes portant la communauté et abaisse la local-preference à 0. La séquence 10 traite normalement toutes les autres routes.
Comment tester le failover BGP ?
Testez le failover en arrêtant la session BGP primaire et en observant depuis le nœud backup et un point de vue externe.
Étape 1 : Vérifiez l'état de routage actuel sur les deux nœuds.
BIRD2 :
birdc show route for 198.51.100.0/24 all
FRR :
vtysh -c "show ip bgp 198.51.100.0/24"
Étape 2 : Arrêtez la session BGP primaire.
BIRD2 (sur VPS-PRI) :
birdc disable upstream_v4
birdc disable upstream_v6
FRR (sur VPS-PRI) :
vtysh -c "configure terminal
router bgp 64500
neighbor 192.0.2.1 shutdown
neighbor 2001:db8:1::1 shutdown
exit
exit"
Étape 3 : Observez le nœud backup.
Sur VPS-BKP, la route devrait maintenant apparaitre comme le seul chemin :
# BIRD2
birdc show route for 198.51.100.0/24
# FRR
vtysh -c "show ip bgp summary"
Étape 4 : Testez depuis l'extérieur.
Depuis votre machine locale ou un looking glass, faites un traceroute vers votre préfixe :
traceroute -A 198.51.100.1
Le trafic devrait maintenant entrer par l'emplacement backup. Avec BFD activé, le basculement se fait en moins d'une seconde. Sans BFD, comptez la durée complète du hold timer avant la convergence.
| Méthode de détection | Temps de failover typique |
|---|---|
| Hold timer BGP seul (BIRD2 par défaut 240 s) | 160-240 s |
| Hold timer BGP seul (FRR par défaut 180 s) | 120-180 s |
| Hold timer réduit (par ex. 30 s) | 20-30 s |
| BFD (intervalles de 300 ms, multiplicateur 3) | < 1 s |
Utilisez NLNOG Looking Glass ou bgp.tools pour confirmer la convergence du routage global.
Comment rétablir le service après un failover ?
Rétablissez la session primaire et confirmez que le trafic revient sur le chemin préféré.
BIRD2 :
birdc enable upstream_v4
birdc enable upstream_v6
FRR :
vtysh -c "configure terminal
router bgp 64500
no neighbor 192.0.2.1 shutdown
no neighbor 2001:db8:1::1 shutdown
exit
exit"
Après quelques secondes, vérifiez que le chemin primaire est de nouveau préféré :
# BIRD2
birdc show route for 0.0.0.0/0 all | grep local_pref
BGP.local_pref: 200
# FRR
vtysh -c "show ip bgp"
Network Next Hop Metric LocPrf Weight Path
*> 0.0.0.0/0 192.0.2.1 200 0 64496 i
Relancez un traceroute depuis un hôte externe pour confirmer que le trafic entre de nouveau par l'emplacement primaire.
Comparaison des configurations BIRD2 et FRR
| Fonctionnalité | BIRD2 | FRR |
|---|---|---|
| LOCAL_PREF | bgp_local_pref = 200; dans le filtre d'import |
set local-preference 200 dans la route-map |
| MED | bgp_med = 0; dans le filtre d'export |
set metric 0 dans la route-map |
| AS-path prepend | bgp_path.prepend(64500); dans le filtre d'export |
set as-path prepend 64500 dans la route-map |
| BFD | protocol bfd {} + bfd graceful; dans BGP |
section bfd + neighbor X bfd profile Y |
| Arrêt gracieux (initier) | Ajouter (65535, 0) à bgp_community dans le filtre d'export |
bgp graceful-shutdown sous router bgp |
| Arrêt gracieux (honorer) | Vérifier (65535, 0) ~ bgp_community dans le filtre d'import, fixer bgp_local_pref = 0 |
match community GRACEFUL_SHUTDOWN dans la route-map, set local-preference 0 |
| Désactiver une session | birdc disable <protocol> |
neighbor X shutdown |
| Recharger la config | birdc configure |
write memory puis clear ip bgp * ou redémarrage |
Surveillance des événements de failover
Mettez en place une surveillance pour recevoir des alertes en cas de basculement. Surveiller les annonces BGP avec BGPalerter sur Linux couvre BGPalerter pour la surveillance des routes. Au minimum, surveillez :
- Les changements d'état des sessions BGP :
journalctl -u birdoujournalctl -u frr - Les flaps des sessions BFD :
birdc show bfd sessions/vtysh -c "show bfd peers" - Les changements du nombre de routes : alertez si le nombre de préfixes exportés tombe à zéro
Dépannage
Session BGP bloquée à l'état Active/Connect :
- Vérifiez les règles de pare-feu pour le port TCP 179
- Vérifiez que l'IP du pair et l'ASN correspondent à ce qu'attend votre amont
- Consultez
journalctl -u bird -foujournalctl -u frr -fpour les messages d'erreur
Session BFD bloquée à l'état Down :
- Les ports UDP 3784 et 3785 doivent être ouverts dans les deux sens
- Confirmez que le pair supporte BFD et l'a configuré
- Vérifiez les problèmes de MTU sur le chemin
MED n'affecte pas le trafic entrant :
- MED n'est comparé qu'entre les chemins du même AS. Si vos amonts sont des AS différents, utilisez l'AS-path prepending à la place
- Certains amonts ignorent MED par politique. Demandez à votre fournisseur
La communauté de l'arrêt gracieux n'est pas honorée :
- Le pair doit explicitement supporter la RFC 8326. Tous les amonts ne le font pas
- Vérifiez auprès de votre fournisseur s'il honore la communauté GRACEFUL_SHUTDOWN
- Certaines implémentations nécessitent une configuration explicite pour respecter la communauté
Le trafic ne bascule pas :
- Vérifiez que les deux nœuds annoncent le même préfixe avec
birdc show route export upstream_v4ouvtysh -c "show ip bgp neighbors X advertised-routes" - Vérifiez depuis un looking glass externe, pas depuis les nœuds eux-mêmes
- Le TTL DNS peut maintenir les clients dirigés vers l'ancienne IP si vous utilisez des IP par emplacement pour les services au-dessus du préfixe anycast