Première rédaction de cet article le 4 février 2012
Un ensemble de RFC vient de sortir, décrivant un mécanisme pour sécuriser les annonces de route sur l'Internet (actuellement, on peut annoncer à peu près ce qu'on veut avec BGP...). Quels sont les logiciels existants qui permettent de regarder ces annonces et/ou de les vérifier ?
Avant de voir l'offre logicielle, il faut rappeler en deux mots comment fonctionne ce système de sécurisation. Les détenteurs de ressources Internet (une ressource est typiquement un préfixe d'adresses IP) obtiennent des certificats numériques prouvant qu'ils sont titulaires de cette ressource. L'ensemble de ces certificats et des entités qui les émettent (typiquement les RIR et LIR) forment la RPKI, Resource Public Key Infrastructure. Muni de son certificat, le titulaire peut émettre des ROA (Route Origin Authorization), des objets signés avec la clé du certificat, qui déclarent quel AS a le droit d'annoncer quel préfixe. L'idée est que les routeurs BGP, recevant une annonce, vont vérifier s'il existe un objet signé authentifiant cette annonce. Sinon, ils peuvent décider de rejeter l'annonce ou bien baisser sa priorité.
Ça, c'est le principe. En pratique, pour que le système passe à l'échelle, pour éviter que les routeurs ne passent leur temps à de coûteuses opérations cryptographiques, une nouvelle classe de machine est introduite, les caches de validation. Ce sont typiquement des serveurs Unix, installés près des routeurs (probablement un cache par POP), qui recevront les ROA, les valideront et diront juste au routeur quelles sont les annonces acceptables. (Ce modèle de déploiement n'est pas le seul obligatoire mais ce sera probablement celui utilisé au début.)
Il y a donc plusieurs classes de logiciels en jeu :
Pour la première catégorie, je l'ai dit, je n'ai pas d'expérience. Il existe des logiciels spécialisés comme celui du RIPE.
Pour la seconde catégorie, les logiciels pour gérer un cache de validation, il existe deux importantes suites logicielles sous une licence libre, les outils du RIPE-NCC et rcynic. On peut aussi, pour certaines fonctions simples, utiliser des outils existants comme OpenSSL. Enfin, il existe des interfaces Web ou whois permettant de parler à des caches de validation publics.
Voyons d'abord la suite du RIPE-NCC. Elle est disponible en ligne. Elle est écrite en Java et on récupère donc un code binaire qu'on peut exécuter directement si on a un JRE. (Les exemples ci-dessous ont été faits avec la version 1, la version 2 a changé bien des choses mais est trop récente pour que j'ai eu le temps de la tester.)
% certification-validator -h usage: For detailed usage scenarios see README file. Options: ... -p,--print Show the certificate repository object in a ... -v,--verbose Show all validation steps --version Show version information
Mais le logiciel n'est rien sans les données. Il faut aussi télécharger les objets de la RPKI. Suivant le RFC 6481, le dépôt est accessible en rsync. Ainsi :
% rsync -av rsync://rpki.ripe.net/repository RPKI-repository
va installer sur votre disque dur tous les objets existants (fin 2011, sur le dépôt du RIPE, ils sont environ 3 000, des statistiques publiques sont disponibles). Une fois que c'est fait, on peut les afficher. D'abord, un certificat :
% certification-validator --print -f \ RPKI-repository/64/71d07d-c9f8-4368-87ea-162d1075dfaa/1/q3C8zU6hYpb7zVqmpjlVY5B_BWE.cer Serial: 85871 Subject: CN=q3C8zU6hYpb7zVqmpjlVY5B_BWE Not valid before: 2010-12-14T15:26:48.000Z Not valid after: 2011-07-01T00:00:00.000Z Resources: 85.118.184.0/21, 93.175.146.0/23, 2001:7fb:fd02::/47
Ensuite, une liste de révocations :
% certification-validator --print -f \ RPKI-repository/42/a01f82-9193-4199-95a8-83ae5d9c832f/1/vIp8GBZHR75QzAcTIHtf0IcdB3g.crl CRL type: X.509 CRL version: 2 Issuer: CN=bc8a7c18164747be50cc0713207b5fd0871d0778 Authority key identifier: vIp8GBZHR75QzAcTIHtf0IcdB3g= Number: 629 This update time: 2011-09-21T14:44:51.000Z Next update time: 2011-09-22T14:44:51.000Z Revoked certificates serial numbers and revocation time:
Le principal service de ce système de sécurité est de valider les ROA. Ces ROA sont distribués via rsync comme ci-dessus mais aussi disponibles en ligne. Affichons-en un :
% certification-validator --print -f roa-5574190.roa Content type: 1.2.840.113549.1.9.16.1.24 Signing time: 2011-01-11T19:04:18.000Z ASN: AS559 Prefixes: 193.5.26.0/23 [24] 193.5.152.0/22 [24] 193.5.168.0/22 [24] 193.5.22.0/24 193.5.54.0/23 [24] 193.5.58.0/24 193.5.60.0/24 193.5.80.0/21 [24]
On voit donc que tous ces préfixes peuvent être légitimement annoncés par l'AS 559. Mais avant de conclure cela, encore faut-il vérifier que le ROA est valide. On peut le valider en ligne. En local, il faut indiquer au validateur les clefs de confiance à utiliser (typiquement, les certificats des RIR, à partir desquels se fait toute la validation). Ces clés (trust anchors) sont accessibles en ligne. Une fois récupérées, on peut valider, ici avec la clé du RIPE :
% certification-validator -t tal/ripe-ncc-root.tal \ -f roa-5574190.roa --output-dir . 17:11:44,179 INFO rsync://rpki.ripe.net/ta/ripe-ncc-ta.cer is VALID 17:11:45,587 INFO rsync://rpki.ripe.net/ta/ripe-ncc-ta.crl is VALID 17:11:45,593 INFO rsync://rpki.ripe.net/ta/u75at9r0D4JbJ3_SFkZXD7C5dmg.cer is VALID 17:11:46,975 INFO rsync://rpki.ripe.net/repository/33/36711f-25e1-4b5c-9748-e6c58bef82a5/1/u75at9r0D4JbJ3_SFkZXD7C5dmg.crl is VALID 17:11:46,978 INFO rsync://rpki.ripe.net/repository/33/36711f-25e1-4b5c-9748-e6c58bef82a5/1/Uz_7R2AURj1tzQ3QylGlM-hEgx0.cer is VALID 17:11:48,183 INFO rsync://rpki.ripe.net/repository/29/c8c6f6-595c-45b1-a76e-bd192676c9bb/1/Uz_7R2AURj1tzQ3QylGlM-hEgx0.crl is VALID 17:11:48,186 INFO file:/home/bortzmeyer/tmp/roa-5574190.roa is VALID
Le logiciel a affiché toute la chaîne de validation, de la clé du RIR, jusqu'au ROA, en passant par tous les certificats intermédiaires.
La version 2 de l'outil du RIPE semble avoir supprimé les outils en ligne de commande (?) mais apporte un serveur Web qui écoute par défaut sur le port 8080 (il y a aussi un serveur RTR, cf. RFC 6810) et permet de gérer les ROA et leur validation. Par exemple, on peut définir des listes blanches de préfixe qui seront acceptés même en cas d'erreur de validation (un problème qui sera sans doute fréquent au début). On peut récupérer les anciennes versions du logiciel sur le serveur du RIPE.
Pour gérer un cache de validation, ou tout simplement pour explorer
la RPKI ou déboguer des problèmes de routage, une alternative aux
outils du RIPE-NCC est rcynic. On ne peut pas
dire qu'il brille par la convivialité de sa documentation, ni par le
support disponible, mais il
marche très bien. La compilation (rcynic est écrit en
C et en Python) à partir du dépôt
Subversion est simple (./configure &&
make && sudo make install
), mais il ne faut
pas utiliser l'option
--with-system-openssl
de
configure
en raison de la bogue Debian citée plus
bas et aussi parce que rcynic nécessite un OpenSSL très récent
(sinon, vous aurez à la compilation des erreurs concernant
v3_addr_validate_path
). rcynic s'installe ensuite
dans une jail. Le script
d'installation a fait une partie du travail mais pas tout (testé sur
une machine Ubuntu). rcynic est livré avec de
nombreux programmes mais peu d'explications de leur rôle.
rpkid
est pour les LIR (ou RIR), qui émettent des
certificats (première catégorie de logiciels, dans ma classification
plus haut). Pour
les opérateurs réseau qui gèrent des routeurs, il faut utiliser
rcynic
.
Pour terminer la configuration de la jail, en
/var/rcynic/lib
, j'ai
dû faire :
# Pour lancer facilement les programmes dans la prison # aptitude install chrootuid # Installation des bibliothèques dynamiques dans la prison # cp /lib/libpopt.so.0* /lib/i386-linux-gnu/libacl.so.1* /lib/i386-linux-gnu/libattr.so.1* /lib/i386-linux-gnu/libnss* /lib/i386-linux-gnu/libresolv* /lib/ld-linux.so.2* /lib/i386-linux-gnu/libc.so.6 /var/rcynic/lib # cp /etc/nsswitch.conf /var/rcynic/etc # Sinon, plein de messages "Host unknown"
La grande majorité des problèmes de configuration de la
jail vient de la résolution de noms. Pour tester,
copier ping dans la jail,
puis chmod u+s /var/rcynic/bin/ping
puis enfin :
% sudo chrootuid /var/rcynic rcynic /bin/ping www.google.com ping: unknown host www.google.com
Ici, il y a un problème, il faut donc vérifier que les fichiers indispensables ont bien été copiés, comme indiqué plus haut.
Ensuite, on édite /var/rcynic/etc/rcynic.conf
si on veut changer des paramètres. rcynic récupère lui-même les objets
de la RPKI. La première fois, c'est très long (cela peut prendre
plusieurs heures). Ensuite, on doit juste exécuter la commande de
temps en temps, par exemple depuis cron :
# chrootuid /var/rcynic rcynic /bin/rcynic -s -c /etc/rcynic.conf rcynic[18606]: Finished, elapsed time 3:03:54
Une fois qu'on a les données, on peut examiner un ROA :
% print_roa RPKI-repository/ff/cf59fc-653f-44eb-aca1-c5d1f27b532d/1/tyIST2Kt6P8tIxIthqPHxCj6lSY.roa Certificates: 1 CRLs: 0 SignerId[0]: b7:22:12:4f:62:ad:e8:ff:2d:23:12:2d:86:a3:c7:c4:28:fa:95:26 [Matches certificate 0] [signingTime(U) 110104093105Z] eContentType: 1.2.840.113549.1.9.16.1.24 version: 0 [Defaulted] asID: 15533 addressFamily: 1 IPaddress: 62.73.128.0/19 IPaddress: 213.212.64.0/18 addressFamily: 2 IPaddress: 2001:4138::/32
ou bien chercher un ROA en fonction d'un préfixe (chose que je n'ai pas trouvé le moyen de faire avec les outils du RIPE) :
% find_roa /var/rcynic 193.5.26.0/23 ASN 3303 prefix 193.5.26.0/23 ROA /var/rcynic/data/authenticated.2011-10-04T09:48:34Z/rpki.ripe.net/repository/29/c8c6f6-595c-45b1-a76e-bd192676c9bb/1/jOKSK_yZRVOwOqhy2iwg0AYnuV4.roa ASN 559 prefix 193.5.26.0/23 ROA /var/rcynic/data/authenticated.2011-10-04T09:48:34Z/rpki.ripe.net/repository/29/c8c6f6-595c-45b1-a76e-bd192676c9bb/1/tm9aENV_7W2xYpYsy5I1u134w8o.roa % ./find_roa /var/rcynic 62.73.128.0/19 ASN 15533 prefix 62.73.128.0/19 ROA /var/rcynic/data/authenticated.2011-10-04T09:48:34Z/rpki.ripe.net/repository/ff/cf59fc-653f-44eb-aca1-c5d1f27b532d/1/fpVFMoMEoV76BKX7gig21v-MDts.roa
Notez qu'il existe deux ROA pour le premier préfixe, car deux AS sont
autorisés à l'annoncer. Notez aussi que les ROA se trouvent dans le
répertoire authenticated
. rcynic valide les
objets au fur et à mesure de leur récupération et son programme
find_roa
ne cherche que parmi les objets
validés (les clés de confiance sont livrées avec rcynic, il n'est pas
nécessaire de les récupérer explicitement). Si on veut plus de détails sur les ROA trouvés par
find_roa
, on peut appeler
print_roa
sur le fichier trouvé :
% print_roa /var/rcynic/data/authenticated.2011-10-04T09:48:34Z/rpki.ripe.net/repository/ff/cf59fc-653f-44eb-aca1-c5d1f27b532d/1/fpVFMoMEoV76BKX7gig21v-MDts.roa Certificates: 1 CRLs: 0 SignerId[0]: 7e:95:45:32:83:04:a1:5e:fa:04:a5:fb:82:28:36:d6:ff:8c:0e:db [Matches certificate 0] [signingTime(U) 110615123707Z] eContentType: 1.2.840.113549.1.9.16.1.24 version: 0 [Defaulted] asID: 15533 addressFamily: 1 IPaddress: 176.62.128.0/21 IPaddress: 62.73.128.0/19 IPaddress: 213.212.64.0/18 addressFamily: 2 IPaddress: 2001:4138::/32
Et comment trouver, non pas le (ou les) ROA mais le certificat
correspondant à un préfixe IP donné ? La seule méthode que je
connaisse consiste en un examen systèmatique du dépôt (ici, on cherche
le titulaire de 98.128.4.0/24
) :
% for file in $(find /var/rcynic/data/authenticated.2011-10-31T13:36:08Z -name '*.cer'); do RESULT=$(openssl x509 -inform DER -text -in $file | grep 98.128.4) if [ ! -z "$RESULT" ]; then echo $file fi done /var/rcynic/data/authenticated.2011-10-31T13:36:08Z/rgnet.rpki.net/rpki/rgnet/635/hAK3Zfkl-_L6YZNsUM2T3i8GeVs.cer
Et hop,
/var/rcynic/data/authenticated.2011-10-31T13:36:08Z/rgnet.rpki.net/rpki/rgnet/635/hAK3Zfkl-_L6YZNsUM2T3i8GeVs.cer
contient le certificat convoité.
Si vous voulez tester votre cache validateur, le RIPE annonce des routes avec des ROA, dont certains délibérement invalides, pour tester.
Après ces deux paquetages, développés spécialement pour la RPKI, les outils génériques. Si on préfère utiliser les outils traditionnels, OpenSSL permet de voir les certificats de la RPKI (ils sont normalisés dans le RFC 6487, et utilisent la syntaxe standard de X.509) :
% openssl x509 -inform DER -text \ -in ./RPKI-repository/64/71d07d-c9f8-4368-87ea-162d1075dfaa/1/q3C8zU6hYpb7zVqmpjlVY5B_BWE.cer Certificate: Data: Version: 3 (0x2) Serial Number: 85871 (0x14f6f) Signature Algorithm: sha256WithRSAEncryption Issuer: CN=5XxoZDVUZvaNYJcVATAgTQ2ifLQ Validity Not Before: Dec 14 15:26:48 2010 GMT Not After : Jul 1 00:00:00 2011 GMT Subject: CN=q3C8zU6hYpb7zVqmpjlVY5B_BWE ... X509v3 extensions: X509v3 Subject Key Identifier: AB:70:BC:CD:4E:A1:62:96:FB:CD:5A:A6:A6:39:55:63:90:7F:05:61 X509v3 Authority Key Identifier: keyid:E5:7C:68:64:35:54:66:F6:8D:60:97:15:01:30:20:4D:0D:A2:7C:B4 X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: critical Certificate Sign, CRL Sign Authority Information Access: CA Issuers - URI:rsync://rpki.ripe.net/ta/5XxoZDVUZvaNYJcVATAgTQ2ifLQ.cer Subject Information Access: CA Repository - URI:rsync://rpki.ripe.net/repository/1a/08941d-c629-44be-9708-fc9c3753f8cd/1/ 1.3.6.1.5.5.7.48.10 - URI:rsync://rpki.ripe.net/repository/1a/08941d-c629-44be-9708-fc9c3753f8cd/1/q3C8zU6hYpb7zVqmpjlVY5B_BWE.mft X509v3 CRL Distribution Points: ...
Mais les extensions du RFC 3779, cruciales pour la RPKI, sont juste affichées en binaire :
sbgp-ipAddrBlock: critical 0%0.....0....Uv....]..0.....0.... .....
Le problème est en fait que, sur ma machine
Debian, OpenSSL a bien le code nécessaire mais
il n'est pas compilé avec la bonne option. Il faut recompiler avec
./config enable-rfc3779
ce que ne fait hélas pas
Debian (vous pouvez insister pour ce changement via la bogue #630790, notez que la non-prise en compte
du RFC 3779 était peut-être due à CVE-2011-4577.).
Une fois OpenSSL compilé avec les bonnes options, on voit le
certificat entier :
X509v3 Certificate Policies: critical Policy: 1.3.6.1.5.5.7.14.2 sbgp-ipAddrBlock: critical IPv4: 85.118.184.0/21 93.175.146.0/23 IPv6: 2001:7fb:fd02::/47
Il existe d'autres outils qui affichent le X.509 et qui semblent capable d'afficher proprement du CMS, comme Legion of Bouncy Castle mais je ne les ai pas testés.
Enfin, dernière façon de regarder et de valider les objets de la RPKI, les services hébergés, comme celui de BGPmon. Il est accessible entre autres par whois :
% whois -h whois.bgpmon.net " --roa 28001 200.7.86.0/23" 0 - Valid ------------------------ ROA Details ------------------------ Origin ASN: AS28001 Not valid Before: 2011-01-07 02:00:00 Not valid After: 2012-08-05 03:00:00 Trust Anchor: repository.lacnic.net Prefixes: 200.7.86.0/23 (max length /24) 2001:13c7:7012::/47 (max length /47) 2001:13c7:7002::/48 (max length /48) 200.3.12.0/22 (max length /24) % whois -h whois.bgpmon.net " --roa 2801 200.7.86.0/23" 2 - Not Valid: Invalid Origin ASN, expected 28001
On voit que l'AS 28001 a le droit d'annoncer
200.7.86.0/23
(le ROA autorise également trois
autres préfixes) mais que le 2801 n'a pas le droit.
Dans le même état d'esprit (validateur accessible via le réseau),
on peut aussi se servir d'un looking
glass comme celui de LACNIC ou de leur service REST (voyez par exemple l'état de l'annonce http://www.labs.lacnic.net/rpkitools/looking_glass/rest/valid/cidr/200.7.84.0/23/
).
Maintenant, troisième catégorie, il faut aussi du logiciel sur le routeur lui-même, pour interroger le cache validant. Pour les mises en œuvre de BGP libres comme Quagga, on peut utiliser, par exemple, bgp-srx. Le LACNIC a documenté l'état du logiciel, et la façon de s'en servir, pour plusieurs modèles de routeurs : JunOS, et Quagga. Le RIPE-NCC a produit une documentation pour les Juniper et Cisco.
Si on veut jouer avec un vrai routeur
vivant, EuroTransit a configuré des routeurs
Juniper publiquement accessibles par telnet :
193.34.50.25
et
193.34.50.26
. Utilisateur "rpki", mot de passe
"testbed" et le tout est
documenté. Il y a aussi juniper.rpki.netsign.net
(rpki/testbed).
% telnet 193.34.50.25 Trying 193.34.50.25... Connected to 193.34.50.25. Escape character is '^]'. RPKI testbed router connected to RIPE RPKI Validator (cache server) hosted by EuroTransit GmbH For further information about this RPKI testbed: http://rpki01.fra2.de.euro-transit.net Unauthorized access prohibited Authorized access only This system is the property of EuroTransit GmbH Disconnect IMMEDIATELY if you are not an authorized user! Contact 'noc@nmc.euro-transit.net' for help. lr1.ham1.de (ttyp0) login: rpki Password: Last login: Tue Dec 13 19:31:05 from 213.211.192.18 --- JUNOS 10.3I built 2011-04-05 18:23:14 UTC rpki@lr1.ham1.de> [La validation sur ce Juniper] rpki@lr1.ham1.de> show validation statistics Total RV records: 1517 Total Replication RV records: 2976 Prefix entries: 1412 Origin-AS entries: 1517 Memory utilization: 446892 bytes Policy origin-validation requests: 13907256 Valid: 41302 Invalid: 39656 Unknown: 13826298 BGP import policy reevaluation notifications: 27490 inet.0, 27490 inet6.0, 0 [Les communications avec le cache, suivant le protocole RTR.] rpki@lr1.ham1.de> show validation session Session State Flaps Uptime #IPv4/IPv6 records 195.13.63.18 Up 1015 00:53:27 1207/310 rpki@lr1.ham1.de> show validation database origin-autonomous-system 15533 RV database for instance master Prefix Origin-AS Session State Mismatch 62.73.128.0/19-19 15533 195.13.63.18 valid 176.62.128.0/21-21 15533 195.13.63.18 valid 213.212.64.0/18-18 15533 195.13.63.18 valid 2001:4138::/32-32 15533 195.13.63.18 valid IPv4 records: 3 IPv6 records: 1 [Notez le maxlength exprimé sous forme de deux chiffres, toujours identiques ici mais qui ne le sont pas forcément.]
Et si on veut un Cisco ? telnet rpki-rtr.ripe.net
, utilisateur « ripe », pas de mot de passe :
rpki-rtr>show ip bgp rpki table 1187 BGP sovc network entries using 104456 bytes of memory 1280 BGP sovc record entries using 25600 bytes of memory Network Maxlen Origin-AS Source Neighbor 24.232.0.0/16 32 10318 0 193.0.19.44/8282 31.3.8.0/21 21 5524 0 193.0.19.44/8282 ... rpki-rtr>show ip bgp 62.73.128.0 BGP routing table entry for 62.73.128.0/19, version 1865228 Paths: (2 available, best #1, table default) Not advertised to any peer Refresh Epoch 1 12654 50300 15533 193.0.4.1 from 193.0.4.28 (193.0.4.28) Origin IGP, localpref 110, valid, external, best path 58970BAC RPKI State valid Refresh Epoch 1 12654 50300 15533, (received-only) 193.0.4.1 from 193.0.4.28 (193.0.4.28) Origin IGP, localpref 100, valid, external path 58970B68 RPKI State valid [Regardez la dernière ligne, ci-dessus.]
Il faudra aussi apprendre à déboguer les annonces invalides. Si on se fie à l'expérience d'un autre système de sécurité, DNSSEC, il y aura des plantages, et souvent. Mais On n'a pas le choix: tant qu'on ne déploie pas pour de bon, ça ne marchera pas.
Autres logiciels que je n'ai pas eu le temps de tester (il existe une liste à peu près à jour) :
Quelques autres lectures sur ce sujet :
Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)
Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)