Introduction
Une session BGP non sécurisée, c'est :
- Un attaquant qui détourne TCP/179 et injecte des routes (hijack)
- Un peer qui te balance accidentellement 800k préfixes et fait OOM ton routeur
- Toi qui acceptes des préfixes qui ne devraient jamais exister sur Internet (RFC 1918, bogons)
- Un voisin qui annonce un préfixe qui ne lui appartient pas, et tu envoies du trafic là-bas
Ce tuto te donne les 5 couches que tout opérateur de transit (et tout client de transit, comme toi avec VeryCloud) doit poser. Du minimum vital au sérieux pro.
Prérequis
- Une session BGP fonctionnelle vers VeryCloud (voir tutos BIRD/FRR/Cisco/Arista)
- Tes préfixes IPv4/IPv6 et un compte chez ton RIR (RIPE NCC, ARIN, APNIC, etc.)
- Accès à la config de ton démon BGP
Couche 1 : ROA RPKI (Route Origin Authorization)
RPKI (RFC 6480) lie cryptographiquement un préfixe à un ASN autorisé à l'annoncer. C'est la défense n°1 contre les hijacks BGP.
Tu publies une ROA (Route Origin Authorization) chez ton RIR qui dit :
"Le préfixe 192.0.2.0/24 peut être annoncé par AS198825, max-length 24"
VeryCloud (et tous les opérateurs sérieux) filtreront les annonces RPKI-invalid.
Créer une ROA chez RIPE NCC
- Connecte-toi sur https://my.ripe.net
- Va dans Resources → ROAs
- Clique Create ROA
- Renseigne :
- Préfixe :
192.0.2.0/24 - Max length :
24(autorise uniquement /24, pas plus spécifique) ou32(autorise toutes les sous-divisions) - ASN autorisé :
198825(l'AS qui annonce, ici VeryCloud)
- Préfixe :
- Valide
⚠️ Si tu utilises ton propre ASN public au lieu d'AS198825, mets ton ASN dans la ROA. Si tu utilises un AS privé (64512-65534), pas de ROA possible — il faudra te reposer uniquement sur l'IRR.
Vérification après publication (propagation ~30 min) :
# Sur un validateur public
curl -s "https://stat.ripe.net/data/rpki-validation/data.json?resource=AS198825&prefix=192.0.2.0/24" | jq
Côté ton routeur : validation RPKI
Si tu veux toi-même filtrer les routes RPKI-invalid reçues de VeryCloud (en plus du filtrage qu'ils font), il te faut un validateur local. Le plus simple : routinator (NLnet Labs).
# Debian / Ubuntu
sudo apt install -y routinator
sudo routinator init --accept-arin-rpa
sudo systemctl enable --now routinator
Routinator expose un endpoint RTR sur TCP/3323 que ton démon BGP consomme.
BIRD 2 :
roa4 table r4;
roa6 table r6;
protocol rpki rpki1 {
roa4 { table r4; };
roa6 { table r6; };
remote "127.0.0.1" port 3323;
retry keep 90;
}
filter bgp_in_v4 {
if (roa_check(r4, net, bgp_path.last) = ROA_INVALID) then reject;
accept;
}
FRR :
rpki
rpki cache 127.0.0.1 3323 preference 1
exit
router bgp 65000
address-family ipv4 unicast
neighbor 169.254.X.1 route-map RPKI-CHECK in
exit-address-family
exit
route-map RPKI-CHECK deny 10
match rpki invalid
route-map RPKI-CHECK permit 20
Couche 2 : Authentification TCP-MD5
TCP-MD5 (RFC 2385) ajoute un MAC dans chaque segment TCP de la session BGP. Sans le mot de passe partagé, impossible d'injecter du trafic dans la connexion.
C'est vieux (1998, MD5 cassé en collision) mais ça suffit largement pour bloquer un attaquant qui veut spoofer la session BGP — il faudrait casser MD5 en quelques secondes en spoofant un port TCP très exact, c'est inopérationnel.
Le successeur moderne est TCP-AO (RFC 5925), mais beaucoup moins déployé. MD5 reste le standard de facto.
BIRD 2 :
protocol bgp verycloud_v4 {
neighbor 169.254.X.1 as 198825;
password "TON_MD5_SECRET";
}
FRR / Cisco / Arista :
router bgp 65000
neighbor 169.254.X.1 password TON_MD5_SECRET
💡 Le mot de passe doit être identique à l'octet près des deux côtés. VeryCloud te fournit le MD5 dans le mail technique.
Couche 3 : Max-prefix / maximum-prefix / import limit
Limite stricte du nombre de préfixes acceptés. Si VeryCloud t'envoie 600k routes par accident, ton routeur drop la session au lieu d'exploser.
Calibrer la valeur :
- Default route only :
5suffit - Full BGP table v4 (~950k routes en mai 2026) : mets
1100000 - Full BGP table v6 (~200k routes en mai 2026) : mets
250000
BIRD 2 :
ipv4 {
import limit 5000 action restart;
};
action restart = redémarre la session, attendant que ça revienne à la normale. Autres options : disable (coupe définitivement), warn (continue mais log).
FRR / Cisco :
neighbor 169.254.X.1 maximum-prefix 5000 80 restart 30
→ Warning à 80%, restart la session toutes les 30 minutes en cas de dépassement.
Arista :
neighbor VC-V4 maximum-routes 5000 warning-limit 4000
Couche 4 : GTSM (Generalized TTL Security Mechanism)
GTSM (RFC 5082) vérifie le TTL des paquets BGP. Une session BGP entre deux peers directement connectés doit avoir TTL=255 (1 hop). Un attaquant distant qui spoofe TCP/179 verra son TTL plus bas → drop.
Inapplicable simple si le peer est à plusieurs hops (cas du tunnel), mais utilisable pour les tunnels : tu sais que c'est toujours 1 hop dans le tunnel, donc TTL=255 attendu.
BIRD 2 :
protocol bgp verycloud_v4 {
neighbor 169.254.X.1 as 198825;
ttl security on;
}
FRR / Cisco :
neighbor 169.254.X.1 ttl-security hops 1
Arista :
neighbor 169.254.X.1 ttl maximum-hops 1
⚠️ Si tu actives
ttl security, désactiveebgp-multihop(ils sont incompatibles dans certaines implémentations). Vérifie côté VeryCloud qu'ils acceptent GTSM avant d'activer unilatéralement.
Couche 5 : Prefix-list / filtre anti-bogons
Refuse explicitement tout préfixe RFC 1918, link-local, multicast, ou doc (RFC 5737, RFC 3849) qui ne devrait jamais transiter par Internet.
Liste minimale IPv4 :
0.0.0.0/8 # this network
10.0.0.0/8 # RFC 1918
100.64.0.0/10 # CGNAT (RFC 6598)
127.0.0.0/8 # loopback
169.254.0.0/16 # link-local
172.16.0.0/12 # RFC 1918
192.0.0.0/24 # IETF protocol assignments
192.0.2.0/24 # TEST-NET-1 (RFC 5737)
192.168.0.0/16 # RFC 1918
198.18.0.0/15 # benchmark (RFC 2544)
198.51.100.0/24 # TEST-NET-2
203.0.113.0/24 # TEST-NET-3
224.0.0.0/4 # multicast
240.0.0.0/4 # reserved
Liste minimale IPv6 :
::/8 # incl. ::1 loopback
64:ff9b::/96 # NAT64
100::/64 # discard prefix
2001::/23 # IETF protocol
2001:db8::/32 # documentation (RFC 3849)
fc00::/7 # ULA
fe80::/10 # link-local
ff00::/8 # multicast
FRR / Cisco :
ip prefix-list NO-BOGONS seq 10 deny 0.0.0.0/8 le 32
ip prefix-list NO-BOGONS seq 20 deny 10.0.0.0/8 le 32
ip prefix-list NO-BOGONS seq 30 deny 100.64.0.0/10 le 32
ip prefix-list NO-BOGONS seq 40 deny 127.0.0.0/8 le 32
ip prefix-list NO-BOGONS seq 50 deny 169.254.0.0/16 le 32
ip prefix-list NO-BOGONS seq 60 deny 172.16.0.0/12 le 32
ip prefix-list NO-BOGONS seq 70 deny 192.0.0.0/24 le 32
ip prefix-list NO-BOGONS seq 80 deny 192.0.2.0/24 le 32
ip prefix-list NO-BOGONS seq 90 deny 192.168.0.0/16 le 32
ip prefix-list NO-BOGONS seq 100 deny 198.18.0.0/15 le 32
ip prefix-list NO-BOGONS seq 110 deny 198.51.100.0/24 le 32
ip prefix-list NO-BOGONS seq 120 deny 203.0.113.0/24 le 32
ip prefix-list NO-BOGONS seq 130 deny 224.0.0.0/4 le 32
ip prefix-list NO-BOGONS seq 140 deny 240.0.0.0/4 le 32
! Accept tout le reste, max /24
ip prefix-list NO-BOGONS seq 1000 permit 0.0.0.0/0 le 24
Puis appliquer en input :
neighbor 169.254.X.1 route-map FROM-VC in
!
route-map FROM-VC permit 10
match ip address prefix-list NO-BOGONS
BIRD 2 : via filter (cf tuto BIRD).
💡 Tu peux automatiser la liste avec Team Cymru Bogon Reference : un service BGP gratuit qui te flush les bogons en temps réel. Voir https://www.team-cymru.com/bogon-networks.
Bonus : IRR (Internet Routing Registry)
Au-delà de RPKI, beaucoup d'opérateurs filtrent sur la base de l'IRR : route(6)-object dans la base RIPE/RADB.
Pour annoncer 192.0.2.0/24 via AS65000, crée dans RIPE :
route: 192.0.2.0/24
origin: AS65000
mnt-by: TON-MNT
source: RIPE
VeryCloud (et Hurricane Electric, Cogent, etc.) vérifient l'IRR. Sans route-object, beaucoup d'opérateurs droperont tes annonces.
Checklist sécurité minimum
| # | Couche | Indispensable ? |
|---|---|---|
| 1 | ROA RPKI sur tes préfixes | ✅ OUI |
| 2 | TCP-MD5 sur la session | ✅ OUI |
| 3 | maximum-prefix / import limit | ✅ OUI |
| 4 | GTSM (si supporté des deux côtés) | Recommandé |
| 5 | Prefix-list anti-bogons en input | ✅ OUI |
| 6 | Route-object IRR | ✅ OUI |
| 7 | Filtre out strict (uniquement tes préfixes) | ✅ OUI |
Sans le 1, 2, 3, 5, 6, 7 → ne mets pas la session en prod. Tout le reste est du bonus.
Dépannage
ROA publiée mais routes toujours rejetées
- Propagation lente : attends 30-60 min
- Cache local du validateur stale :
routinator vrpspour voir ce qu'il a en cache - Max-length incorrect dans la ROA (souvent oublié)
MD5 password failing
- Espaces invisibles dans le mot de passe (très fréquent quand copié-collé)
- Encoding : éviter les caractères non-ASCII
maximum-prefix exceeded
- Tu reçois plus que prévu : ajuste la valeur
- Ou côté VeryCloud, ils t'envoient full table alors que tu voulais default
Commandes utiles
# RPKI validation status (BIRD)
sudo birdc show route protocol verycloud_v4
# RPKI cache (FRR)
sudo vtysh -c "show rpki cache-server"
sudo vtysh -c "show rpki prefix-table"
# Validator routinator
sudo routinator vrps
sudo routinator rtrtr
Conclusion
5 couches : RPKI, MD5, max-prefix, GTSM, prefix-list. Plus l'IRR en bonus. Ça paraît beaucoup, mais c'est 30 minutes de config bien posée pour des années de tranquillité. Tout opérateur sérieux fait ça. Si tu sautes une de ces couches, tu prends un risque proportionnel.
Pour aller plus loin : ASPA (RFC 9286) pour valider les chemins AS, BGPsec (RFC 8205) pour signer les annonces, Mutually Agreed Norms for Routing Security (MANRS).


















