RPKI ROA voor BGP: ROA's aanmaken, routes valideren in BIRD2 en FRR

12 min leestijd·Matthieu·rpkiroabgpbird2frrroutinatorripe-nccipv6|

Maak IPv4- en IPv6-ROA's aan in het RIPE NCC-portaal, installeer Routinator als RTR-cache, configureer RPKI-routevalidatie in BIRD2 en FRRouting en controleer de prefixstatus met bgp.tools en RIPE Stat.

Zonder RPKI kan elk ASN elk prefix aankondigen. Een Route Origin Authorization (ROA) bindt je prefix cryptografisch aan je ASN, en Route Origin Validation (ROV) laat je router ongeldige aankondigingen afwijzen. Deze tutorial behandelt de volledige keten: ROA's aanmaken in het RIPE NCC-portaal, Routinator draaien als lokale RPKI-cache, validatie configureren in BIRD2 en FRRouting, en alles verifiëren.

Vereisten: een geregistreerd ASN, toegewezen IP-prefixen (PA of PI), een werkende BGP-sessie op een Linux VPS (BGP met eigen IP op een VPS), en BIRD2 (BIRD2 BGP-configuratie) of FRR (FRR BGP-configuratie) al draaiend.

Wat is RPKI en waarom heeft je BGP-prefix een ROA nodig?

Resource Public Key Infrastructure (RPKI) is een cryptografisch framework gedefinieerd in RFC 6480 dat internetresources (IP-prefixen, ASN's) via X.509-certificaten van de Regional Internet Registries aan hun rechtmatige houders bindt. Een Route Origin Authorization (ROA) is een ondertekend object dat verklaart: "ASN X is gemachtigd om prefix Y aan te kondigen met een maximale prefixlengte van Z." Validators halen deze ROA's op en geven het resultaat door aan je router via het RPKI-to-Router (RTR) protocol (RFC 8210).

Wanneer een router een BGP-update ontvangt, controleert hij de origin-ASN en het prefix tegen zijn lokale ROA-tabel. Elk prefix krijgt een van drie validatiestatussen:

Status Betekenis Aanbevolen actie
Valid Er bestaat een ROA die overeenkomt met de origin-ASN en prefixlengte Accepteren
Invalid Er bestaat een ROA maar de origin-ASN of prefixlengte komt niet overeen Afwijzen
Not Found Geen ROA dekt dit prefix Accepteren (optioneel met lager local-pref)

Zonder ROA verschijnen je prefixen als "Not Found." Dat is beter dan "Invalid", maar netwerken die ROV uitvoeren geven de voorkeur aan "Valid" routes van je peers boven je "Not Found" aankondigingen wanneer beide beschikbaar zijn. ROA's aanmaken is de eerste stap. Inkomende routes valideren beschermt je netwerk tegen het accepteren van gekaapte prefixen.

Hoe maak je IPv4- en IPv6-ROA's aan in het RIPE NCC-portaal?

Log in op het RIPE NCC-portaal, navigeer naar Resources en dan RPKI Dashboard. Als je RPKI nog niet hebt geïnitialiseerd, selecteer dan "Hosted" certificate authority. RIPE NCC beheert de CA en ondertekening voor je. Zodra de Hosted CA actief is, schakel naar het tabblad BGP Announcements. RIPE vult ROA-suggesties vooraf in op basis van je huidige BGP-aankondigingen.

  1. Klik op Create ROA (of + New ROA in het ROA-tabblad).
  2. Stel Origin ASN in op je AS-nummer (bijv. AS213279).
  3. Stel Prefix in op je IPv4-allocatie (bijv. 192.0.2.0/24).
  4. Stel Maximum Length gelijk aan de prefixlengte (/24). Verhoog deze niet. Zie de maxLength-sectie hieronder.
  5. Klik op Publish.
  6. Herhaal voor je IPv6-prefix (bijv. 2001:db8::/48 met maximale lengte /48).

Controleer in het RPKI Dashboard dat de ROA-status "Published" toont. Propagatie naar validators duurt doorgaans 10 tot 20 minuten, afhankelijk van hun verversingsinterval.

Dual-stack herinnering: maak één ROA per prefix. Als je 192.0.2.0/24 en 2001:db8::/48 aankondigt, heb je twee ROA's nodig. Als je extra more-specifics aankondigt (een /25 uit het /24), heeft elk zijn eigen ROA met zijn eigen ASN-binding nodig.

Hoe installeer je Routinator als RPKI-RTR-cache op Linux?

Routinator is een RPKI Relying Party (validator) ontwikkeld door NLnet Labs. Het haalt ROA's op van alle vijf RIR trust anchors, valideert ze en levert Validated ROA Payloads (VRP's) aan je router via het RTR-protocol. Huidige stabiele versie: 0.15.1.

Installatie vanuit de NLnet Labs-repository

Op Debian 12 of Ubuntu 24.04:

sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release

Voeg de NLnet Labs-ondertekeningssleutel en repository toe:

curl -fsSL https://packages.nlnetlabs.nl/aptkey.asc | sudo gpg --dearmor -o /usr/share/keyrings/nlnetlabs-archive-keyring.gpg

Voor Debian:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/nlnetlabs-archive-keyring.gpg] https://packages.nlnetlabs.nl/linux/debian $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/nlnetlabs.list > /dev/null

Voor Ubuntu:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/nlnetlabs-archive-keyring.gpg] https://packages.nlnetlabs.nl/linux/ubuntu $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/nlnetlabs.list > /dev/null

Installeer Routinator:

sudo apt update
sudo apt install -y routinator

Het pakket installeert een systemd-service die automatisch start. Routinator draait als de routinator-gebruiker.

Service controleren

sudo systemctl status routinator

Je zou active (running) moeten zien. De eerste synchronisatie duurt 2 tot 5 minuten terwijl Routinator alle trust anchor-certificaten ophaalt en de globale ROA-set valideert.

Controleer of de initiële synchronisatie is voltooid door de HTTP-API te bevragen (de pakketversie logt naar syslog met weinig detail; de HTTP-API is de betrouwbare bron):

curl -s http://127.0.0.1:8323/api/v1/status | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'IPv4 VRPs: {d[\"payload\"][\"routeOriginsIPv4\"][\"final\"]}, IPv6 VRPs: {d[\"payload\"][\"routeOriginsIPv6\"][\"final\"]}')"

Als de synchronisatie nog loopt, zijn de tellers nul. Wacht 2 tot 5 minuten en probeer opnieuw. Zodra je niet-nulwaarden ziet (honderdduizenden voor IPv4, tienduizenden voor IPv6), is de initiële synchronisatie voltooid.

Configuratie

De pakketconfiguratie staat in /etc/routinator/routinator.conf. De standaardwaarden zijn veilig: RTR luistert op 127.0.0.1:3323 en HTTP op 127.0.0.1:8323. Beide zijn alleen aan localhost gebonden.

Belangrijke instellingen:

Optie Standaard Doel
rtr-listen ["127.0.0.1:3323"] RTR-server voor routers
http-listen ["127.0.0.1:8323"] HTTP-interface en API
refresh 600 Seconden tussen RPKI-synchronisaties
retry 600 Seconden voor herpoging na mislukte synchronisatie
expire 7200 Seconden voordat gecachte VRP's als verlopen worden beschouwd

Als BIRD2 of FRR op dezelfde machine draait (typisch voor een VPS BGP-setup), houd dan de standaard 127.0.0.1-binding aan. Geen firewallwijzigingen nodig.

Als je Routinator op een aparte server draait, bind dan aan een privé-IP en beperk de toegang:

sudo ufw allow from 10.0.0.0/24 to any port 3323 proto tcp comment "RTR from routers"

Controleer de HTTP-interface:

curl -s http://127.0.0.1:8323/api/v1/status | head -20

Dit geeft JSON terug met het huidige VRP-aantal, de laatste synchronisatietijd en de validatorstatus.

Hoe configureer je RPKI-validatie in BIRD2?

BIRD2 heeft native RPKI-ondersteuning via het rpki-protocol (beschikbaar sinds BIRD 2.0; Ubuntu 24.04 levert BIRD 2.14). Het verbindt via RTR met Routinator, vult ROA-tabellen en biedt de roa_check()-functie voor importfilters. Geen externe bibliotheken nodig.

Voeg het volgende toe aan je BIRD2-configuratie (doorgaans /etc/bird/bird.conf):

ROA-tabellen definiëren

roa4 table roa_v4;
roa6 table roa_v6;

RPKI-protocol configureren

protocol rpki rpki_routinator {
    roa4 { table roa_v4; };
    roa6 { table roa_v6; };
    remote 127.0.0.1 port 3323;
    retry keep 90;
    refresh keep 600;
    expire keep 7200;
}

Het keep-sleutelwoord vertelt BIRD om de door de server geleverde timerwaarden te prefereren en terug te vallen op de opgegeven standaardwaarden. retry 90 betekent dat BIRD 90 seconden na verlies van de RTR-sessie opnieuw verbindt.

ROA-validatie toevoegen aan je importfilter

filter bgp_import_v4 {
    if (roa_check(roa_v4, net, bgp_path.last_nonaggregated) = ROA_INVALID) then {
        print "RPKI INVALID: ", net, " from AS", bgp_path.last;
        reject;
    }
    if (roa_check(roa_v4, net, bgp_path.last_nonaggregated) = ROA_VALID) then {
        bgp_local_pref = 200;
    }
    accept;
}

filter bgp_import_v6 {
    if (roa_check(roa_v6, net, bgp_path.last_nonaggregated) = ROA_INVALID) then {
        print "RPKI INVALID: ", net, " from AS", bgp_path.last;
        reject;
    }
    if (roa_check(roa_v6, net, bgp_path.last_nonaggregated) = ROA_VALID) then {
        bgp_local_pref = 200;
    }
    accept;
}

bgp_path.last_nonaggregated is veiliger dan bgp_path.last omdat het AS_SET-entries van aggregatie overslaat. Ongeldige routes worden afgewezen. Geldige routes krijgen een hoger local-pref. Not Found-routes passeren met het standaard local-pref.

Filter toepassen op je BGP-peer

protocol bgp upstream_v4 {
    local as 213279;
    neighbor 198.51.100.1 as 64500;
    ipv4 {
        import filter bgp_import_v4;
        import table;
        export where source ~ [RTS_STATIC, RTS_BGP];
    };
}

De import table-directive is belangrijk. Het laat BIRD gefilterde routes opnieuw evalueren wanneer de ROA-tabel verandert, zonder een volledige sessiereset.

Herladen en verifiëren

sudo birdc configure

Controleer de RPKI-sessie:

sudo birdc show protocols all rpki_routinator

Zoek naar Established in de output. Controleer dan de inhoud van de ROA-tabel:

sudo birdc show route table roa_v4 count

Je zou honderdduizenden entries moeten zien (de globale ROA-tabel bevat begin 2026 meer dan 800.000 VRP's).

Controleer de validatie van een specifiek prefix:

sudo birdc show route 192.0.2.0/24 all

De output bevat een ROA-veld dat valid, invalid of unknown (not found) toont.

Hoe configureer je RPKI-validatie in FRRouting?

FRRouting ondersteunt RPKI via de rpki-module, die librtr onder de motorkap gebruikt (Ubuntu 24.04 levert FRR 8.4.4; FRR 9.x+ en 10.x worden ook ondersteund). De module verbindt met de RTR-server van Routinator en integreert met BGP route-maps.

RPKI-module installeren

Op Debian/Ubuntu met FRR al geïnstalleerd:

sudo apt install -y frr-rpki-rtrlib

Module activeren

Bewerk /etc/frr/daemons en voeg -M rpki toe aan de bgpd-opties:

bgpd_options="  -A 127.0.0.1 -M rpki"

Herstart FRR:

sudo systemctl restart frr

Controleer of bgpd de module heeft geladen:

sudo vtysh -c "show rpki cache-server"

Als het commando zonder fout wordt uitgevoerd (output kan leeg zijn vóór het configureren van een cache), is de module geladen. Als je % Unknown command krijgt, ontbreekt de -M rpki-vlag of is frr-rpki-rtrlib niet geïnstalleerd.

RTR-cache configureren

Ga naar vtysh en configureer:

sudo vtysh
configure terminal
rpki
 rpki cache 127.0.0.1 3323 preference 1
 rpki polling_period 300
 rpki expire_interval 7200
 rpki retry_interval 600
 exit

Opmerking: FRR 9.x+ gebruikt de syntax rpki cache tcp 127.0.0.1 3323 preference 1 (met expliciet tcp-sleutelwoord). FRR 8.x gebruikt rpki cache 127.0.0.1 3323 preference 1 zonder. Controleer je versie met vtysh -c "show version".

Route-maps maken voor RPKI-statussen

route-map rpki-filter permit 10
 match rpki valid
 set local-preference 200
exit

route-map rpki-filter deny 20
 match rpki invalid
exit

route-map rpki-filter permit 30
 match rpki notfound
exit

Dit accepteert geldige routes met verhoogd local-pref, weigert ongeldige routes en accepteert not-found routes met standaard local-pref.

Route-map toepassen op je BGP-buur

router bgp 213279
 neighbor 198.51.100.1 remote-as 64500
 address-family ipv4 unicast
  neighbor 198.51.100.1 route-map rpki-filter in
  neighbor 198.51.100.1 soft-reconfiguration inbound
 exit-address-family
 address-family ipv6 unicast
  neighbor 2001:db8::1 route-map rpki-filter in
  neighbor 2001:db8::1 soft-reconfiguration inbound
 exit-address-family
exit

soft-reconfiguration inbound is vereist. Zonder kan FRR bestaande routes niet opnieuw evalueren wanneer de RPKI-cache wordt bijgewerkt. FRR slaat de ongewijzigde routes van de peer op en past de route-map opnieuw toe wanneer de VRP's veranderen.

Configuratie opslaan:

write memory
end

Verifiëren

Controleer de RTR-verbinding:

sudo vtysh -c "show rpki cache-connection"

Zoek naar (connected) in de output. Controleer dan de prefixtabel:

sudo vtysh -c "show rpki prefix-table" | head -20

Filter BGP-routes op validatiestatus:

sudo vtysh -c "show bgp ipv4 unicast rpki valid" | head -20
sudo vtysh -c "show bgp ipv4 unicast rpki invalid"

De invalid-output zou de routes moeten tonen die je actief afwijst.

BIRD2 vs FRR: RPKI-configuratie in één oogopslag

Functie BIRD2 FRR
Module-installatie Ingebouwd (geen extra pakket) Pakket frr-rpki-rtrlib + vlag -M rpki
RTR-configuratie protocol rpki-blok met remote rpki cache-commando in vtysh
ROA-tabellen Expliciete roa4/roa6-tabellen Intern, niet direct toegankelijk
Filtermechanisme roa_check() in importfilter match rpki in route-map
Automatische herevaluatie import table-directive soft-reconfiguration inbound
ROA-aantal tonen birdc show route table roa_v4 count vtysh show rpki prefix-table
Validatie tonen birdc show route ... all (ROA-veld) vtysh show bgp rpki valid/invalid/notfound

Hoe controleer je de RPKI-status van je prefix?

Na het aanmaken van ROA's en het configureren van validatie, verifieer je vanuit meerdere punten.

Lokale verificatie

Op de router zelf, controleer of je eigen prefix als geldig wordt getoond:

BIRD2:

sudo birdc show route 192.0.2.0/24 all | grep -i roa

FRR:

sudo vtysh -c "show rpki prefix-table 192.0.2.0/24"

Beide zouden je ASN als geautoriseerde origin moeten tonen.

Routinator HTTP-API

curl -s "http://127.0.0.1:8323/api/v1/validity/AS213279/192.0.2.0/24"

Geeft JSON terug met de validatiestatus, overeenkomende VRP's en de bron trust anchor.

bgp.tools

Open https://bgp.tools/prefix/192.0.2.0/24 in een browser. De RPKI-kolom toont een groen schild voor Valid, rood voor Invalid of grijs voor Not Found. Reken op 15 tot 30 minuten na ROA-aanmaak voordat externe tools de wijziging oppikken.

RIPE Stat

Bevraag de RPKI-validatie-API:

curl -s "https://stat.ripe.net/data/rpki-validation/data.json?resource=AS213279&prefix=192.0.2.0/24" | python3 -m json.tool

Zoek naar "status": "valid" in het antwoord. RIPE Stat toont ook welke ROA's het prefix dekken en of de maxLength overeenkomt.

Herhaal voor IPv6

Voer dezelfde controles uit met je IPv6-prefix. Elk commando hierboven accepteert IPv6-prefixen. Vervang 192.0.2.0/24 door 2001:db8::/48 en verifieer dat beide adresfamilies gedekt zijn.

Waarom moet je maxLength niet langer instellen dan je prefixlengte?

Stel maxLength gelijk aan je prefixlengte. Dit is de aanbeveling uit RFC 9319 (die RFC 7115 bijwerkt en uitbreidt).

Wanneer je maxLength op /24 zet bij een /20-ROA, autoriseer je je ASN om het /20 en elk more-specific tot /24 aan te kondigen. Dat betekent dat 16 /24's gedekt zijn. Een aanvaller die een van die /24's kaapt met jouw ASN als origin, passeert de RPKI-validatie als "Valid." Het gekaapte more-specific wint door longest-match routing, en de ROA kan je niet helpen omdat je die lengte hebt geautoriseerd.

Dit heet een forged-origin sub-prefix hijack. Metingen uit 2017, geciteerd in RFC 9319, toonden aan dat 84% van de ROA's met maxLength kwetsbaar waren voor deze aanval.

Concreet voorbeeld:

ROA Wat het autoriseert
192.0.2.0/20, maxLength /20 Alleen 192.0.2.0/20 van je ASN. Veilig.
192.0.2.0/20, maxLength /24 /20, /21, /22, /23, /24 van je ASN. Elk /24 kan gekaapt worden door je origin-ASN te spoofen.

Wanneer is maxLength > prefixlengte acceptabel? Alleen wanneer je daadwerkelijk deaggregeert in productie (bijv. zowel een /20 als specifieke /24's aankondigt voor traffic engineering) en elk gedeaggregeerd prefix gevalideerd moet worden. Maak in dat geval individuele ROA's voor elk aangekondigd prefix in plaats van één ROA met een brede maxLength. Eén ROA per aankondiging is het veiligste patroon.

DDoS-mitigatie uitzondering: als je een dienst gebruikt zoals een scrubbing center dat je more-specifics opnieuw aankondigt vanaf je ASN, heb je mogelijk maxLength nodig om die prefixen te dekken. Documenteer deze uitzondering en audit deze regelmatig.

Wat gebeurt er wanneer de RPKI-cache uitvalt?

Wanneer Routinator stopt of onbereikbaar wordt, hangt het gedrag van je router af van de expire-timer.

BIRD2 bewaart de laatst bekende ROA-tabel in het geheugen voor de duur van expire (standaard 7200 seconden / 2 uur). Tijdens dit venster gaat de validatie normaal door met verouderde gegevens. Na het verlopen verwijdert BIRD alle ROA-entries en valt elke route terug op "Not Found." Er worden geen routes afgewezen wegens ongeldigheid, maar geen routes krijgen de valid local-pref-bonus.

FRR gedraagt zich vergelijkbaar. Het rpki expire_interval bepaalt hoe lang gecachte VRP's bruikbaar blijven nadat de RTR-verbinding wegvalt.

Risico verminderen

Draai een tweede Routinator-instantie of gebruik een andere validator (StayRTR, Fort) op een aparte machine. Configureer beide als RTR-bronnen.

BIRD2 ondersteunt meerdere protocol rpki-blokken:

protocol rpki rpki_backup {
    roa4 { table roa_v4; };
    roa6 { table roa_v6; };
    remote 10.0.0.2 port 3323;
    retry keep 90;
    refresh keep 600;
    expire keep 7200;
}

FRR ondersteunt meerdere cacheservers met verschillende voorkeuren:

rpki
 rpki cache 127.0.0.1 3323 preference 1
 rpki cache 10.0.0.2 3323 preference 2
exit

Lagere voorkeurswaarden worden eerst geprobeerd. FRR valt terug op de secundaire als de primaire uitvalt.

Monitor de gezondheid van Routinator. Controleer systemctl status routinator en het status-endpoint van de HTTP-API met je monitoringsysteem. Stel alerts in voor dalingen in het VRP-aantal (een plotselinge daling naar nul betekent synchronisatiefout) en voor RTR-verbindingsverliezen zichtbaar in journalctl -u routinator.

Probleemoplossing

ROA toont "Not Found" na aanmaak. Propagatie duurt 10 tot 20 minuten. Routinator synchroniseert standaard elke 10 minuten (refresh = 600). Forceer een synchronisatie-herstart: sudo systemctl restart routinator, wacht dan tot de initiële synchronisatie is voltooid.

birdc toont 0 entries in de ROA-tabel. Controleer birdc show protocols all rpki_routinator. Als de status niet "Established" is, verifieer dan dat Routinator draait en luistert op poort 3323: ss -tlnp | grep 3323.

FRR "Unknown command" voor rpki. De -M rpki-vlag ontbreekt in /etc/frr/daemons of frr-rpki-rtrlib is niet geïnstalleerd. Installeer het pakket, voeg de vlag toe, herstart FRR.

Routes worden niet opnieuw geëvalueerd na ROA-wijziging. Voeg in BIRD2 import table; toe aan het BGP-kanaal. Schakel in FRR soft-reconfiguration inbound in bij de buur.

Alle routes tonen Invalid. Je ROA heeft mogelijk het verkeerde ASN of prefix. Controleer dit in het RIPE-portaal. Verifieer ook dat de ASN van je router overeenkomt met wat je in de ROA hebt gezet.

Volgende stappen: combineer RPKI-validatie met prefix-lists en AS-path-filters voor defense in depth . Monitor RPKI invalid-alerts voor je prefixen met BGPalerter .


Copyright 2026 Virtua.Cloud. Alle rechten voorbehouden. Deze inhoud is een origineel werk van het Virtua.Cloud-team. Reproductie, herpublicatie of herdistributie zonder schriftelijke toestemming is verboden.

Klaar om het zelf te proberen?

Deploy uw eigen server in seconden. Linux, Windows of FreeBSD.

Bekijk VPS-aanbod