9.5 KiB
Babel Tester
Ce script permet de simuler un petit réseau de quelques nœuds et d'exécuter 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 du nœuds 2, interdisant le trafic HTTP uniquement (port 80/TCP). De plus, le voisin 3 est marqué comme non-priviligié afin que Babel choisisse la route congestionnée par le nœud 2.
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
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.14.2</center>
</body>
</html>
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.