Failover BGP e multihoming da due VPS
Annuncia lo stesso prefisso da due posizioni con BGP per il failover automatico. Copre LOCAL_PREF, MED, AS-path prepending, BFD e graceful shutdown con configurazioni complete per BIRD2 e FRR.
Questo tutorial spiega come annunciare lo stesso prefisso IP da due VPS separati tramite BGP. Configurerai la preferenza primario/backup con LOCAL_PREF e MED, abiliterai BFD per il rilevamento guasti in meno di un secondo e implementerai il graceful shutdown per la manutenzione pianificata. Tutti gli esempi mostrano BIRD2 e FRR affiancati.
Prerequisiti:
- Una sessione BGP funzionante su almeno un VPS (Configurazione BGP con BIRD2 su VPS Linux o Configurazione BGP con FRRouting su un VPS Linux)
- Il tuo ASN e almeno un prefisso /24 (IPv4) o /48 (IPv6)
- Conoscenza di base delle community BGP (BGP Communities: standard, large ed extended)
Cos'è il multihoming BGP e perché usarlo su un VPS?
Il multihoming BGP significa annunciare lo stesso prefisso IP da due o più posizioni tramite eBGP. Ogni posizione mantiene una sessione BGP indipendente con il proprio provider upstream. Se una posizione si guasta, l'altra continua ad annunciare il prefisso e assorbe automaticamente tutto il traffico. Il tempo di convergenza dipende dagli hold timer (tipicamente 180-240 secondi con le impostazioni predefinite) o da BFD (sotto il secondo con configurazione corretta).
Su un VPS, il multihoming offre ridondanza senza dipendere da un singolo data center. Esegui due istanze VPS in posizioni diverse, entrambe che annunciano il tuo prefisso. Una funge da primaria, l'altra da backup. Gli attributi di traffic engineering (LOCAL_PREF, MED, AS-path prepending) controllano quale percorso gestisce il traffico in condizioni normali.
Come si progetta il failover BGP tra due posizioni?
Il setup utilizza due VPS Virtua in posizioni europee diverse, ciascuno con una sessione eBGP verso il router upstream locale. Entrambi annunciano lo stesso /24 e /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
Entrambi i nodi appartengono al tuo AS (AS 64500 in questi esempi). Sostituisci ASN, prefissi e IP di peering con i tuoi valori reali.
Regole firewall per entrambi i nodi:
BGP usa la porta TCP 179. BFD usa le porte UDP 3784 e 3785. Apri queste porte tra il tuo VPS e il peer upstream prima di procedere.
# 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
Come si controlla la preferenza di percorso BGP?
Tre attributi permettono di influenzare quale percorso segue il traffico. Ognuno opera a un livello diverso.
| Attributo | Direzione | Ambito | Inviato ai peer? | Quando usarlo |
|---|---|---|---|---|
| LOCAL_PREF | Uscita (la tua uscita) | All'interno del tuo AS | No (solo iBGP) | Controllare quale nodo invia il traffico in uscita |
| MED | Ingresso (dall'upstream) | Tra te e un AS upstream | Sì (al vicino diretto) | Indicare a un upstream quale punto di ingresso preferire |
| AS-path prepending | Ingresso (globale) | Tutti gli AS nel percorso | Sì (propagato) | Far apparire un percorso più lungo a tutta Internet |
LOCAL_PREF e MED sono precisi. L'AS-path prepending è uno strumento grossolano ma funziona quando le tue posizioni sono connesse a upstream diversi.
Come si configura LOCAL_PREF per i percorsi primario e backup?
LOCAL_PREF determina quale percorso di uscita preferisce il tuo AS per il traffico in uscita. Il valore più alto vince. Il valore predefinito è 100. Imposta 200 sul nodo primario e lascia 100 sul backup. Questo influisce solo sul traffico che lascia la tua rete.
Configurazione LOCAL_PREF con BIRD2
Sul nodo primario (VPS-PRI), crea o modifica il filtro di 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;
};
}
Sul nodo backup (VPS-BKP), mantieni il LOCAL_PREF predefinito:
# /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;
};
}
Ricarica BIRD2 e controlla le rotte:
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
Il valore BGP.local_pref: 200 sul nodo primario significa che sarà preferito per il traffico in uscita.
Configurazione LOCAL_PREF con FRR
Sul nodo primario:
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"
Sul nodo backup, imposta set local-preference 100 (o ometti la route-map dato che 100 è il valore predefinito).
Controlla la tabella di routing:
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
Come si usa MED per controllare il traffico in ingresso?
MED (Multi-Exit Discriminator) indica al tuo upstream quale punto di ingresso preferire. Il valore più basso vince. Imposta MED 0 sul primario e MED 100 sul backup. MED viene confrontato solo tra percorsi ricevuti dallo stesso AS vicino, quindi funziona meglio quando entrambe le posizioni fanno peering con lo stesso provider upstream.
Configurazione MED con BIRD2
Sul nodo primario, imposta MED nel filtro di 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;
};
}
Sul nodo backup:
filter upstream_export_backup {
if net = 198.51.100.0/24 || net = 2001:db8::/48 then {
bgp_med = 100;
accept;
}
reject;
}
Configurazione MED con FRR
Sul nodo primario:
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"
Sul nodo backup, usa set metric 100.
Controlla le rotte esportate:
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 colonna Metric mostra 0 sul primario. Il backup mostrerà 100.
Quando usare AS-path prepending invece di MED?
Usa l'AS-path prepending quando le tue due posizioni sono connesse a provider upstream diversi. MED viene confrontato solo tra percorsi dello stesso AS, quindi non ha effetto se i tuoi upstream sono AS diversi. Il prepending fa apparire il percorso del backup più lungo, orientando le decisioni di routing globali verso il primario.
Aggiungi il tuo ASN da 1 a 3 volte sul nodo backup. Più di 3 prepend raramente cambia le decisioni di routing e aggiunge solo rumore.
BIRD2 (filtro di export del nodo 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 (nodo backup):
vtysh -c "configure terminal
route-map UPSTREAM-OUT permit 10
set as-path prepend 64500 64500
exit
exit"
Dopo l'applicazione, controlla l'AS path da un looking glass o un host remoto:
# From an external machine
traceroute -A 198.51.100.1
Il percorso del backup ora mostra 64500 64500 64500 (il tuo ASN appare tre volte: una reale, due aggiunte) mentre il primario mostra 64500 una sola volta.
Come si abilita BFD per il rilevamento rapido dei guasti?
Senza BFD, BGP si affida agli hold timer per rilevare un guasto del peer. L'hold time predefinito è di 240 secondi in BIRD2 e 180 secondi in FRR. Con BFD, il rilevamento scende sotto il secondo su link a bassa latenza.
| Parametro | Predefinito | Raccomandato per VPS |
|---|---|---|
| Intervallo di trasmissione | 300 ms | 300 ms |
| Intervallo di ricezione | 300 ms | 300 ms |
| Moltiplicatore di rilevamento | 3 | 3 |
| Tempo di rilevamento effettivo | 900 ms | 900 ms |
Per ambienti VPS sullo stesso backbone del provider, intervalli di 300 ms con moltiplicatore 3 garantiscono un rilevamento affidabile sotto il secondo senza falsi positivi. Non scendere sotto i 100 ms su istanze VPS. Il jitter della virtualizzazione può causare flapping.
Configurazione BFD con BIRD2
Aggiungi un protocollo BFD e abilitalo sulla sessione 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'opzione bfd graceful significa che BIRD2 attiverà un graceful restart (conservando le rotte obsolete) anziché un hard reset della sessione quando BFD rileva un guasto. Se il peer non esegue BFD, la sessione si stabilisce normalmente.
Dopo il ricaricamento, controlla lo stato 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
Configurazione BFD con 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"
Controlla lo stato del peer 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 richiede che le porte UDP 3784 e 3785 siano aperte tra i peer. Se hai saltato il passaggio del firewall, le sessioni BFD rimarranno nello stato Down.
Come si esegue un graceful shutdown per la manutenzione?
La RFC 8326 definisce la community ben nota GRACEFUL_SHUTDOWN (65535:0). Prima di una manutenzione pianificata, contrassegni tutte le rotte con questa community. I peer che la rispettano impostano la local-preference a 0 per quelle rotte, facendo spostare il traffico su percorsi alternativi prima di chiudere la sessione. Questo evita il buco nero di traffico che si verifica durante la normale convergenza BGP.
La procedura di graceful shutdown:
- Contrassegna le rotte con la community GRACEFUL_SHUTDOWN sul nodo che stai per spegnere
- Attendi la convergenza (30-60 secondi perché Internet reindirizzi il traffico)
- Verifica che il traffico si sia spostato tramite looking glass o contatori di traffico
- Chiudi la sessione BGP
- Esegui la manutenzione
- Ripristina la sessione e rimuovi la community
- Conferma la ri-convergenza
Graceful shutdown con BIRD2
Per avviare il graceful shutdown sul nodo primario prima della manutenzione, modifica il filtro di 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;
}
Applicalo cambiando il filtro di export nel protocollo BGP e ricaricando:
# Edit bird.conf: change export filter to upstream_export_shutdown
# Then reload
birdc configure
Per rispettare il graceful shutdown dai peer (applica su entrambi i nodi), aggiungi un controllo nel filtro di import. L'ordine conta: il controllo del graceful shutdown deve chiamare accept dentro il blocco if, altrimenti un'assegnazione successiva di bgp_local_pref la sovrascriverà.
filter upstream_import_backup {
if (65535, 0) ~ bgp_community then {
bgp_local_pref = 0;
accept;
}
bgp_local_pref = 100;
accept;
}
Graceful shutdown con FRR
FRR fornisce un singolo comando che gestisce il tagging automaticamente:
vtysh -c "configure terminal
router bgp 64500
bgp graceful-shutdown
exit
exit"
Questo aggiunge la community GRACEFUL_SHUTDOWN (65535:0) a tutte le rotte e imposta la local-preference a 0. Viene inviato un route refresh a tutti i peer.
Per confermare che la community viene inviata:
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
Dopo la manutenzione, rimuovila:
vtysh -c "configure terminal
router bgp 64500
no bgp graceful-shutdown
exit
exit"
Per far sì che FRR rispetti il graceful shutdown dai peer, configura una route-map in ingresso:
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 sequenza 5 corrisponde alle rotte con la community e abbassa la local-preference a 0. La sequenza 10 gestisce normalmente tutte le altre rotte.
Come si testa il failover BGP?
Testa il failover chiudendo la sessione BGP primaria e osservando dal nodo backup e da un punto esterno.
Passo 1: Controlla lo stato di routing attuale su entrambi i nodi.
BIRD2:
birdc show route for 198.51.100.0/24 all
FRR:
vtysh -c "show ip bgp 198.51.100.0/24"
Passo 2: Chiudi la sessione BGP primaria.
BIRD2 (su VPS-PRI):
birdc disable upstream_v4
birdc disable upstream_v6
FRR (su VPS-PRI):
vtysh -c "configure terminal
router bgp 64500
neighbor 192.0.2.1 shutdown
neighbor 2001:db8:1::1 shutdown
exit
exit"
Passo 3: Osserva il nodo backup.
Su VPS-BKP, la rotta dovrebbe ora apparire come unico percorso:
# BIRD2
birdc show route for 198.51.100.0/24
# FRR
vtysh -c "show ip bgp summary"
Passo 4: Testa dall'esterno.
Dal tuo computer locale o da un looking glass, esegui un traceroute verso il tuo prefisso:
traceroute -A 198.51.100.1
Il traffico dovrebbe ora entrare dalla posizione di backup. Con BFD abilitato, il passaggio avviene in meno di un secondo. Senza BFD, aspettati la durata completa dell'hold timer prima della convergenza.
| Metodo di rilevamento | Tempo di failover tipico |
|---|---|
| Solo hold timer BGP (BIRD2 predefinito 240 s) | 160-240 s |
| Solo hold timer BGP (FRR predefinito 180 s) | 120-180 s |
| Hold timer ridotto (es. 30 s) | 20-30 s |
| BFD (intervalli 300 ms, moltiplicatore 3) | < 1 s |
Usa NLNOG Looking Glass o bgp.tools per confermare la convergenza del routing globale.
Come si ripristina il servizio dopo un failover?
Ripristina la sessione primaria e conferma che il traffico torna sul percorso preferito.
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"
Dopo qualche secondo, verifica che il percorso primario sia di nuovo preferito:
# 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
Esegui di nuovo un traceroute da un host esterno per confermare che il traffico rientra dalla posizione primaria.
Confronto configurazioni BIRD2 e FRR
| Funzionalità | BIRD2 | FRR |
|---|---|---|
| LOCAL_PREF | bgp_local_pref = 200; nel filtro di import |
set local-preference 200 nella route-map |
| MED | bgp_med = 0; nel filtro di export |
set metric 0 nella route-map |
| AS-path prepend | bgp_path.prepend(64500); nel filtro di export |
set as-path prepend 64500 nella route-map |
| BFD | protocol bfd {} + bfd graceful; in BGP |
sezione bfd + neighbor X bfd profile Y |
| Graceful shutdown (avviare) | Aggiungere (65535, 0) a bgp_community nel filtro di export |
bgp graceful-shutdown sotto router bgp |
| Graceful shutdown (rispettare) | Controllare (65535, 0) ~ bgp_community nel filtro di import, impostare bgp_local_pref = 0 |
match community GRACEFUL_SHUTDOWN nella route-map, set local-preference 0 |
| Disabilitare sessione | birdc disable <protocol> |
neighbor X shutdown |
| Ricaricare configurazione | birdc configure |
write memory poi clear ip bgp * o riavvio |
Monitoraggio degli eventi di failover
Configura il monitoraggio per ricevere avvisi quando si verifica un failover. Monitorare gli annunci BGP con BGPalerter su Linux copre BGPalerter per il monitoraggio delle rotte. Come minimo, monitora:
- Cambiamenti di stato delle sessioni BGP:
journalctl -u birdojournalctl -u frr - Flap delle sessioni BFD:
birdc show bfd sessions/vtysh -c "show bfd peers" - Variazioni nel numero di rotte: allarme se il numero di prefissi esportati scende a zero
Risoluzione dei problemi
Sessione BGP bloccata nello stato Active/Connect:
- Controlla le regole firewall per TCP 179
- Verifica che l'IP del peer e l'ASN corrispondano a quanto si aspetta il tuo upstream
- Consulta
journalctl -u bird -fojournalctl -u frr -fper messaggi di errore
Sessione BFD bloccata nello stato Down:
- Le porte UDP 3784 e 3785 devono essere aperte in entrambe le direzioni
- Conferma che il peer supporti BFD e lo abbia configurato
- Controlla problemi di MTU sul percorso
MED non influenza il traffico in ingresso:
- MED viene confrontato solo tra percorsi dello stesso AS. Se i tuoi upstream sono AS diversi, usa l'AS-path prepending
- Alcuni upstream ignorano MED per policy. Chiedi al tuo provider
La community di graceful shutdown non viene rispettata:
- Il peer deve supportare esplicitamente la RFC 8326. Non tutti gli upstream lo fanno
- Verifica con il tuo provider se rispettano la community GRACEFUL_SHUTDOWN
- Alcune implementazioni richiedono una configurazione esplicita per rispettare la community
Il traffico non effettua il failover:
- Verifica che entrambi i nodi annuncino lo stesso prefisso con
birdc show route export upstream_v4ovtysh -c "show ip bgp neighbors X advertised-routes" - Controlla da un looking glass esterno, non dai nodi stessi
- Il TTL DNS può mantenere i client puntati al vecchio IP se usi IP per posizione per i servizi sopra il prefisso anycast
Pronto a provare?
Esegui sessioni BGP sul tuo spazio IP con VPS Virtua.Cloud. →