- Mode Opératoire
- 1. Configuration Réseau
- 2. L’interface virtuelle TUN
- 3. Un tunnel simple pour IPv6
- 4. Validation Fonctionnelle
- 5. Améliorations
- 6. FAQ
- 6.1. Comment ouvrir un shell en root ?
- 6.2. Java, ce n’est pas la fête pour les appels système
- 6.3. Les interfaces TUN n’apparaissent pas dans l’interface graphique
- 6.4. Comment envoyer un seul paquet ICMP avec ping6 ?
- 6.5. Les paquets lus sur tun0 sont incomplets ?
- 6.6. Les commandes de configuration de tun0 échouent : “RTNETLINK answers: Network is down“
- 6.7. J’ai mis en place la redirection de ports sur virtualbox mais le ping/ping6 ne fonctionne pas ?
Le but de ce projet est de permettre des communications entre îlots IPv6 en utilisants des tunnels simples au-dessus de IPv4.
Mode Opératoire
Le projet se déroule en groupes de 3 personnes maximum sur l’ensemble des séances de TP restantes plus une soutenance le 11 décembre 2024.
Vous devrez respecter l’ensemble des instructions données dans ce sujet ainsi que les dates de rendu des livrables sur AMETICE.
0.1. Livrables
Vos livrables contiendront une archive sous forme zip
ainsi qu’un fichier pdf
décrivant votre travail et répondant aux questions
du sujet.
Dates :
- Mardi 26 novembre 18h: inscription des groupes sur AMETICE
- Vendredi 29 novembre 18h : livrable intermédiaire (correspondant au minimum à la partie 1.) à déposer ici
- jour de la soutenance 19h: livrable final, à déposer sur AMETICE
- Soutenance : mercredi 11/12 planning transmis ultérieurement.
0.2. Présentation et gestion du code
Le choix du langage est libre même si C ou python sont sans doute plus avantageux étant donnée l’utilisation des appels systèmes. Voir la FAQ, si vous souhaitez utiliser java. Pensez à expliquer pourquoi vous avez retenu l’un plutôt que l’autre.
Une attention particulière sera portée à la lisibilité du code, les commentaires sont indispensables. Un soin particulier sera porté à la modularité du code. En règle général, toute méthodologie enseignée dans une autre UE, par exemple en Génie Logiciel, est à réutiliser ici.
Il est indispensable de mettre proprement en place des tests, fonctionnels a minima.
Il est attendu que vos fichiers soient versionnés sur git (voir également le support).
0.3. Rendu
Le rendu s’effectuera sur l’ENT.
Notez que vous pouvez rendre plusieurs versions de votre projet tant que vous ne validez pas définitivement.
Aucun fichier ne sera accepté par courriel.
0.4. Soutenance
La soutenance consiste à une démonstration de votre système. Vous avez 12 min de préparation, 8 minutes de présentation sur PC + 4 minutes de questions. La présentation pourra suivre l’ordre des parties de l’énoncé et des tests associés. Il n’est pas demandé de présenter votre code (celui-ci sera évalué ultérieurement) mais plutôt le fonctionnement des tunnels. Le déroulé pourra suivre le plan suivant :
- tunnel: montrer quelles parties fonctionnent
- illuster concrètement la circulation d’un paquet donné.
Pensez à préparer des fichiers de configuration ou des scripts permettant de montrer plusieurs scénarios (avec autant de VMs que nécessaire) en temps limité.
0.5. Support
Pour le choix des langages, le support est assuré a minima parmi C/C++, java, python.
Pour toute question qui impliquerait de tester vos fichiers, merci de nous donner l’accès à votre dépôt git afin que nous ayons accès à la même configuration que vous.
1. Configuration Réseau
On commence par considérer le réseau qui servira à déployer notre système.
1.1. Topologie et Adressage
Vous utiliserez vos 6 machines virtuelles avec le plan d’adressage suivant (cf le TP précédent, dont le corrigé est ici).
LAN1 | LAN2 | LAN3-6 | LAN4-6 | LAN1-6 | LAN2-6 | |
---|---|---|---|---|---|---|
réseau | 172.16.2.128/28 | 172.16.2.160/28 | fc00:1234:3::/64 | fc00:1234:4::/64 | fc00:1234:1::/64 | fc00:1234:2::/64 |
VM1 | 172.16.2.131 | fc00:1234:3::1 | ||||
VM2 | 172.16.2.132 | 172.16.2.162 | ||||
VM3 | 172.16.2.163 | fc00:1234:4::3 | ||||
VM1-6 | fc00:1234:3::16 | auto | ||||
VM2-6 | fc00:1234:1::26 | fc00:1234:2::26 | ||||
VM3-6 | fc00:1234:4::36 | auto |
Si l’on ne souhaite pas utiliser l’auto-configuration IPv6, on pourra utiliser fc00:1234:1::16 pour VM1-6 dans LAN1-6 et fc00:1234:2::36 pour VM3-6 dans LAN2-6.
Reprendre les fichiers Vagrantfile
et salt
permettant de préparer
votre système. Si vous n’aviez pas terminé la configuration au TP précédent, passez directement à la section suivante.
Vérifier que tout fonctionne bien en partant de VM neuves.
1.2. Un grand malheur !
La machine VM2-6 s’est arrêtée ! VM1-6 n’a donc plus accès directement à VM3-6.
Comment pourrait-on faire ?…
Nous allons relier nos deux îlots IPv6 via le réseau IPv4 en créant un tunnel IPv6 sur IPv4 entre VM1 et VM3 …
Préalable au projet : avoir une collection de 5 VMs, configurées, formant le réseau ci-dessus.
2. L’interface virtuelle TUN
Afin de pouvoir injecter le trafic dans un tunnel, nous devons
récupérer le trafic depuis l’espace noyau pour le mettre en espace
utilisateur. Pour ceci, Linux offre la possibilité de créer des
interfaces réseaux virtuelles TUN.
Les paramètres réseau de ces interfaces pourront être configurées
comme n’importe quelle interface.
Vous devrez être root (via sudo
) pour pouvoir créer l’interface.
Certaines parties du projet exigeant des droits root
, elles
seront donc à réaliser dans une machine virtuelle.
Si vous rencontrez de sérieux problèmes de quotas voir la FAQ Dans tous les cas, évaluer votre place disponible
2.1. Création de l’interface
En vous inspirant du code exemple de la
documentation
(section 3),
utiliser le code qui crée une telle
interface virtuelle pour créer une bibliothèque iftun
qui a pour but de créer l’interface virtuelle, extrémité du tunnel.
- en C :
tunalloc.c
- en python :
tunalloc.py
Le nom de l’interface pourra être défini à l’exécution.
Prendre "tun0"
pour les tests de cette partie.
NB l’interface n’est pas persistante par défaut et disparaît dès
que le processus l’ayant créée termine : pensez à mettre
votre programme en pause avant de configurer tun0
.
2.2. Configuration de l’interface
- Configurer l’interface
tun0
avec l’adressefc00:1234:ffff::1
, mettre un masque adéquat. Ecrire un scriptconfigure-tun.sh
reprenant vos commandes de configuration. - Routage : Suite à la disparition tragique de VM2-6, faut-il modifier les informations de routage sur VM1 ? ou sur VM1-6 ?
- Faire un
ping6 fc00:1234:ffff::1
. Donner la capture surtun0
(avecwireshark
). Que constatez-vous ? - Faire
ping6 fc00:1234:ffff::10
. Que constatez-vous ? - Expliquez.
2.3. Récupération des paquets
A la création de tun0
, un descripteur de fichier est renvoyé (cf
l’exemple). C’est ce descripteur qui permet de lire ce qui est envoyé
à l’interface par un appel read
.
- Compléter la bibliothèque
iftun
avec une fonction avec deux descripteurs de fichiers en paramètressrc
etdst
, qui, étant donné un descripteursrc
correspondant à une interface TUN, recopie perpétuellement toutes les données lisibles sursrc
dans le fichier décrit pardst
. - Tester avec
dst=1
(sortie standard). Comme ce qui est recopié est du binaire, on filtrera la sortira du programme de test avechexdump
. Par exemple en faisantVM# test_iftun tun0 | hexdump -C
- Refaire
ping6 fc00:1234:ffff::1
puisping6 fc00:1234:ffff::10
. Comparer et expliquer. Quel type de trafic voyez-vous? Refaire une capture avecwireshark
dans le second cas et comparer avec ce qui est obtenu par votre programmetest_iftun
. - A quoi sert l’option
IFF_NO_PI
? Que ce passe-t-il si vous ajoutez cette option lors de la création de l’interface ?
3. Un tunnel simple pour IPv6
Le but de cette partie est de créer un tunnel simple encapsulant un trafic IPv6 dans des paquets TCP/IPv4.
3.1. Redirection du trafic entrant
On utilisera par défaut le port 123
.
Dans cette partie, on créera une bibliothèque extremite
qui gérera
le trafic entre extrémités du tunnel.
- Ecrire une fonction
ext-out
qui crée un serveur écoutant sur le port123
, et redirige les données reçues sur la sortie standard. - Ecrire une fonction
ext-in
qui ouvre une connexion TCP avec l’autre extrémité du tunnel, puis lit le trafic provenant detun0
et le retransmet dans la socket.
- La commance
nc
(netcat) permet de transférer des données sur un port réseau. Pour le support IPv6 sur vos VMs, il faudra installer éventuellementnetcat6
. L’option-u
permet d’envoyer en UDP (puisque votre tunnel est unidirectionnel pour l’instant).VM$ nc -u fc00:1234:4::36 123
- Mettre en place une extrémité
ext-in
et une extrémitéext-out
sur deux VMs distinctes. - Tester avec un “client”
ping6 fc00:1234:ffff::10
pour injecter du trafic comme dans la partie précédente.
- Mettre en place une extrémité
3.2. Redirection du trafic sortant
- Compléter la fonction
ext-out
de la bibliothèqueextremite
pour créer une extrémité qui retransmet le trafic provenant de la socket TCP dans letun0
local. - Que devrait-il se passer alors pour ce trafic ?
Indication : Que se passe-t-il lorsque l’on écrit dans le fichier correspondant à (au descripteur de)
tun0
? - Vérifier avec l’un de vos paquets capturés dans le cas précédent. Pensez à le modifier éventuellement (avec un éditeur hexadécimal) pour que cela corresponde à tous vos paramètres réseau.
- Proposer des tests de connectivité. Tester et vérifier !
Indication : La commande nc
(netcat) permet également de transférer le contenu
d’un fichier sur un port réseau
VM$ nc IPDEST 123 < fichier.bin
Indication : Que se passe-t-il si le paquet est modifié sans modifier le CRC? Comment pourrait-on calculer le nouveau CRC ?
3.3. Intégration Finale du Tunnel
- Compléter la bibliothèque pour pouvoir avoir un flux bidirectionnel
- Assurez-vous que les communications sont bien asynchrones.
3.4. Mise en place du tunnel entre VM1 et VM3 : Schémas
On veut utiliser VM1 et VM3 pour pouvoir faire un tunnel entre LAN3-6 et LAN4-6.
- Compléter le schéma simplifié en expliquant en détail le parcours complet d’un paquet.
3.5. Mise en place du tunnel entre VM1 et VM3 : Système
- Créer un exécutable
tunnel64d
qui, en s’appuyant sur la bibliothèqueextremite
crée un service offrant un tunnel TCP bidirectionnel. Cet exécutable lira sa configuration dans un fichier de la forme suivante:# interface tun tun=tun0 # adresse locale inip= inport= options= # adresse distante outip= outport=
Il pourra appeler le script de configuration réseau avec ces paramètres une fois que l’interface est créée. Il est également possible de faire des appels systèmes directs avecioctl
.
- Tester en configurant et lançant
tunnel64d
sur deux VMs différentes. - Comparer le trafic direct et celui passant par le tunnel.
4. Validation Fonctionnelle
Il s’agit des tests minimaux à mettre en oeuvre pour valider votre tunnel.
4.1. Configuration
Sur VM1-6, VM1,VM2,VM3,VM3-6, afficher les paramètres réseaux significatifs avec ip addr
et ip route
.
4.2. Couche 3
Depuis VM1-6, effectuer ping6 fc00:1234:4::36
.
Proposer éventuellement d’autre tests au niveau “Réseau”.
4.3. Couche 4
Depuis VM1-6, créer un fichier “msg.txt” puis l’envoyer sur le service echo
de VM3-6.
VM1-6$ echo "Test" > msg.txt VM1-6$ nc fc00:1234:4::36 VOTREPORTECHO < msg.txt
4.4. Couche 4 : bande passante
Afin de tester les performances réseaux, nous allons utiliser l’utilitaire
iperf3
, qui permet de tester les performances d’une connexion.
Ce banc d’essai fonctionne en mode client/serveur, lancer le serveur sur VM3-6
VM3-6$ iperf3 -s
Tester avec un petit, un moyen, un gros et un très gros tampon.
VM1-6$ iperf3 -6 -c fc00:1234:4::36 -n 1 -l 10 VM1-6$ iperf3 -6 -c fc00:1234:4::36 -n 1 -l 2K VM1-6$ iperf3 -6 -c fc00:1234:4::36 -n 1 -l 128K VM1-6$ iperf3 -6 -c fc00:1234:4::36 -n 1 -l 1M
5. Améliorations
Il est attendu que soient implémentées au moins une de ces améliorations.
5.1. Tests Avancés Couche 4
Proposer éventuellement d’autres tests en couche 4 afin de valider votre système.
Indication : En consultant notamment la documentation de iperf3
,
on pourra s’intéreser à l’évolution de la bande passante au cours du temps,
à la gestion de la congestion, à la fragmentation, au MTU,
à la gestion des TTL, etc…
5.2. Configuration salt
Peut-on mettre en place la gestion du tunnel via salt
.
Quelles seraient les difficultés ? Proposer une solution et la mettre
en oeuvre.
5.3. Une amélioration simple
Il est possible d’ajouter en tête du paquet la taille de celui-ci sur deux octets avant de l’envoyer dans le tunnel. A la sortie du tunnel, cette information est utilisée pour attendre tous les octets avant de les envoyer à l’interface virtuelle.
- Compléter la bibliothèque
traitement
en ajoutant des méthodestaillentete_in
ettaillentête_out
permettant de mettre en place ce prétraitement. - La taille du paquet étant donné dans l’entête IP, écrire un
traitement
tailleauto
qui n’ajoute pas d’entête mais tient compte de la taille par lecture du champ taille de l’entête du paquet encapsulé.
5.4. Fragmentation et Réassemblage
Au lieu de mettre en attente les données comme dans le cas précédent, on peut gérer explicitement la fragmentation au niveau des extrémités du tunnel.
- Ajoute des méthodes
frag_in
etfrag_out
permettant de mettre en place un tel traitement.
5.5. Tunnels entre VMs
- Comment faire pour réaliser un tunnel entre VMs situés sur des hôtes
différents ?
Indication : Penser à utiliser la redirection de port de
virtualbox
. - Faire une démonstration de communication par un tel tunnel entre un
serveur echov6 et un client echov6 situé sur des VMs qui n’hébergent
pas
tunnel64d
.
5.6. Annonce de route IPv6
A l’établissement du tunnel, chaque extrémité lance le service radvd
pour annoncer la route vers la plage IPv6 correspondant à l’autre extrémité.
6. FAQ
6.1. Comment ouvrir un shell en root ?
Utiliser sudo -s
6.2. Java, ce n’est pas la fête pour les appels système
Le code java est compilé vers une machine virtuelle JAVA, ce qui rend le code portable d’un système d’exploitation à l’autre. Mais si vous souhaitez faire des appels système, il faudra sans doute utiliser JNA, ou encore JNI pour accéder directement au système d’exploitation sous-jacent.
Notez également que dans tous les cas, vous pouvez faire les appels
système en C, puis, par un appel exec()
, passer la main
(et surtout les descripteurs de fichiers) à un programme écrit dans un
autre langage.
6.3. Les interfaces TUN n’apparaissent pas dans l’interface graphique
Il faudra utiliser ip link show
pour les voir.
Vous pouvez les configurer comme toute interface réseau.
6.4. Comment envoyer un seul paquet ICMP avec ping6 ?
Utiliser l’option -c
: ping6 -c 1 123.45.67.89
6.5. Les paquets lus sur tun0 sont incomplets ?
Attention le paramètre MTU
de votre interface (en général 1500)
doit correspondre à votre propre traitement : si vous utilisez un
tampon intermédiaire de taille inférieure au MTU
, les données
manquées seront perdues et vos paquets tronqués (c’est le même
pĥénomène pour des sockets en mode datagramme).
Attention la MTU
choisie doit être compatible avec IPv6.
6.6. Les commandes de configuration de tun0 échouent : “RTNETLINK answers: Network is down“
Il est possible qu’une manipulation malencontreuse ait désactivé tun0
.
Vous pouvez le voir avec
$ ip addr show tun0 5: tun0: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 500 [...]
Pour remettre l’interface en fonctionnement, il faut faire
$ ip link set tun0 up
6.7. J’ai mis en place la redirection de ports sur virtualbox mais le ping/ping6 ne fonctionne pas ?
La redirection de port pour passer un NAT/PAT ne fonctionne que pour le protocole TCP.