Movatterモバイル変換


[0]ホーム

URL:


SwordArMor

Sécurisation du routage BGP en utilisant ASPA avec routinator et bird (cas de Breizh-IX)

Publié le Wed 22 January 2025
Rédigé paralarig dans la catégorieactus

Le BGP est un protocole de routage dynamique qui se base historiquement sur la confiance. En théorie, n’importe qui peut plus ou moins annoncer n’importe quoi, et ça sera pris en compte. En pratique, les peerings BGP sont protégés par des prefix-lists afin de ne propager que ce qui est réellement voulu. Mais cela implique que chaque opérateur soit extrêment consciencieux, et cela étant bien sûr impossibles, nous pouvons recenser denombreux incidents. De nombreuses techniques de préventions ont donc été mises en place au fur et à mesure, et l’ASPA est complémentaires à celles déjà en place. C’est discuté en paragraphe 9 « Comparison to Other Technologies ».

Nous avons vu arriver en février 2012 l’une de ces technique : les Route Origin Authorizations (ROAs) par laRFC 6482. En se basant la Resource Public Key Infrastructure (RPKI) nous pouvons cryptographiquement signer la relation entre un préfixe et le (ou les) AS source ; ainsi, un préfixe annoncé par erreur par un AS se verra très fortement filtré. Cela ne protège par contre pas des attaques volontaires car il suffit de prepend le bon AS lors de l’annonce afin de faire correspondre la source avec le ROA et tout se passera comme si de rien n’était. Petit aparté sur les chiffres : à la fin janvier 2025 je vois 519213 ROAs sur 1001519 annonces (en IPv4), soit un peu plus de la moitié. Je n’ai pas de métriques sur les ASes qui vérifient ou non les ROAs, mais il est clair qu’un transitaire qui ne le fait pas en 2025 est à fuir comme la peste.

Depuis 2019 une discussion est actuellement ouverte à l’IETF afin de pouvoir étendre la RPKI à la vérification de l’AS path au lieu d’uniquement l’AS source, c’estl’ASPA (Autonomous System Provider Authorization). L’idée est qu’un AS va publier quels sont ses fournisseurs, et si un préfixe (signé en ROA évidemment) est vu avec un chemin qui n’a rien à voir avec la choucroute, l’annonce sera rejetée. C’est un peu à voir comme la version 2 des IRRs que l’on trouve dans les whois d’AS.
Tout ceci étant encore en draft, il n’est pas encore possible de publier des entrées ASPA depuis une CA hébergée directement par un RIR, il faut l’héberger soi-même (par exemple aveckrill). Cela limite donc grandement l’adoption, ce qui fait que nous avons une table comprenantseulement 81 entrées. Du côté de la vérification, le support a été ajouté avecbird 2.16, et pour la diffusion des entrées, le support via RTR a été ajouté avecroutinator 0.14.1. Ce n’est pas un hasard si je suivais l’évolution de ces deux logiciels, car ils font partie de la stack du second serveur de routes deBreizh-IX.

Breizh-IX est un point d’échange rennais dont je m’occupe. Comme l’immense majorité des points d’échange nous proposons des serveurs de route, et comme j’aime les choses bien faites je préfère éviter d’annoncer des routes fallacieuses aux membres de l’IX. Pour se faire nous avions déjà mis en place les choses de base comme la vérification des ROAs et la génération de listes de préfixes pour chaque membre, mais aussi des choses moins connues comme la vérification de l’attribut Only to Customer (OTC). Aujourd’hui un pas de plus est fait avec l’ajout d’ASPA.

La mise en place de la partie validation est très simple, il suffit de compiler routinator en version 0.14.1, d’installer les binaires, d’ajouterenable-aspa = true dans le fichier de configuration et de redémarrer le daemon.
Maintenant que notre serveur RTR (ici routinator) supporte ASPA, il ne reste plus qu’à dire à bird de le prendre en compte.
Après avoir également compilé et installé la version 2.16, il faut créer une table en plus qui servira à stocker les entrées ASPA (en plus de celles pour les ROAs IPv4 et IPv6), et de l’ajouter au protocole RPKI qui correspond au routinator :

roa4 table r4;roa6 table r6;aspa table at;protocol rpki rpki_conan {remote "conan.grifon.fr";roa4 { table r4; };roa6 { table r6; };aspa { table at; };}

Ensuite au reload, le protocole devrait être négocié en version 2 et la nouvelle table va se remplir :

[root@rs2 ~]# birdcBIRD 2.16 ready.bird> show protocols all rpki_conanName       Proto      Table      State  Since         Inforpki_conan RPKI       ---        up     20:59:54.811  Established  Cache server:     89.234.186.8  Status:           Established  Transport:        Unprotected over TCP  Protocol version: 2  Session ID:       12256  Serial number:    19  Last update:      before 504.687 s  Refresh timer   : 648.312/1153  Retry timer     : ---  Expire timer    : 6695.312/7200  Channel roa4    State:          UP    Table:          r4    Preference:     100    Input filter:   ACCEPT    Output filter:  REJECT    Routes:         519235 imported, 0 exported, 83 preferred    Route change stats:     received   rejected   filtered    ignored   accepted      Import updates:         519247          0          0          0     519247      Import withdraws:           12          0        ---          0         12      Export updates:              0          0          0        ---          0      Export withdraws:            0        ---        ---        ---          0  Channel roa6    State:          UP    Table:          r6    Preference:     100    Input filter:   ACCEPT    Output filter:  REJECT    Routes:         126571 imported, 0 exported, 31 preferred    Route change stats:     received   rejected   filtered    ignored   accepted      Import updates:         126589          0          0          0     126589      Import withdraws:           18          0        ---          0         18      Export updates:              0          0          0        ---          0      Export withdraws:            0        ---        ---        ---          0  Channel aspa    State:          UP    Table:          at    Preference:     100    Input filter:   ACCEPT    Output filter:  REJECT    Routes:         81 imported, 0 exported, 81 preferred    Route change stats:     received   rejected   filtered    ignored   accepted      Import updates:             81          0          0          0         81      Import withdraws:            0          0        ---          0          0      Export updates:              0          0          0        ---          0      Export withdraws:            0        ---        ---        ---          0

Nous pouvons maintenant utiliser les données de cette table dans les filtres d’entrée, grâce à la fonction intégréeaspa_check :

# https://www.ietf.org/archive/id/draft-ietf-sidrops-aspa-verification-20.html#name-algorithm-for-upstream-pathcase aspa_check(at, bgp_path, true) {ASPA_INVALID:igp_metric = 12;reject "Invalid ASPA:", net, bgp_path;ASPA_VALID:igp_metric = 10;ASPA_UNKNOWN:igp_metric = 11;}

Le premier paramètre de la fonction est la table depuis laquelle nous tirons les informations, le second est l’AS path à évaluer et la dernière est l’algorithme de vérification à utiliser. Les deux premiers étant assez évidents, je vais uniquement m’attarder sur le dernier.
Dans la version actuelle d’ASPA (draft v20), il existe deux algorithmes : un pour évaluer des routes upstream, et un autre pour les routes downstream. Il est explicitement écrit qu’un serveur de route doit utiliser l’algorithme upstream :

The upstream verification algorithm described here is applied when a route is received from a Customer or Peer, or is received by an RS from an RS-client, or is received by an RS-client from an RS.

6.2. Algorithm for Upstream Paths

Les routes ayant un seul AS sur le chemin sont automatiquement considérées comme valides, et bird respecte bien cela :

bird> show route all where igp_metric = 10Table master4:45.94.17.0/24        unicast [bgp_20766_185_1_89_28 21:04:43.510] * (100) [AS20766i]via 185.1.89.28 on vtnet1Type: BGP univigp_metric: 10BGP.origin: IGPBGP.as_path: 20766BGP.next_hop: 185.1.89.28BGP.local_pref: 100BGP.community: (20766,1)BGP.ext_community: BGP.large_community: (206165, 100, 0)45.67.83.0/24        unicast [bgp_207910_185_1_89_26 21:04:43.617] * (100) [AS207910i]via 185.1.89.26 on vtnet1Type: BGP univigp_metric: 10BGP.origin: IGPBGP.as_path: 207910BGP.next_hop: 185.1.89.26BGP.local_pref: 100BGP.ext_community: BGP.large_community: (206165, 100, 0)185.204.199.0/24     unicast [bgp_211733_185_1_89_39 21:04:45.785] * (100) [AS211733i]via 185.1.89.39 on vtnet1Type: BGP univigp_metric: 10BGP.origin: IGPBGP.as_path: 211733BGP.next_hop: 185.1.89.39BGP.local_pref: 100BGP.ext_community: BGP.large_community: (206165, 100, 0)193.222.128.0/24     unicast [bgp_34019_185_1_89_36 21:04:48.454] * (100) [AS34019i]via 185.1.89.36 on vtnet1Type: BGP univigp_metric: 10BGP.origin: IGPBGP.as_path: 34019BGP.next_hop: 185.1.89.36BGP.med: 75BGP.local_pref: 100BGP.community: (34019,34019)BGP.ext_community: BGP.large_community: (206165, 100, 0)37.157.128.0/21      unicast [bgp_57943_185_1_89_19 21:04:43.486] * (100) [AS57943?]via 185.1.89.19 on vtnet1Type: BGP univigp_metric: 10BGP.origin: IncompleteBGP.as_path: 57943BGP.next_hop: 185.1.89.19BGP.local_pref: 100BGP.ext_community: BGP.large_community: (206165, 100, 0)[…]

Nous n’avons pas de route invalide et les autres routes ont bien le statut inconnu :

bird> show route all filtered where igp_metric = 12bird> bird> show route all where igp_metric = 11Table master4:37.60.157.0/24       unicast [bgp_34019_185_1_89_36 21:04:44.346] * (100) [AS201080i]via 185.1.89.36 on vtnet1Type: BGP univigp_metric: 11BGP.origin: IGPBGP.as_path: 34019 201080BGP.next_hop: 185.1.89.36BGP.med: 75BGP.local_pref: 100BGP.community: (34019,20108) (34019,64512) (65512,20001)BGP.ext_community: BGP.large_community: (206165, 100, 0)195.190.3.0/24       unicast [bgp_34019_185_1_89_36 21:04:48.670] * (100) [AS47612i]via 185.1.89.36 on vtnet1Type: BGP univigp_metric: 11BGP.origin: IGPBGP.as_path: 34019 35600 47612BGP.next_hop: 185.1.89.36BGP.med: 75BGP.local_pref: 100BGP.community: (34019,35600) (34019,64512)BGP.ext_community: BGP.large_community: (206165, 100, 0)45.67.83.0/24        unicast [bgp_204092_185_1_89_13 21:04:43.555] (100) [AS207910i]via 185.1.89.13 on vtnet1Type: BGP univigp_metric: 11BGP.origin: IGPBGP.as_path: 204092 207910BGP.next_hop: 185.1.89.13BGP.local_pref: 100BGP.community: (64496,200)BGP.ext_community: BGP.large_community: (204092, 100, 200) (206165, 100, 0)                     unicast [bgp_34019_185_1_89_36 21:04:44.684] (100) [AS207910i]via 185.1.89.36 on vtnet1Type: BGP univigp_metric: 11BGP.origin: IGPBGP.as_path: 34019 207910BGP.next_hop: 185.1.89.36BGP.med: 75BGP.local_pref: 100BGP.community: (34019,20791) (34019,64512) (65512,20001)BGP.ext_community: BGP.large_community: (206165, 100, 0)185.20.5.0/24        unicast [bgp_34019_185_1_89_36 21:04:47.976] * (100) [AS56648i]via 185.1.89.36 on vtnet1Type: BGP univigp_metric: 11BGP.origin: IGPBGP.as_path: 34019 35600 56648BGP.next_hop: 185.1.89.36[…]

Si nous étions en train de vérifier les annonces d’un fournisseur, nous aurions dû appliquer l’algorithme downstream. Pourquoi avoir deux algorithmes ? Car lors d’une relation client-fournisseur il n’est pas possible de savoir si le fournisseur a appris la route sur un peering ou via l’un des transits de l’AS source (qu’ils auraient en communs). Nous ne pouvons donc pas strictement rechercher si l’un des ASes dans l’entrée ASPA est dans l’AS path, et on se contente alors d’estimer le statut de la route par rapport à longueur de l’AS path.
Par exemple, si on prend une route vers telenor (AS2119) du point de vue de gitoyen (AS20766)

Graphe BGP AS20766 →     AS2119

Pour un ordinateur il n’est pas possible de deviner quels sont les chemins légitime ou pas. En tant qu’humain, comme j’ai géré le peering de gandi avant que ça ne tourne au FullBullshit™ et que je connais le peering manager de ielo, je sais que ces deux ASes ont un peering avec telenor, et donc que ces deux chemin sont fiables. Cette théorie se confirme avec un mtr vers l’une des IPs du range qui montre que ça passe par l’AMS-IX :

grifon@gitoyen01:~$ mtr -bzwe 148.122.1.1Start: 2025-01-22T23:16:35+0000HOST: gitoyen01.ring.nlnog.net                                    Loss%   Snt   Last   Avg  Best  Wrst StDev  1. AS20766  x-ray.probe.gitoyen.net (80.67.163.243)              0.0%    10    0.3   0.2   0.2   0.3   0.0  2. AS20766  vodka.gitoyen.net (80.67.168.7)                      0.0%    10    0.9   0.6   0.4   1.3   0.3  3. AS20766  gandi-pa3.gitoyen.net (80.67.168.149)                0.0%    10    0.7   0.7   0.5   1.5   0.3  4. AS???    ti9000b400.ti.telenor.net (80.249.209.192)           0.0%    10   10.7   9.9   9.3  13.0   1.2  5. AS2119   ti3003c400-ae13-0.ti.telenor.net (146.172.105.37)    0.0%    10   29.1  29.7  29.1  31.3   0.9       [MPLS: Lbl 9197 TC 0 S u TTL 1]  6. AS???    ???                                                 100.0    10    0.0   0.0   0.0   0.0   0.0  7. AS2119   ti0001b400-ae0-0.ti.telenor.net (146.172.105.49)     0.0%    10   29.0  29.9  28.9  38.0   2.8  8. AS2119   148.122.9.50                                         0.0%    10   30.2  29.4  29.2  30.2   0.3  9. AS2119   tix01c01-fge1-17.tix.telenor.net (148.122.2.81)      0.0%    10   29.2  29.3  29.2  29.6   0.1       [MPLS: Lbl 29 TC 0 S u TTL 1]       [MPLS: Lbl 648 TC 0 S u TTL 1] 10. AS2119   tix01d01-fge7-1.tix.telenor.net (148.122.2.66)       0.0%    10   29.3  29.6  29.2  32.1   0.9       [MPLS: Lbl 648 TC 0 S u TTL 1] 11. AS2119   148.122.205.225                                      0.0%    10   30.0  29.9  29.3  32.7   1.0 12. AS2119   tix01d01-ec2-v100.tix.telenor.net (148.122.205.25)   0.0%    10   31.2  29.6  29.1  31.2   0.6 13. AS2119   part1.online.no (148.122.1.1)                        0.0%    10   29.3  29.4  29.3  29.8   0.1

L’IRR de l’AS2119 nous dit que les deux upstreams connus sont telia et level3 et dtag est censé être un peering :

alarig@x280 ~ % whois AS2119 | grep 'accept ANY'import:         from AS1299 action pref=100; accept ANYimport:         from AS3356 action pref=100; accept ANYalarig@x280 ~ % whois AS2119 | grep 3320import:         from AS3320 action pref=100; accept AS3320:AS-DTAGexport:         to AS3320 announce AS-TELENOR

Si telenor publiait une entrée ASPA, elle contiendrait a priori les ASes 1299 et 3356. La route que nous voyons ici via telia aurait alors le statut valide. Les deux routes par gandi ou ielo auraient le statut inconnu. Nous pouvons par contre légitimement nous demander si le chemin via Hopus et DTAG est entièrement légitime ou non ; mais les IRRs étant principalement là à titre indicatif, nous ne pouvons pas nous baser dessus à 100%. Bien que DTAG soit un tier 1 de piètre qualité, il serait tout de même étonnant qu’ils réannoncent les préfixes d’un opérateur national sans que ce ne soit l’un de leur clients, même si ce n’est jamais à exclure non plus. En effet, dans ce cas présent la politique tarifaire d’Hopus fait que DTAG gagne de l’argent sur le trafic qui rentre dans son réseau sur ce port. Afin d’augmenter le volume dudit trafic, ils peuvent très bien ré-annoncer leurs peers en plus de leurs clients, bien que ça soit contraire aux pratiques communes.

mautrix-signal ⚠ Your message may not have been bridged: 110: Verification failure in zkgroup

Publié le Wed 29 May 2024
Rédigé paralarig dans la catégorieactus

Pour éviter d’avoir plein d’applications de messagerie instantanée sur mon téléphone, je bridge tout dans matrix et je n’utilise directement que matrix. Ma machine matrix était sur une infra d’hypervision que je n’ai plus vraiment envie d’utiliser, et j’ai depuis une plus grosse …

Lire la suite

Le concept d’empty non terminal (ENT) en DNS, et son interaction avec les wildcards

Publié le Fri 19 May 2023
Rédigé paralarig dans la catégorieactus

Cet article est écrit en collaboration avecAxel Viala. Tout au long de l’article nous parlons de serveurs faisant autorité, les révolveurs n’ayant pas ce cas à gérer.

Sur un nom de domaine, on peut se retrouver avec des sous-domaines vides mais ayant des enfants. Nous appelons cela …

Lire la suite

Faire tenir la charge à une instance mastodon malgré Musk

Publié le Wed 16 November 2022
Rédigé paralarig dans la catégorieactus

Si vous lisez ce blog, vous savez sûrement qu’un riche mégalomane étasunien a racheté twitter, et qu’on en attendait pas moins de son mode de gestion. Cela a entraîné un exode vers mastodon, qui ronronnait tranquillement dans son coin jusqu’ici.
Je vais ici partager les différentes actions …

Lire la suite

Avoir une sorte de flowspec sous linux avec ipset

Publié le Sun 10 April 2022
Rédigé paralarig dans la catégorieactus

Internet étant truffé de machines plus ou moins vérolées qui scannent le monde entier, j’ai eu envie de les bloquer à l’échelle complète de mon réseau ; un genre de fail2ban2bgp.
Avec netfilter il n’existe pas de mécanisme pour avoir des règles dynamiques, et donc pas de moyen …

Lire la suite

Remonter le constructeur et le modèle d’un serveur en SNMP

Publié le Tue 10 August 2021
Rédigé paralarig dans la catégorieactus

Par défaut, la configuration de net-snmpd ne remonte pas le constructeur et le modèle d’un serveur, ce qui fait que LibreNMS (ou Observium) vont afficher « Generic x86 64-bit » là où on pourrait avoir « Dell Inc. [PowerEdge R510] » ou « HP [ProLiant DL320e Gen8] », ce qui rend plus facile l’inventorisation …

Lire la suite

Installer son instance mastodon sous Gentoo

Publié le Sun 31 January 2021
Rédigé paralarig dans la catégorieactus

Suite à l’annonce de Valère d’arrêter les services hostux, et donc l’instance mastodon, j’ai décidé de monter la mienne. La principale raison est que je n’ai pas trouvé d’autre instance en Europe avec un TLSA. Je ne vais pas ici expliquer toute l’installation …

Lire la suite

Désactivation de la souris pour urxvt et terminator (et autres terminaux basés sur VTE)

Publié le Sun 09 February 2020
Rédigé paralarig dans la catégorieactus

Depuis quelques temps, le support de la souris est activé par défaut sur certaines applications CLI, notamment vim. Ceci empêche d’utiliser le presse-papier « clic milieu » et ne sert en outre à rien, c’est donc fort ennuyeux.

J’ai un peu cherché comment désactiver le support de la souris …

Lire la suite

Vérification RPKI avec routinator, bird et IOS-XE

Publié le Mon 13 January 2020
Rédigé paralarig dans la catégorieactus

Quand on fait partie de la DFZ, on peut en gros annoncer n’importe quel préfixe tant que ça passe les filtres de nos pairs, et on est censé leur faire plus ou moins confiance. Sauf que croire encore à ce système de la confiance en 2020, c’est aussi …

Lire la suite

Remplir la table SNMP ifAlias sous Linux

Publié le Sun 20 October 2019
Rédigé paralarig dans la catégorieactus

Il m’arrive encore de jouer avec des routeurs soft, et comme à chaque fois il faut bricoler pour avoir ce que l’on veut, ici avoir une table ifAlias correcte. À une époque je le faisais avec FreeBSD, et j’avais trouvé la parade en utilisant un proxy vers …

Lire la suite

[8]ページ先頭

©2009-2025 Movatter.jp