228 lines
9.5 KiB
Markdown
228 lines
9.5 KiB
Markdown
# 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
|
||
<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.
|