📝 Add complete README

Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
This commit is contained in:
Yohann D'ANELLO 2021-05-31 14:53:22 +00:00
parent 4c8ba03a0a
commit 83cb7216b6

227
README.md Normal file
View File

@ -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
<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.