BGP-failover en multihoming vanaf twee VPS-locaties

10 min leestijd·Matthieu·bird2bfdfailoverfrrbgpmultihoming|

Kondig hetzelfde prefix aan vanaf twee locaties met BGP voor automatische failover. Behandelt LOCAL_PREF, MED, AS-path prepending, BFD en graceful shutdown met volledige BIRD2- en FRR-configuraties.

Deze tutorial laat zien hoe je hetzelfde IP-prefix aankondigt vanaf twee afzonderlijke VPS-locaties via BGP. Je configureert primaire/backup-voorkeur met LOCAL_PREF en MED, schakelt BFD in voor foutdetectie binnen een seconde, en implementeert graceful shutdown voor gepland onderhoud. Alle voorbeelden tonen BIRD2 en FRR naast elkaar.

Vereisten:

Wat is BGP-multihoming en waarom op een VPS?

BGP-multihoming betekent dat je hetzelfde IP-prefix aankondigt vanaf twee of meer locaties via eBGP. Elke locatie onderhoudt een onafhankelijke BGP-sessie met zijn upstream-provider. Als een locatie uitvalt, blijft de andere het prefix aankondigen en neemt automatisch al het verkeer over. De convergentietijd hangt af van de hold-timers (doorgaans 180-240 seconden met standaardinstellingen) of BFD (minder dan een seconde bij correcte configuratie).

Op een VPS biedt multihoming redundantie zonder afhankelijkheid van een enkel datacenter. Je draait twee VPS-instanties op verschillende locaties, die beide je prefix aankondigen. De ene fungeert als primair, de andere als backup. Traffic engineering-attributen (LOCAL_PREF, MED, AS-path prepending) bepalen welk pad het verkeer afhandelt onder normale omstandigheden.

Hoe ontwerp je BGP-failover over twee locaties?

De opzet gebruikt twee Virtua VPS op verschillende Europese locaties, elk met een eBGP-sessie naar de lokale upstream-router. Beide kondigen hetzelfde /24 en /48 aan.

                    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

Beide nodes behoren tot je AS (AS 64500 in deze voorbeelden). Vervang ASN, prefixen en peer-IP's door je eigen waarden.

Firewallregels voor beide nodes:

BGP gebruikt TCP-poort 179. BFD gebruikt UDP-poorten 3784 en 3785. Open deze poorten tussen je VPS en de upstream-peer voordat je verder gaat.

# 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

Hoe bepaal je de BGP-padvoorkeur?

Drie attributen stellen je in staat het verkeerspad te beïnvloeden. Elk werkt op een ander niveau.

Attribuut Richting Bereik Verstuurd naar peers? Wanneer gebruiken
LOCAL_PREF Uitgaand (jouw uitgang) Binnen je AS Nee (alleen iBGP) Bepalen welke node uitgaand verkeer verstuurt
MED Inkomend (van upstream) Tussen jou en één upstream-AS Ja (naar directe buur) Een upstream vertellen welk ingangspunt de voorkeur heeft
AS-path prepending Inkomend (globaal) Alle AS'en in het pad Ja (wordt gepropageerd) Een pad langer laten lijken voor het hele internet

LOCAL_PREF en MED zijn precies. AS-path prepending is een grof instrument maar werkt wanneer je locaties met verschillende upstreams verbonden zijn.

Hoe configureer je LOCAL_PREF voor primaire en backup-paden?

LOCAL_PREF bepaalt welk uitgaand pad je AS verkiest voor uitgaand verkeer. De hoogste waarde wint. Standaard is 100. Stel 200 in op de primaire node en laat 100 op de backup. Dit beïnvloedt alleen verkeer dat je netwerk verlaat.

BIRD2 LOCAL_PREF-configuratie

Op de primaire node (VPS-PRI), maak of wijzig het importfilter:

# /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;
    };
}

Op de backup node (VPS-BKP), behoud de standaard LOCAL_PREF:

# /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;
    };
}

Herlaad BIRD2 en controleer de 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

De waarde BGP.local_pref: 200 op de primaire node betekent dat deze de voorkeur krijgt voor uitgaand verkeer.

FRR LOCAL_PREF-configuratie

Op de primaire node:

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"

Op de backup node, stel set local-preference 100 in (of laat de route-map weg aangezien 100 de standaardwaarde is).

Controleer de routeringstabel:

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

Hoe gebruik je MED om inkomend verkeer te sturen?

MED (Multi-Exit Discriminator) vertelt je upstream welk ingangspunt de voorkeur heeft. De laagste waarde wint. Stel MED 0 in op de primaire en MED 100 op de backup. MED wordt alleen vergeleken tussen paden van hetzelfde buur-AS, dus het werkt het best wanneer beide locaties peeren met dezelfde upstream-provider.

BIRD2 MED-configuratie

Op de primaire node, stel MED in via het exportfilter:

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;
    };
}

Op de backup node:

filter upstream_export_backup {
    if net = 198.51.100.0/24 || net = 2001:db8::/48 then {
        bgp_med = 100;
        accept;
    }
    reject;
}

FRR MED-configuratie

Op de primaire node:

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"

Op de backup node, gebruik set metric 100.

Controleer de geëxporteerde routes:

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

De kolom Metric toont 0 op de primaire. De backup toont 100.

Wanneer AS-path prepending gebruiken in plaats van MED?

Gebruik AS-path prepending wanneer je twee locaties verbonden zijn met verschillende upstream-providers. MED wordt alleen vergeleken tussen paden van hetzelfde AS, dus het heeft geen effect als je upstreams verschillende AS'en zijn. Prepending maakt het backup-pad langer, waardoor globale routeringsbeslissingen richting de primaire gaan.

Voeg je eigen ASN 1 tot 3 keer toe op de backup-node. Meer dan 3 prepends verandert zelden routeringsbeslissingen en voegt alleen ruis toe.

BIRD2 (exportfilter van de backup-node):

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 (backup-node):

vtysh -c "configure terminal
route-map UPSTREAM-OUT permit 10
 set as-path prepend 64500 64500
exit
exit"

Controleer na toepassing het AS-pad vanaf een looking glass of een externe machine:

# From an external machine
traceroute -A 198.51.100.1

Het backup-pad toont nu 64500 64500 64500 (je ASN verschijnt drie keer: één keer echt, twee keer toegevoegd) terwijl het primaire pad 64500 één keer toont.

Hoe schakel je BFD in voor snelle foutdetectie?

Zonder BFD vertrouwt BGP op hold-timers voor het detecteren van een peer-uitval. De standaard hold-time is 240 seconden in BIRD2 en 180 seconden in FRR. Met BFD daalt de detectietijd tot onder een seconde op verbindingen met lage latentie.

Parameter Standaard Aanbevolen voor VPS
Verzendinterval 300 ms 300 ms
Ontvangstinterval 300 ms 300 ms
Detectiemultiplicator 3 3
Effectieve detectietijd 900 ms 900 ms

Voor VPS-omgevingen op hetzelfde provider-backbone bieden 300 ms-intervallen met multiplicator 3 betrouwbare detectie onder een seconde zonder vals alarm. Stel intervallen niet lager dan 100 ms in op VPS-instanties. Virtualisatiejitter kan flapping veroorzaken.

BIRD2 BFD-configuratie

Voeg een BFD-protocol toe en schakel het in op de BGP-sessie:

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;
    };
}

De optie bfd graceful betekent dat BIRD2 een graceful restart activeert (met behoud van verouderde routes) in plaats van een harde sessiereset wanneer BFD een storing detecteert. Als de peer geen BFD draait, wordt de sessie normaal opgezet.

Controleer na het herladen de BFD-status:

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

FRR BFD-configuratie

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"

Controleer de BFD-peerstatus:

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 vereist dat UDP-poorten 3784 en 3785 open zijn tussen de peers. Als je de firewallstap hebt overgeslagen, blijven BFD-sessies in de status Down.

Hoe voer je een graceful shutdown uit voor onderhoud?

RFC 8326 definieert de welbekende GRACEFUL_SHUTDOWN-community (65535:0). Voor gepland onderhoud markeer je alle routes met deze community. Peers die deze respecteren stellen de local-preference in op 0 voor die routes, waardoor verkeer verschuift naar alternatieve paden voordat je de sessie beëindigt. Dit voorkomt het verkeersblackhol dat optreedt tijdens normale BGP-convergentie.

De graceful shutdown-procedure:

  1. Markeer routes met de GRACEFUL_SHUTDOWN-community op de node die je uitschakelt
  2. Wacht op convergentie (30-60 seconden totdat het internet het verkeer omleidt)
  3. Controleer of het verkeer is verschoven via een looking glass of verkeerstellers
  4. Beëindig de BGP-sessie
  5. Voer onderhoud uit
  6. Herstel de sessie en verwijder de community
  7. Bevestig de herconvergentie

Graceful shutdown met BIRD2

Om graceful shutdown op de primaire node te initiëren voor onderhoud, wijzig het exportfilter:

# 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;
}

Pas het toe door het exportfilter in het BGP-protocol te wijzigen en te herladen:

# Edit bird.conf: change export filter to upstream_export_shutdown
# Then reload
birdc configure

Om graceful shutdown van peers te respecteren (pas dit toe op beide nodes), voeg een controle toe in het importfilter. De volgorde is belangrijk: de graceful shutdown-controle moet accept aanroepen binnen het if-blok, anders overschrijft een latere bgp_local_pref-toewijzing de waarde.

filter upstream_import_backup {
    if (65535, 0) ~ bgp_community then {
        bgp_local_pref = 0;
        accept;
    }
    bgp_local_pref = 100;
    accept;
}

Graceful shutdown met FRR

FRR biedt een enkel commando dat de tagging automatisch afhandelt:

vtysh -c "configure terminal
router bgp 64500
 bgp graceful-shutdown
exit
exit"

Dit voegt de GRACEFUL_SHUTDOWN-community (65535:0) toe aan alle routes en stelt de local-preference in op 0. Er wordt een route refresh naar alle peers gestuurd.

Om te bevestigen dat de community wordt verstuurd:

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

Na onderhoud verwijder je de community:

vtysh -c "configure terminal
router bgp 64500
 no bgp graceful-shutdown
exit
exit"

Om FRR graceful shutdown van peers te laten respecteren, configureer een inkomende route-map:

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"

Sequentie 5 matcht routes met de community en verlaagt de local-preference naar 0. Sequentie 10 verwerkt alle andere routes normaal.

Hoe test je BGP-failover?

Test failover door de primaire BGP-sessie te beëindigen en te observeren vanaf de backup-node en een extern punt.

Stap 1: Controleer de huidige routeringsstatus op beide nodes.

BIRD2:

birdc show route for 198.51.100.0/24 all

FRR:

vtysh -c "show ip bgp 198.51.100.0/24"

Stap 2: Beëindig de primaire BGP-sessie.

BIRD2 (op VPS-PRI):

birdc disable upstream_v4
birdc disable upstream_v6

FRR (op VPS-PRI):

vtysh -c "configure terminal
router bgp 64500
 neighbor 192.0.2.1 shutdown
 neighbor 2001:db8:1::1 shutdown
exit
exit"

Stap 3: Observeer de backup-node.

Op VPS-BKP zou de route nu als enig pad moeten verschijnen:

# BIRD2
birdc show route for 198.51.100.0/24

# FRR
vtysh -c "show ip bgp summary"

Stap 4: Test van buitenaf.

Voer vanaf je lokale machine of een looking glass een traceroute uit naar je prefix:

traceroute -A 198.51.100.1

Verkeer zou nu via de backup-locatie moeten binnenkomen. Met BFD ingeschakeld vindt de omschakeling plaats in minder dan een seconde. Zonder BFD is de volledige hold-timerduur te verwachten voor convergentie.

Detectiemethode Typische failovertijd
Alleen BGP hold-timer (BIRD2-standaard 240 s) 160-240 s
Alleen BGP hold-timer (FRR-standaard 180 s) 120-180 s
Verlaagde hold-timer (bijv. 30 s) 20-30 s
BFD (300 ms-intervallen, multiplicator 3) < 1 s

Gebruik NLNOG Looking Glass of bgp.tools om de globale routeringsconvergentie te bevestigen.

Hoe herstel je na een failover?

Herstel de primaire sessie en bevestig dat het verkeer terugkeert naar het voorkeurspad.

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"

Controleer na enkele seconden of het primaire pad weer de voorkeur heeft:

# 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

Voer opnieuw een traceroute uit vanaf een externe host om te bevestigen dat het verkeer weer via de primaire locatie binnenkomt.

Vergelijking BIRD2- en FRR-configuraties

Functie BIRD2 FRR
LOCAL_PREF bgp_local_pref = 200; in importfilter set local-preference 200 in route-map
MED bgp_med = 0; in exportfilter set metric 0 in route-map
AS-path prepend bgp_path.prepend(64500); in exportfilter set as-path prepend 64500 in route-map
BFD protocol bfd {} + bfd graceful; in BGP bfd-sectie + neighbor X bfd profile Y
Graceful shutdown (initiëren) (65535, 0) toevoegen aan bgp_community in exportfilter bgp graceful-shutdown onder router bgp
Graceful shutdown (respecteren) (65535, 0) ~ bgp_community controleren in importfilter, bgp_local_pref = 0 instellen match community GRACEFUL_SHUTDOWN in route-map, set local-preference 0
Sessie uitschakelen birdc disable <protocol> neighbor X shutdown
Configuratie herladen birdc configure write memory daarna clear ip bgp * of herstart

Monitoring van failover-events

Stel monitoring in om meldingen te ontvangen wanneer failover optreedt. BGP-aankondigingen monitoren met BGPalerter op Linux behandelt BGPalerter voor routemonitoring. Monitor minimaal:

  • BGP-sessiestatuswijzigingen: journalctl -u bird of journalctl -u frr
  • BFD-sessieflaps: birdc show bfd sessions / vtysh -c "show bfd peers"
  • Wijzigingen in routeaantallen: alarm als het aantal geëxporteerde prefixen naar nul daalt

Probleemoplossing

BGP-sessie vast in Active/Connect-status:

  • Controleer firewallregels voor TCP 179
  • Verifieer dat het peer-IP en ASN overeenkomen met wat je upstream verwacht
  • Bekijk journalctl -u bird -f of journalctl -u frr -f voor foutmeldingen

BFD-sessie vast in Down-status:

  • UDP-poorten 3784 en 3785 moeten in beide richtingen open zijn
  • Bevestig dat de peer BFD ondersteunt en geconfigureerd heeft
  • Controleer op MTU-problemen in het pad

MED beïnvloedt inkomend verkeer niet:

  • MED wordt alleen vergeleken tussen paden van hetzelfde AS. Als je upstreams verschillende AS'en zijn, gebruik dan AS-path prepending
  • Sommige upstreams negeren MED als beleid. Vraag je provider

Graceful shutdown-community wordt niet gerespecteerd:

  • De peer moet RFC 8326 expliciet ondersteunen. Niet alle upstreams doen dat
  • Vraag je provider of ze de GRACEFUL_SHUTDOWN-community respecteren
  • Sommige implementaties vereisen expliciete configuratie om de community te respecteren

Verkeer failovert niet:

  • Verifieer dat beide nodes hetzelfde prefix aankondigen met birdc show route export upstream_v4 of vtysh -c "show ip bgp neighbors X advertised-routes"
  • Controleer vanaf een externe looking glass, niet vanaf de nodes zelf
  • DNS TTL kan clients naar het oude IP blijven verwijzen als je locatiespecifieke IP's gebruikt voor diensten bovenop het anycast-prefix