diff --git a/README.md b/README.md new file mode 100644 index 0000000..dc67f07 --- /dev/null +++ b/README.md @@ -0,0 +1,227 @@ +# Babel Tester + +Ce script permet de simuler un petit réseau de quelques nœuds et d'exécuter +[babeld](https://github.com/jech/babeld) afin d'étudier son comportement. + +Le but est avant tout de modéliser le comportement d'un réseau dans le cas +de pare-feux restrictifs, bloquant par exemple de gros traffics ou certains +ports, et de réfléchir à une façon de calculer une route en tenant compte +de ces comportements. + +Pour cela, on utilise la notion de *namespaces* introduite dans la version +3.8 du noyau Linux, qui permet d'avoir des espaces séparés avec différentes +configurations système, en particulier différentes configurations réseau. +On construit donc différents namespaces permettant de simuler plusieurs +routeurs avec différentes configurations au sein de sa même machine. + + +## Démo + +Dans cet exemple, on construit le réseau suivant : + + + EXT + | + | + +------+ + |NŒUD 1| + +------+ + / \ + 1 / \1 + / \ + / \ + +------+ 1,2 +------+ + |NŒUD 2|----------------|NŒUD 3| + +------+ +------+ + \ / + \ / + 2\ /2 + \ / + +------+ + |NŒUD 4| + +------+ + + +4 nœuds sont créés et connectés dans 2 sous-réseaux différents : le +premier englobe les 3 premiers nœuds et le second les trois derniers. +De plus, le premier nœud est connecté à la machine hôte qui sait router +vers l'extérieur. Elle dispose d'une route par défaut vers la machine +hôte. + +On peut représenter plus en détails le réseau avec les différentes +interfaces connectées et leurs IP : + + EXT + 0.0.0.0/0 (default) + ::/0 (default) + | + | + +-----------------+ + | + | + eth0 vde0 + 172.16.43.152/24--------HÔTE-----------10.2.1.1/30 + 2a0c:700:3012:3:4000:ff:fe01:5243 2a0c:700:3012:3::ff:0/127 + | + | + +-----------------------------------+ + | + | + vde0 vde1 + 10.2.1.2/30---------NŒUD 1---------172.17.1.1/32-------+ + 2a0c:700:3012:3::ff:1/127 2a0c:700:3012:3::1:1/128 | + | + | + | + vde2 vde1 | + +-------172.17.2.2/32---------NŒUD 2---------172.17.1.2/32-------+ + | 2a0c:700:3012:3::2:2/128 2a0c:700:3012:3::1:2/128 | + | | + | | + | | + | vde2 vde1 | + +-------172.17.2.3/32---------NŒUD 3---------172.17.1.3/32-------+ + | 2a0c:700:3012:3::2:3/128 2a0c:700:3012:3::1:3/128 + | + | + | + | vde2 + +-------172.17.2.4/32---------NŒUD 4 + 2a0c:700:3012:3::2:4/128 + + +Les IPv6 de lien local n'ont pas été représentées, mais elles existent +bien sûr sur chacune des interfaces, et ont leur pleine importance dans +le calcul des routes. + +Une fois les nœuds et interfaces configurés, ``babeld`` est lancé sur +chacune des interfaces, afin de calculer les différentes routes. +Le nœud 1 expose de plus les routes qu'il connaît pour les communiquer +à ses voisins, via l'option ``redistribute metric 256``. + +Afin de modéliser les problèmes sur le réseau, un pare-feu peut-être +installé sur le nœud 2 ou le nœud 3 afin d'intercepter une partie du +trafic. Dans cet exemple, un pare-feu est présent bloquant toutes +les requêtes de type 80/TCP. + +Pour faciliter les communications avec l'extérieur, des règles de NAT +en IPv4 sont définies au niveau de la machine hôte. + + +## Lancer la démonstration + +Le script est conçu pour être exécuté avec des dépendances minimales : + + * babeld + * nftables (pour le pare-feu) + * tmux (pour la gestion des namespaces) + * vdeplug (>= 4.0) (pour la gestion des interfaces virtuelles) + +Le script est testé sous Debian Bullseye et Arch Linux, le résultat +n'est pas garanti sur d'autres distributions. + + /!\ Les IP sont pour le moment hardcodées dans le script. Si en + IPv4 le NAT permet d'avoir une configuration plus ou moins + indépendante de votre réseau, vous devez avoir une bonne + configuration de routage vers l'extérieur en IPv6, par exemple + à l'aide d'une délégation de préfixe qui pointent vers la machine + hôte. Ici, les préfixes 2a0c:700:3012:3::1:0/112, + 2a0c:700:3012:3::2:0/112 et 2a0c:700:3012:3::ff:0/112 sont + délégués. + +La machine hôte doit ensuite connaître les routes en IPv4 +et en IPv6 vers le reste du réseau en passant par le premier nœud. +Cela pourrait se faire simplement en ajoutant la machine hôte au +réseau babel, afin de connaître toutes les routes. Afin de +limiter le réseau Babel aux namespaces virtuels, et de n'utiliser +la machine hôte qu'en guise de passerelle entre le réseau Babel +de test et le monde extérieur, le choix a été fait d'ajouter les +routes vers le réseau Babel à la main, en IPv4 et en IPv6. +Les routes de la machine hôte vers les nœuds virtuels sont gérés +directement par le script, ne manque qu'à router les bons préfixes +vers cette machine. + +Vous devez ensuite configurer votre hôte pour router les paquets +IPv4 et IPv6. Pour cela, créez si ce n'est pas déjà fait un fichier +``/etc/sysctl.d/99-forward.conf`` dans lequel vous rentrez les +options : + + net.ipv4.ip_forward=1 + net.ipv6.conf.all.forwarding=1 + +La configuration peut être rechargée via ``sudo sysctl --system``. +Pour uniquement tester sans rendre la configuration persistante, +executez simplement : + + $ sudo sysctl -w net.ipv4.ip_forward=1 + $ sudo sysctl -w net.ipv6.conf.all.forwarding=1 + +L'exemple peut désormais être lancé, en tant de ``root`` afin de +pouvoir configurer la sortie vers l'extérieur : + + $ sudo ./start.sh + +Un terminal ``tmux`` va ensuite s'ouvrir. Dans l'onglet principal, +vous serez dans le namespace principal, rien a changé. Une interface +virtuelle ``vde0`` a toutefois été ajoutée, permettant de communiquer +avec les namespaces. + +4 onglets tmux font sinon leur apparition, correspondant à chacun +des namespaces. Leurs interfaces sont décrites selon le schéma +présenté ci-dessus. Les IP sont ajoutées automatiquement par le +script, manuellement. Afin de laisser babeld faire son travail, les +IP sont volontairement mises dans un /32 ou un /128, afin de ne +communiquer exclusivement par les IP de lien local. +La configuration de babeld est montée dans ``/etc/babeld.conf``, +et le fichier de logs reste monté dans ``/var/log/babeld.log``. + +Une fois les namespaces créés et les interfaces configurées, ``babeld`` +est lancé sur chacun des namespaces. Quelques secondes plus tard, +les routes apparaîtront dans chacun des namespaces. + +Pour mettre le trafic IPv4 de sortir, une règle NAT basique est +appliquée au niveau de la machine hôte grâce à ``nftables``, +voir ``firewall/nat.conf``. + +Pour modéliser les restrictions au niveau du réseau, un pare-feu est +également chargé au niveau des nœuds 2 et 3, interdisant le trafic +HTTP uniquement (port 80/TCP). À terme, seul un seul des nœud bloquera +le trafic, qui sera le nœud privilégié presque sûrement par Babel. + +Pour tester, dans le namespace 4 : + + $ ip r + default via 172.17.2.2 dev vde2 proto babel onlink + 10.2.1.0/30 via 172.17.2.2 dev vde2 proto babel onlink + 10.2.1.2 via 172.17.2.2 dev vde2 proto babel onlink + 172.17.1.1 via 172.17.2.2 dev vde2 proto babel onlink + 172.17.1.2 via 172.17.2.3 dev vde2 proto babel onlink + 172.17.1.3 via 172.17.2.3 dev vde2 proto babel onlink + 172.17.2.2 via 172.17.2.3 dev vde2 proto babel onlink + 172.17.2.3 via 172.17.2.3 dev vde2 proto babel onlink + + $ ping crans.org -c 1 + PING (185.230.79.10) 56(84) octets de données. + 64 octets de hodaur.crans.org (185.230.79.10) : icmp_seq=1 ttl=52 + temps=21.0 ms + + --- statistiques ping --- + 1 paquets transmis, 1 reçus, 0% packet loss, time 0ms + rtt min/avg/max/mdev = 21.001/21.001/21.001/0.000 ms + + $ curl http://crans.org + curl: (7) Failed to connect to crans.org port 80: Connexion refusée + + $ curl https://crans.org + + 302 Found + +

302 Found

+
nginx/1.14.2
+ + + + +On constate donc que le namespace 4 sait sortir, en passant soit par +le nœud 2 soit le nœud 3, peut effectuer par exemple des requêtes HTTPS +mais pas de requête HTTP.