BGP Route Filtering: Prefix List, Filtri AS-Path, Bogon Rejection e GTSM

16 min di lettura·Matthieu·bgpbird2frrroute-filteringnetwork-securityrpkimanrs|

Riferimento pratico per rafforzare le sessioni BGP su Linux con filtri a strati. Copre prefix-list, bogon rejection, filtri AS-path, limiti max-prefix e GTSM sia in sintassi BIRD2 che FRR, con passi di verifica.

RPKI valida che un AS sia autorizzato a originare un prefisso. Non protegge da route leak, bogon injection, esplosione della tabella per un peer mal configurato, o pacchetti BGP spoofed da host non adiacenti. Questo articolo tratta i filtri che gestiscono tutto ciò che RPKI non copre.

Ogni filtro è mostrato sia in sintassi BIRD2 che FRR, con esempi IPv4 e IPv6. Ogni sezione spiega cosa previene il filtro, fornisce la configurazione, poi mostra come verificarne il funzionamento.

Se non hai ancora configurato la RPKI origin validation, fallo prima. Vedi RPKI ROA Setup for BGP.

Per la configurazione base di sessione BGP, vedi BIRD2 BGP Configuration on Linux (BIRD2) o FRR BGP Configuration on Linux (FRR). Questo articolo presuppone che tu abbia già una sessione BGP funzionante e voglia rafforzarla.

Perché BGP ha bisogno di route filtering oltre a RPKI?

Il BGP route filtering è la pratica di accettare o rifiutare annunci BGP in base a prefisso, AS-path o attributi di origine. Previene route leak, prefix hijack, bogon injection ed esplosione della routing table. RPKI copre solo la origin validation. Senza filtri aggiuntivi, il tuo router è esposto a ogni altra categoria di incidente BGP.

Ecco cosa previene ogni strato:

Tipo di filtro Minaccia bloccata Cosa succede senza
Bogon prefix rejection Spazio privato/riservato nel DFZ Il router instrada traffico verso spazio RFC 1918. Black hole.
Small prefix rejection Hijack more-specific (/25+, /49+) Un attaccante annuncia un /32 che copre parte di un /24 accettato. La sua route vince per longest match.
AS-path bogon filtering ASN privati/riservati nei path Route con AS 65535 o AS 4200000000 finiscono nella tua tabella. Inoltri traffico su path spazzatura.
AS-path length limit Path inflation attack, table bloat Un peer invia route con 50+ AS hop. La memoria si riempie di voci inutili.
Max-prefix limit Route leak, session overload Un peer fa leak di una full table (1M+ prefissi) nella sessione. Il router esaurisce la memoria.
GTSM (TTL security) Pacchetti BGP spoofed da host remoti Un attaccante a più hop di distanza inietta pacchetti BGP OPEN o UPDATE nella sessione.
RPKI origin validation Origin hijack Qualcuno origina il tuo prefisso dal proprio AS. Già trattato in RPKI ROA Setup for BGP.

Incidenti reali mostrano perché ogni strato conta. Nel 2008, Pakistan Telecom annunciò route more-specific per i prefissi di YouTube per attuare un ordine di censura domestico. Quelle route finirono nei transit provider internazionali e mandarono YouTube in black hole globalmente per ore. Un filtro bogon o small-prefix avrebbe scartato quegli annunci. Nel giugno 2019, un piccolo ISP in Pennsylvania (AS396531) fece accidentalmente leak di route per Cloudflare, Amazon e Linode verso Verizon, che le propagò globalmente. Un limite max-prefix avrebbe chiuso la sessione prima che il leak si diffondesse.

Come si filtrano i prefissi bogon in BIRD2 e FRR?

I prefissi bogon sono range di indirizzi che non devono mai apparire nella routing table globale. Includono spazio privato RFC 1918, indirizzi link-local, range di documentazione e blocchi riservati. Accettarli significa che il router tenterà di instradare traffico verso indirizzi senza una destinazione globale legittima, creando black hole.

Prefissi bogon IPv4

Prefisso Riferimento Scopo
0.0.0.0/8 RFC 1122 Rete "This"
10.0.0.0/8 RFC 1918 Spazio privato
100.64.0.0/10 RFC 6598 Carrier-grade NAT
127.0.0.0/8 RFC 1122 Loopback
169.254.0.0/16 RFC 3927 Link-local
172.16.0.0/12 RFC 1918 Spazio privato
192.0.2.0/24 RFC 5737 TEST-NET-1
192.88.99.0/24 RFC 7526 Relay 6to4 deprecato
192.168.0.0/16 RFC 1918 Spazio privato
198.18.0.0/15 RFC 2544 Benchmarking
198.51.100.0/24 RFC 5737 TEST-NET-2
203.0.113.0/24 RFC 5737 TEST-NET-3
224.0.0.0/4 RFC 5771 Multicast
240.0.0.0/4 RFC 1112 Riservato per uso futuro

Prefissi bogon IPv6

Prefisso Riferimento Scopo
::/8 Vari Compatibile IPv4, loopback, mapped
100::/64 RFC 6666 Discard-only
2001:2::/48 RFC 5180 Benchmarking BMWG
2001:10::/28 RFC 4843 ORCHID
2001:db8::/32 RFC 3849 Documentazione
3fff::/20 RFC 9637 Documentazione
2002::/16 RFC 7526 6to4 deprecato
3ffe::/16 RFC 3701 Ex 6bone
5f00::/16 RFC 9602 SRv6 SID
fc00::/7 RFC 4193 Unique local unicast
fe80::/10 RFC 4291 Link-local unicast
fec0::/10 RFC 3879 Site-local deprecato
ff00::/8 RFC 4291 Multicast

Queste liste cambiano quando IANA alloca nuovi blocchi o ne depreca di vecchi. Il riferimento bogon di Team Cymru fornisce un feed BGP di fullbogon (spazio non allocato + riservato) che si aggiorna automaticamente. Per le liste statiche, controlla periodicamente la NLNOG BGP Filter Guide.

Filtro bogon BIRD2

# /etc/bird/bogons.conf - include this from your main bird.conf

define BOGON_PREFIXES_V4 = [
    0.0.0.0/8+,
    10.0.0.0/8+,
    100.64.0.0/10+,
    127.0.0.0/8+,
    169.254.0.0/16+,
    172.16.0.0/12+,
    192.0.2.0/24+,
    192.88.99.0/24+,
    192.168.0.0/16+,
    198.18.0.0/15+,
    198.51.100.0/24+,
    203.0.113.0/24+,
    224.0.0.0/4+,
    240.0.0.0/4+
];

define BOGON_PREFIXES_V6 = [
    ::/8+,
    0100::/64+,
    2001:2::/48+,
    2001:10::/28+,
    2001:db8::/32+,
    3fff::/20+,
    2002::/16+,
    3ffe::/16+,
    5f00::/16+,
    fc00::/7+,
    fe80::/10+,
    fec0::/10+,
    ff00::/8+
];

function reject_bogon_prefixes_v4() {
    if (net ~ BOGON_PREFIXES_V4) then {
        print "REJECTED bogon prefix: ", net, " path: ", bgp_path;
        reject;
    }
}

function reject_bogon_prefixes_v6() {
    if (net ~ BOGON_PREFIXES_V6) then {
        print "REJECTED bogon prefix: ", net, " path: ", bgp_path;
        reject;
    }
}

Il + dopo ogni prefisso significa "questo prefisso e tutti i more-specific." 10.0.0.0/8+ corrisponde a 10.0.0.0/8, 10.0.0.0/9, 10.1.0.0/16 e così via. Questo intercetta un attaccante che annuncia un /24 all'interno dello spazio RFC 1918.

Chiama queste funzioni nel tuo import filter:

filter import_from_upstream_v4 {
    reject_bogon_prefixes_v4();
    # ... other filters ...
    accept;
}

protocol bgp upstream_v4 {
    local as 64500;
    neighbor 198.51.100.1 as 64501;
    ipv4 {
        import filter import_from_upstream_v4;
        export none;
    };
}

Filtro bogon FRR

! IPv4 bogon prefix-list
ip prefix-list BOGONS_v4 seq 10 deny 0.0.0.0/8 le 32
ip prefix-list BOGONS_v4 seq 20 deny 10.0.0.0/8 le 32
ip prefix-list BOGONS_v4 seq 30 deny 100.64.0.0/10 le 32
ip prefix-list BOGONS_v4 seq 40 deny 127.0.0.0/8 le 32
ip prefix-list BOGONS_v4 seq 50 deny 169.254.0.0/16 le 32
ip prefix-list BOGONS_v4 seq 60 deny 172.16.0.0/12 le 32
ip prefix-list BOGONS_v4 seq 70 deny 192.0.2.0/24 le 32
ip prefix-list BOGONS_v4 seq 80 deny 192.88.99.0/24 le 32
ip prefix-list BOGONS_v4 seq 90 deny 192.168.0.0/16 le 32
ip prefix-list BOGONS_v4 seq 100 deny 198.18.0.0/15 le 32
ip prefix-list BOGONS_v4 seq 110 deny 198.51.100.0/24 le 32
ip prefix-list BOGONS_v4 seq 120 deny 203.0.113.0/24 le 32
ip prefix-list BOGONS_v4 seq 130 deny 224.0.0.0/4 le 32
ip prefix-list BOGONS_v4 seq 140 deny 240.0.0.0/4 le 32
ip prefix-list BOGONS_v4 seq 999 permit 0.0.0.0/0 le 32

! IPv6 bogon prefix-list
ipv6 prefix-list BOGONS_v6 seq 10 deny ::/8 le 128
ipv6 prefix-list BOGONS_v6 seq 20 deny 100::/64 le 128
ipv6 prefix-list BOGONS_v6 seq 30 deny 2001:2::/48 le 128
ipv6 prefix-list BOGONS_v6 seq 40 deny 2001:10::/28 le 128
ipv6 prefix-list BOGONS_v6 seq 50 deny 2001:db8::/32 le 128
ipv6 prefix-list BOGONS_v6 seq 60 deny 3fff::/20 le 128
ipv6 prefix-list BOGONS_v6 seq 70 deny 2002::/16 le 128
ipv6 prefix-list BOGONS_v6 seq 80 deny 3ffe::/16 le 128
ipv6 prefix-list BOGONS_v6 seq 90 deny 5f00::/16 le 128
ipv6 prefix-list BOGONS_v6 seq 100 deny fc00::/7 le 128
ipv6 prefix-list BOGONS_v6 seq 110 deny fe80::/10 le 128
ipv6 prefix-list BOGONS_v6 seq 120 deny fec0::/10 le 128
ipv6 prefix-list BOGONS_v6 seq 130 deny ff00::/8 le 128
ipv6 prefix-list BOGONS_v6 seq 999 permit ::/0 le 128

Le clausole le 32 (IPv4) e le 128 (IPv6) corrispondono al prefisso e a tutti i more-specific, come l'operatore + in BIRD2. La riga finale permit al seq 999 consente tutto ciò che non è stato negato in precedenza.

Applica la prefix-list al tuo neighbor:

router bgp 64500
 neighbor 198.51.100.1 remote-as 64501
 address-family ipv4 unicast
  neighbor 198.51.100.1 prefix-list BOGONS_v4 in
 address-family ipv6 unicast
  neighbor 2001:db8::1 prefix-list BOGONS_v6 in

Attenzione. Quella voce 2001:db8::/32 è nella lista bogon. Non usare indirizzi di documentazione in produzione. Sostituisci gli indirizzi neighbor sopra con i tuoi IP peer reali.

Rifiutare i prefissi troppo piccoli

Route più piccole di /24 (IPv4) o /48 (IPv6) non si propagheranno in modo affidabile nel DFZ globale. Accettarle apre a more-specific hijack attack. Filtrali in inbound.

BIRD2:

function reject_small_prefixes_v4() {
    if (net.len > 24) then {
        print "REJECTED too-small prefix: ", net, " path: ", bgp_path;
        reject;
    }
}

function reject_small_prefixes_v6() {
    if (net.len > 48) then {
        print "REJECTED too-small prefix: ", net, " path: ", bgp_path;
        reject;
    }
}

FRR:

! Add to the same prefix-lists, before the final permit
ip prefix-list BOGONS_v4 seq 150 deny 0.0.0.0/0 ge 25 le 32
ipv6 prefix-list BOGONS_v6 seq 140 deny ::/0 ge 49 le 128

Questo intercetta qualsiasi prefisso più specifico di /24 (IPv4) o /48 (IPv6). Posiziona queste righe prima delle voci seq 999 permit.

Come i filtri AS-path prevengono i route leak?

I filtri AS-path ispezionano la sequenza di autonomous system che una route ha attraversato. Intercettano tre problemi: ASN bogon che non dovrebbero mai apparire in un path, path eccessivamente lunghi che indicano leak o manipolazione, e ASN privati che non sono stati rimossi prima dell'annuncio.

Filtrare gli ASN bogon

Gli ASN bogon sono numeri riservati che non dovrebbero mai apparire in un BGP path su internet pubblico:

Range ASN Riferimento Scopo
0 RFC 7607 Riservato
23456 RFC 4893 AS_TRANS (transizione AS a 4 byte)
64496-64511 RFC 5398 Documentazione/esempi
64512-65534 RFC 6996 Uso privato (16-bit)
65535 RFC 7300 Ultimo ASN 16-bit
65536-65551 RFC 5398 Documentazione/esempi (32-bit)
65552-131071 IANA Riservato
4200000000-4294967294 RFC 6996 Uso privato (32-bit)
4294967295 RFC 7300 Ultimo ASN 32-bit

BIRD2:

define BOGON_ASNS = [
    0,
    23456,
    64496..64511,
    64512..65534,
    65535,
    65536..65551,
    65552..131071,
    4200000000..4294967294,
    4294967295
];

function reject_bogon_asns()
int set bogon_asns;
{
    bogon_asns = BOGON_ASNS;
    if (bgp_path ~ bogon_asns) then {
        print "REJECTED bogon ASN in path: ", net, " path: ", bgp_path;
        reject;
    }
}

L'operatore bgp_path ~ bogon_asns verifica se uno qualsiasi degli ASN nel path è membro del set. Un singolo ASN bogon ovunque nel path scatta il rifiuto.

FRR:

bgp as-path access-list BOGON_ASNS deny _0_
bgp as-path access-list BOGON_ASNS deny _23456_
bgp as-path access-list BOGON_ASNS deny _6449[6-9]_
bgp as-path access-list BOGON_ASNS deny _6450[0-9]_
bgp as-path access-list BOGON_ASNS deny _6451[01]_
bgp as-path access-list BOGON_ASNS deny _64[5-9][1-9][2-9]_
bgp as-path access-list BOGON_ASNS deny _6[5-9][0-9][0-9][0-9]_
bgp as-path access-list BOGON_ASNS deny _[1-9][0-9][0-9][0-9][0-9]_
bgp as-path access-list BOGON_ASNS deny _[1-3][0-9][0-9][0-9][0-9][0-9]_
bgp as-path access-list BOGON_ASNS permit .*

FRR usa il matching regex sulla stringa AS-path. I trattini bassi _ corrispondono ai delimitatori AS-path (spazio, inizio, fine). Questo approccio regex è meno preciso del matching su set interi di BIRD2. Per un approccio più semplice ma meno granulare, usa una route-map con l'as-path access-list:

route-map IMPORT_FILTER deny 10
 match as-path BOGON_ASNS
route-map IMPORT_FILTER permit 100

router bgp 64500
 address-family ipv4 unicast
  neighbor 198.51.100.1 route-map IMPORT_FILTER in

Nota: i pattern regex sopra sono semplificati. Fare il match dell'intero range di ASN privati 32-bit (4200000000-4294967294) con regex è soggetto a errori. Per i deployment in produzione, usa bgpq4 per generare prefix-list e filtri AS-path dai dati IRR, che è sia più accurato che automatizzabile.

Limitare la lunghezza dell'AS-path

Un BGP path legittimo raramente supera i 10-15 ASN. Path più lunghi indicano tipicamente un route leak, una manipolazione del path, o un prepending andato storto. Imposta un limite fisso.

BIRD2:

function reject_long_paths() {
    if (bgp_path.len > 25) then {
        print "REJECTED long AS-path (", bgp_path.len, "): ", net, " path: ", bgp_path;
        reject;
    }
}

FRR:

bgp as-path access-list LONG_PATHS deny ^([0-9]+_){25,}
bgp as-path access-list LONG_PATHS permit .*

route-map IMPORT_FILTER deny 20
 match as-path LONG_PATHS

Un limite di 25 è conservativo. La maggior parte delle route legittime ha path sotto i 10. Se ricevi una full table, ispeziona i path più lunghi nel tuo RIB prima di scegliere una soglia:

# BIRD2
birdc 'show route where bgp_path.len > 15' | head -20

# FRR
vtysh -c "show ip bgp regexp ^([0-9]+_){15,}"

Rimuovere gli ASN privati in outbound

Se usi iBGP con ASN privati internamente, assicurati che non finiscano nei tuoi upstream.

BIRD2:

filter export_to_upstream_v4 {
    # Strip private ASNs before advertising
    bgp_path.delete([64512..65534, 4200000000..4294967294]);
    # ... your export policy ...
    accept;
}

FRR:

router bgp 64500
 address-family ipv4 unicast
  neighbor 198.51.100.1 remove-private-AS all

La keyword all rimuove ogni ASN privato anche quando nel path sono presenti ASN pubblici. Senza all, FRR rimuove gli ASN privati solo se l'intero path contiene esclusivamente ASN privati.

Qual è il limite max-prefix corretto per una sessione BGP?

Un limite max-prefix è una valvola di sicurezza che chiude una sessione BGP se un peer annuncia più prefissi della soglia configurata. Previene l'esplosione della routing table quando un peer fa accidentalmente leak di una full table o viene compromesso. Senza di esso, un singolo peer mal configurato può far esaurire la memoria al router.

Imposta il limite in base a ciò che ti aspetti da ciascun peer:

Tipo di peer Prefissi attesi (IPv4) Limite suggerito Limite suggerito (IPv6)
Full table upstream ~1.200.000 (marzo 2026) 1.500.000 300.000
Partial table / IXP peer Variabile 1,5x conteggio attuale 1,5x conteggio attuale
Customer single-homed 1-10 50 50
Customer multi-homed 10-100 200 200

Controlla la dimensione attuale della full table su bgp.potaroo.net prima di impostare i limiti upstream. Imposta il limite a circa 1,2x il conteggio atteso per assorbire la crescita normale senza falsi trigger.

BIRD2:

protocol bgp upstream_v4 {
    local as 64500;
    neighbor 198.51.100.1 as 64501;
    ipv4 {
        import limit 1500000 action restart;
        import filter import_from_upstream_v4;
        export none;
    };
}

protocol bgp customer_v4 {
    local as 64500;
    neighbor 203.0.113.10 as 64502;
    ipv4 {
        import limit 50 action disable;
        import filter import_from_customer_v4;
        export filter export_to_customer_v4;
    };
}

BIRD2 offre tre azioni quando il limite viene raggiunto:

  • action restart - chiude la sessione e la riavvia dopo un ritardo. Ottimo per gli upstream.
  • action disable - chiude e disabilita il protocollo. Richiede birdc enable manuale per ripristinare. Ottimo per i customer dove un limite raggiunto indica qualcosa di seriamente sbagliato.
  • action block - smette di importare nuove route ma mantiene la sessione attiva. Utile se vuoi mantenere le route esistenti durante l'indagine.

FRR:

router bgp 64500
 neighbor 198.51.100.1 remote-as 64501
 address-family ipv4 unicast
  neighbor 198.51.100.1 maximum-prefix 1500000 90 restart 5

 neighbor 203.0.113.10 remote-as 64502
 address-family ipv4 unicast
  neighbor 203.0.113.10 maximum-prefix 50 80

In FRR, maximum-prefix 1500000 90 restart 5 significa: avvisa all'90% (1.350.000 prefissi), chiudi a 1.500.000 e riavvia la sessione dopo 5 minuti. Senza la keyword restart, FRR chiude la sessione e richiede un clear bgp neighbor manuale per ripristinarla.

Verificare la configurazione max-prefix

# BIRD2 - check current prefix count and limit
birdc show protocols all upstream_v4 | grep -E "Routes|Limit"

# FRR - check prefix count per neighbor
vtysh -c "show ip bgp summary"

L'output mostra il conteggio attuale dei prefissi accanto al limite configurato. Se il conteggio è vicino al limite, aumenta la soglia prima che scatti.

Come protegge GTSM le sessioni BGP dai pacchetti spoofed?

GTSM (Generalized TTL Security Mechanism, RFC 5082) limita i pacchetti BGP accettati ai peer direttamente connessi verificando il campo TTL/Hop Limit. Quando abilitato, i pacchetti BGP vengono inviati con TTL 255. Il ricevitore scarta qualsiasi pacchetto BGP con TTL inferiore a 254 (per un peer direttamente connesso). Poiché i router decrementano il TTL a ogni hop, un attaccante a più di un hop di distanza non può inviare pacchetti che arrivino con TTL 255.

Questo blocca il TCP RST injection remoto, i SYN flood diretti alla porta BGP 179 e i pacchetti BGP OPEN/UPDATE artefatti da attaccanti non adiacenti. GTSM è mutuamente esclusivo con eBGP multihop sulla stessa sessione. Entrambi i peer devono abilitarlo.

BIRD2:

protocol bgp upstream_v4 {
    local as 64500;
    neighbor 198.51.100.1 as 64501;
    ttl security yes;
    ipv4 {
        import limit 1500000 action restart;
        import filter import_from_upstream_v4;
        export none;
    };
}

FRR:

router bgp 64500
 neighbor 198.51.100.1 remote-as 64501
 neighbor 198.51.100.1 ttl-security hops 1

hops 1 significa che il peer deve essere esattamente a 1 hop di distanza (direttamente connesso). Imposta questo valore per corrispondere al numero reale di hop. Per i peer eBGP su uno switching fabric IXP, hops 1 è corretto. Per sessioni multihop (ad esempio BGP su tunnel GRE), non puoi usare GTSM. Usa invece l'autenticazione MD5:

Alternativa MD5 BIRD2:

protocol bgp multihop_peer {
    local as 64500;
    neighbor 198.51.100.5 as 64503;
    multihop 2;
    password "your-md5-secret";
    # ...
}

Alternativa MD5 FRR:

router bgp 64500
 neighbor 198.51.100.5 remote-as 64503
 neighbor 198.51.100.5 ebgp-multihop 2
 neighbor 198.51.100.5 password your-md5-secret

Conserva la password MD5 in un file con permessi ristretti (chmod 600) piuttosto che nel config principale. Per FRR, referenziala da /etc/frr/frr.conf che dovrebbe già essere 640 di proprietà di frr:frr. Per BIRD2, mantieni /etc/bird/bird.conf a 640 di proprietà di bird:bird.

Quali filtri BGP richiede MANRS?

MANRS (Mutually Agreed Norms for Routing Security) definisce azioni di base per gli operatori di rete. Le azioni 1, 3 e 4 sono obbligatorie per diventare un partecipante MANRS. Ecco come i filtri in questo articolo si mappano sulle azioni MANRS.

Azione 1: Prevenire la propagazione di informazioni di routing errate.

Questa è l'azione di filtering principale. Richiede filtri espliciti a livello di prefisso sulle connessioni customer e raccomanda filtri AS-path per prevenire i route leak.

Filtro di questo articolo Copertura MANRS Azione 1
Prefix-list filtering (bogon) Previene l'annuncio/accettazione di spazio riservato
Small prefix rejection Blocca route more-specific che indicano hijack
AS-path bogon filtering Rifiuta route con ASN privati/riservati
Max-prefix limits Ferma la propagazione di full table in leak
Customer prefix filter Non trattato in questo articolo. Costruiscili per-customer da IRR usando bgpq4.

Azione 2 (raccomandata): Prevenire traffico con source address spoofed.

Non è un filtro BGP. Si tratta della source address validation BCP 38/84 (uRPF). Fuori dallo scope di questo articolo ma ugualmente importante.

Azione 3: Facilitare la comunicazione operativa globale.

Mantieni aggiornati i tuoi contatti in PeeringDB e nel database del tuo RIR. Non è un filtro, ma gli operatori che gestiscono filtri corretti tendono anche a mantenere aggiornate le proprie informazioni di contatto.

Azione 4: Facilitare le informazioni di routing su scala globale.

Pubblica la tua routing policy in IRR (RIPE, RADB) usando oggetti RPSL. Crea ROA per RPKI. Questo rende possibile per i tuoi peer costruire filtri accurati per i tuoi annunci.

La combinazione di bogon filtering (prefissi + ASN) + small prefix rejection + max-prefix limits + customer prefix-list copre MANRS Azione 1. Aggiungi RPKI (RPKI ROA Setup for BGP) e la registrazione IRR per l'Azione 4.

Mettere tutto insieme: un import filter completo

Ecco un import filter combinato che usa tutte le tecniche viste sopra.

Import filter completo BIRD2

# /etc/bird/filters.conf

include "/etc/bird/bogons.conf";  # BOGON_PREFIXES_V4, BOGON_PREFIXES_V6, BOGON_ASNS

function import_checks_v4() {
    # 1. Reject bogon prefixes
    if (net ~ BOGON_PREFIXES_V4) then {
        print "REJECT bogon prefix: ", net, " ", bgp_path;
        reject;
    }

    # 2. Reject too-small prefixes
    if (net.len > 24) then {
        print "REJECT small prefix: ", net, " ", bgp_path;
        reject;
    }

    # 3. Reject bogon ASNs in path
    if (bgp_path ~ [0, 23456, 64496..64511, 64512..65534, 65535,
                     65536..65551, 65552..131071,
                     4200000000..4294967294, 4294967295]) then {
        print "REJECT bogon ASN: ", net, " ", bgp_path;
        reject;
    }

    # 4. Reject excessively long paths
    if (bgp_path.len > 25) then {
        print "REJECT long path: ", net, " ", bgp_path;
        reject;
    }

    # 5. Reject RPKI invalid (if RPKI is configured)
    if (roa_check(rpki4, net, bgp_path.last) = ROA_INVALID) then {
        print "REJECT RPKI invalid: ", net, " ", bgp_path;
        reject;
    }
}

filter import_upstream_v4 {
    import_checks_v4();
    accept;
}

protocol bgp upstream_v4 {
    local as 64500;
    neighbor 198.51.100.1 as 64501;
    ttl security yes;
    ipv4 {
        import limit 1500000 action restart;
        import filter import_upstream_v4;
        export none;
    };
}

Import filter completo FRR

! /etc/frr/frr.conf

! --- Prefix lists (bogons + small prefix rejection) ---
ip prefix-list IMPORT_V4 seq 10 deny 0.0.0.0/8 le 32
ip prefix-list IMPORT_V4 seq 20 deny 10.0.0.0/8 le 32
ip prefix-list IMPORT_V4 seq 30 deny 100.64.0.0/10 le 32
ip prefix-list IMPORT_V4 seq 40 deny 127.0.0.0/8 le 32
ip prefix-list IMPORT_V4 seq 50 deny 169.254.0.0/16 le 32
ip prefix-list IMPORT_V4 seq 60 deny 172.16.0.0/12 le 32
ip prefix-list IMPORT_V4 seq 70 deny 192.0.2.0/24 le 32
ip prefix-list IMPORT_V4 seq 80 deny 192.88.99.0/24 le 32
ip prefix-list IMPORT_V4 seq 90 deny 192.168.0.0/16 le 32
ip prefix-list IMPORT_V4 seq 100 deny 198.18.0.0/15 le 32
ip prefix-list IMPORT_V4 seq 110 deny 198.51.100.0/24 le 32
ip prefix-list IMPORT_V4 seq 120 deny 203.0.113.0/24 le 32
ip prefix-list IMPORT_V4 seq 130 deny 224.0.0.0/4 le 32
ip prefix-list IMPORT_V4 seq 140 deny 240.0.0.0/4 le 32
ip prefix-list IMPORT_V4 seq 150 deny 0.0.0.0/0 ge 25 le 32
ip prefix-list IMPORT_V4 seq 999 permit 0.0.0.0/0 le 32

! --- AS-path filters (bogon ASNs + path length) ---
bgp as-path access-list BOGON_ASNS deny _0_
bgp as-path access-list BOGON_ASNS deny _23456_
bgp as-path access-list BOGON_ASNS deny _6449[6-9]_
bgp as-path access-list BOGON_ASNS deny _6450[0-9]_
bgp as-path access-list BOGON_ASNS deny _6451[01]_
bgp as-path access-list BOGON_ASNS permit .*

bgp as-path access-list LONG_PATHS deny ^([0-9]+_){25,}
bgp as-path access-list LONG_PATHS permit .*

! --- Route-map combining all checks ---
route-map IMPORT_UPSTREAM deny 10
 match as-path BOGON_ASNS
route-map IMPORT_UPSTREAM deny 20
 match as-path LONG_PATHS
route-map IMPORT_UPSTREAM permit 100

! --- BGP neighbor configuration ---
router bgp 64500
 neighbor 198.51.100.1 remote-as 64501
 neighbor 198.51.100.1 ttl-security hops 1
 address-family ipv4 unicast
  neighbor 198.51.100.1 prefix-list IMPORT_V4 in
  neighbor 198.51.100.1 route-map IMPORT_UPSTREAM in
  neighbor 198.51.100.1 maximum-prefix 1500000 90 restart 5

In FRR, vengono valutati sia la prefix-list che la route-map. La prefix-list viene eseguita per prima e scarta i prefissi bogon e i prefissi piccoli. Le route che superano la prefix-list raggiungono poi la route-map, che controlla i filtri AS-path. Entrambe devono consentire la route affinché venga accettata.

Come si verifica che i filtri BGP funzionino?

I filtri sono utili solo se rifiutano effettivamente ciò che dovrebbero. Verifica dopo ogni modifica.

Verifica BIRD2

# Check what routes were rejected (requires print statements in filters)
grep "REJECT" /var/log/bird.log | tail -20

# Show the routing table with filter details
birdc show route filtered

# Show routes from a specific protocol
birdc show route protocol upstream_v4

# Count accepted routes per protocol
birdc show protocols all upstream_v4 | grep "Routes:"

# Test a specific prefix against your import filter
birdc show route for 10.0.0.0/8 all

Il comando show route filtered mostra le route che sono state ricevute ma rifiutate dall'import filter. Se il filtro bogon funziona, dovresti vedere zero prefissi bogon nella tabella accettata e i bogon ricevuti nella tabella filtered.

Verifica FRR

# Show accepted routes from a neighbor
vtysh -c "show ip bgp neighbors 198.51.100.1 received-routes"

# Show routes filtered by inbound policy
vtysh -c "show ip bgp neighbors 198.51.100.1 filtered-routes"

# Check the prefix count per neighbor
vtysh -c "show ip bgp summary"

# Test if a specific prefix is accepted
vtysh -c "show ip bgp 10.0.0.0/8"

# Check max-prefix status
vtysh -c "show ip bgp neighbors 198.51.100.1" | grep -A2 "Maximum prefix"

Perché received-routes e filtered-routes funzionino, devi abilitare la soft-reconfiguration inbound sul neighbor:

router bgp 64500
 address-family ipv4 unicast
  neighbor 198.51.100.1 soft-reconfiguration inbound

Questo usa memoria extra (memorizza tutte le route ricevute prima del filtering). Su una sessione full-table è circa 2x la memoria per il RIB. Su router di produzione con RAM limitata, usalo selettivamente.

Verifica esterna

I tuoi filtri proteggono il tuo RIB. Per verificare cosa annunci agli altri, usa looking glass esterni:

  • bgp.tools - cerca il tuo ASN per vedere quali prefissi stai annunciando globalmente
  • RIPE RIS - servizio di informazioni di routing BGP, mostra la visibilità delle route sui collector
  • Hurricane Electric BGP Toolkit - ricerca per prefisso e ASN

Controlla questi strumenti dopo aver modificato i filtri per confermare di non stare filtrando accidentalmente route legittime o non stare propagando route che non dovresti annunciare.

Per il monitoraggio automatizzato, vedi .

Confronto sintassi BIRD2 vs FRR

Riferimento rapido per tradurre tra i due daemon:

Tipo di filtro BIRD2 FRR
Bogon prefix if (net ~ BOGON_PREFIXES) then reject ip prefix-list BOGONS deny 10.0.0.0/8 le 32
Small prefix if (net.len > 24) then reject ip prefix-list X deny 0.0.0.0/0 ge 25 le 32
Bogon ASN if (bgp_path ~ [64512..65534]) then reject bgp as-path access-list X deny _64[5-9][1-9][2-9]_
Path length if (bgp_path.len > 25) then reject bgp as-path access-list X deny ^([0-9]+_){25,}
Max-prefix import limit 50 action disable neighbor X maximum-prefix 50
GTSM ttl security yes neighbor X ttl-security hops 1
MD5 auth password "secret" neighbor X password secret
Strip private AS bgp_path.delete([64512..65534]) neighbor X remove-private-AS all
Apply filter import filter name neighbor X prefix-list/route-map name in

BIRD2 usa una singola funzione filter che combina tutti i controlli. FRR suddivide i controlli tra prefix-list (matching su prefisso), as-path access-list (matching su path) e route-map (combinazione di più condizioni di match). Entrambi gli approcci funzionano. L'approccio BIRD2 è più leggibile per policy complesse. L'approccio FRR è più familiare agli operatori Cisco.

Qualcosa è andato storto?

Sessione chiusa da max-prefix: Controlla journalctl -u bird o journalctl -u frr per il messaggio di limite raggiunto. Aumenta il limite se il peer è cresciuto legittimamente, o indaga se è un leak. In BIRD2, riabilita con birdc enable upstream_v4. In FRR, ripristina con vtysh -c "clear bgp 198.51.100.1".

Route legittime filtrate: Controlla birdc show route filtered o vtysh -c "show ip bgp neighbors X filtered-routes" per vedere cosa è stato scartato. Causa comune: la lista bogon è troppo aggressiva, o la soglia small-prefix sta rifiutando /25 legittimi di un customer. Aggiusta il filtro e ricarica: birdc configure o vtysh -c "write memory" poi systemctl reload frr.

GTSM che rifiuta un peer valido: Entrambi i lati devono abilitare GTSM. Se un lato lo ha attivo e l'altro no, i pacchetti arrivano con TTL 1 e vengono scartati dal lato con GTSM abilitato. Controlla con tcpdump -i eth0 port 179 -v e guarda il valore TTL.

Filtri non attivi dopo una modifica: In BIRD2, esegui birdc configure per ricaricare. In FRR, se cambi una prefix-list o route-map, esegui un soft reset: vtysh -c "clear bgp 198.51.100.1 in". Senza questo, le route esistenti nel RIB non vengono rivalutate con il nuovo filtro.

Log: Entrambi i daemon scrivono log tramite systemd journal per default.

# BIRD2
journalctl -u bird -f

# FRR
journalctl -u frr -f

Le istruzioni print nelle funzioni filter di BIRD2 scrivono nel log di bird. In FRR, abilita il debug logging con debug bgp updates in vtysh per la risoluzione dei problemi temporanea. Disabilitalo quando hai finito perché genera grandi quantità di output di log.


Questo articolo fa parte della serie BGP Bring Your Own IP on a VPS.


Copyright 2026 Virtua.Cloud. Tutti i diritti riservati. Questo contenuto è un'opera originale del team Virtua.Cloud. La riproduzione, ripubblicazione o redistribuzione senza autorizzazione scritta è vietata.

Pronto a provare?

Distribuisci il tuo server in pochi secondi. Linux, Windows o FreeBSD.

Vedi piani VPS
BGP Route Filtering: Prefix List, AS-Path, GTSM