Table des matières
Guide pour le concepteur de "réseaux"
Introduction
Ce guide peut vous intéresser si vous souhaitez par exemple :
- ajouter un logiciel/service dans le disque
- modifier un réseau (ajouter/retirer des machines)
- créer de nouveaux réseaux
et de façon plus générale comprendre le fonctionnement interne de VDN.
VDN assiste le concepteur de réseaux “pédagogiques” en permettant principalement :
- l'intégration de machines virtuelles lambda (supportées par QEMU/KVM)
- l'intégration de machines Debian “modifiées” offrant :
- une spécialisation à l'amorçage/arrêt
- une sauvegarde des modifications optimisée et compressée
- la création des brins Ethernet virtuels interconnectant les machines virtuelles
- la gestion dynamique des redirection de ports, adresse IP virtuelles et adresses MAC virtuelles.
- l'échange simple de ses réseaux (upload/download)
En fonction des modifications que vous souhaitez apportées (logiciels/services, machine, réseaux) vous pourrez vous référer à ce guide.
Dans les premiers chapitres sont présentés les particularités des systèmes VDN. Si vous vous posez des questions sur les choix faits gardez à l'esprit que VDN est un outil devant fonctionner sur un réseau universitaire sur lequel nos utilisateurs (étudiants/profs) :
- ne sont jamais root
- ne disposent pas de pile IP en tant que root
- n'ont aucun droit privilégiés autre que d'appartenir au groupe kvm (VDN fonctionne sans mais dans ce cas les machines virtuelles sont 5 à 10 fois plus lentes).
- accèdent à un home distant (via NFS) et ont peu de quota disque (actuellement nous réservons 3 Go pour l'ensemble des machines virtuelles).
et que ses objectifs sont de permettre aux utilisateurs :
- d'être root sur leurs systèmes virtuels en toute sécurité pour le système hôte et le réseau de l'hôte.
- de disposer de machines virtuelles diverses et variées, éventuellement interconnectés
- d'installer leur propre systèmes, réseaux.
- de personnaliser des systèmes fournis.
- …
La réalisation des objectifs avec les contraintes imposées ont amené à devoir développer une gestion spécifiques des réseaux virtuels, des modes de sauvegardes, des spécialisation des machines que vous devrez comprendre pour intervenir sur les machines/réseaux existants ou les nouveaux que vous créerez et diffuserez.
Je vous rassure elle n'est pas censée être vue des utilisateurs.
qemu-system-x86_64 -smp 8 -enable-kvm -cpu host -device virtio-rng-pci,rng=rng0 -object rng-random,filename=/dev/urandom,id=rng0 -pidfile /tmp/vdn-davalan/vdn-debian-1-davalan-pid -rtc base=localtime -m 2024M -serial mon:stdio -monitor null -vnc unix:/tmp/vdn-davalan/vdn-vnc-davalan-debian-1-socket -spice unix,disable-ticketing,addr=/tmp/vdn-davalan/vdn-spice-davalan-debian-1-socket-initrd /home/davalan/vdn/files/initrd-tgz.img-4.19.0-6-amd64 -kernel /home/davalan/vdn/files/vmlinuz-4.19.0-6-amd64 -append root=/dev/vda1 ro console=ttyS0,115200n8 vdn-emulator=kvm vdn-mode=tgz net.ifnames=0 noresume -boot order=c -drive file=/home/davalan/vdn/files/debian.disk,if=virtio,snapshot=on,format=raw -drive file=/tmp/davalan/docker-hdb.disk,if=virtio,format=raw -drive file=/home/scratch/davalan/vdn-save/docker-hdb/debian-1.tgz,if=virtio,media=disk,format=raw -drive file=/tmp/vdn-davalan/vdn-debian-1-davalan-part,if=virtio,media=disk,format=raw -drive file=/tmp/vdn-davalan/vdn-debian-1-davalan-swap,if=virtio,media=disk,format=raw -drive file=/tmp/vdn-davalan/vdn-debian-1-davalan-config.tgz,if=virtio,media=disk,format=raw -device virtio-net-pci,netdev=n0,mac=52:55:25:E8:00:00 -netdev user,id=n0,hostfwd=tcp::5022-:22,hostfwd=tcp::5080-:80,hostfwd=tcp::5443-:443
- en magenta les options générales passées à QEMU/KVM
- en l'initramfs, le noyaux et ses paramètres
- en les disques (créés/partitonner/formattés automatiquement si nécessaire)
- en <color green>les cartes réseaux (adresses MAC et redirections de ports calculées dynamiquement)
VDN à construit et démarrer la machine virtuelle debian-1 à partir de la définition suivante :
#!/usr/bin/env bash set -eu build() { local n n=debian-1 vdn-build $n vdn-config $n MEMORY "2048" vdn-config $n SAVE_DIR_HDB "/tmp/$USER" vdn-config $n HDB "docker-hdb.disk" vdn-config $n HDB_SIZE "1024" vdn-config $n REDIRS "\ tcp:22:(ssh) \ tcp:80:(http) \ tcp:443:(https) \ " }
Ce que l'on ne voit pas sur cette commande générée mais que VDN effectue (via l'injection de scripts) est la “spécialisation du système” à son amorçage/arrêt (génération de mots de passes aléatoires, mise en place d'une authentification ssh par clés, …), compression de la sauvegarde, …
Une solution pour découvrir plus complètement les capacités de définition des réseaux est d'observer comment sont définis les réseaux fournis avec VDN et de lire les notes techniques associées.
La place occupée sur le disque par les systèmes et les modifications de ces derniers nous a amener a utiliser ou développer dans VDN différentes “stratégies” de sauvegardes des modifications (direct, cow, cow+, overlay, tgz), adaptées à différents cas d'utilisation des systèmes invités (système lambda supporté par QEMU/KVM, système de type Debian modifié, système devant être plus ou moins modifié, système persistant/temporaire (le temps d'un TP)).
Faire le bon choix a un impact sur le volume des sauvegardes. Actuellement seul le système de sauvegarde de type “tgz” nous permet de gérer de façon persistante les 9000 machines virtuelles de nos étudiants dans un espace (sous leur quotas) de quelques Mo seulement par étudiant.
Sécurité
VDN est sécurisé pour le système hôte et le réseau de l'hôte. Un utilisateur ne peut effectuer d'élévation de privilège à cause de VDN. Nous l'affirmons car VDN peut fonctionner sans aucune intervention de l'administrateur du système hôte. L'accès au réseau de l'hôte est “filtré” par slirp qui ne laisse passer que les couches réseaux transports et plus (UDP, TCP et plus) mais ni IP ni ICMP (le but étant de ne pas sniffer ou d'injecter de trame “martiennes” sur le réseau de l'hôte). Aucun accès privilégié n'est donc nécessaire.
Cependant, dans les faits l'administrateur est invité à activer les instructions de virtualisation et à ajouter les utilisateurs au groupe kvm
pour des raisons de performances (accélération d'un facteur 5 à 10), mais ce n'est pas bloquant, juste très pénible pour les utilisateurs (recherche cve kvm kernel security).
Au niveau des interconnexions réseaux VDN utilise 2 techniques différentes :
- slirp (intégré à QEMU): adaptée pour les connexions entre l'hôte et les machines virtuelles mais également des machines virtuelles vers les ressources du réseau hôte (le proxy Internet réel par exemple).
- des canaux multicast IPv4 (intégré à QEMU) pour les connexions entre machines virtuelles d'un même réseau mais également pour, si souhaité, interconnecter tous les réseaux de tous les étudiants (Internet virtuel par exemple).
Les canaux multicast IPv4 remplacent les hubs et les switchs virtuels. Ce sont des brins Ethernet virtuels (ils sont représentés par des hubs virtuels sur les schémas).
Potentiellement, tout utilisateur peux écouter ces brins Ethernet virtuels. Les réseaux virtuels peuvent tous être sniffés (qu'ils soient diffusés en dehors de l'hôte ou pas). Un réseau VDN ne peut donc en aucun cas être considéré comme un réseau sécurisé. Pédagogiquement c'est intéressant (a charge aux utilisateurs de le rendre sécurisé via un chiffrement systématique des protocoles et/ou la mise en oeuvre d'un VPN ou …).
Le piratage d'une machine virtuelle Debian d'un utilisateur par un autre utilisateur est cependant assez complexe à partir du moment ou les systèmes fournis possèdent des mots de passes aléatoires et donc inconnus. L'utilisateur se connecte à ses Debian via ssh à l'aide d'une authentification par clés (mise en place automatiquement par VDN).
A l'utilisateur, via la connexion ssh, en toute responsabilité, de fixer ses mots de passes si nécessaire. Ses sauvegardes sont implicitement protégées (droits Unix 600).
Portabilité
VDN a été conçu sous Debian et dépends des versions précises de certains outils (kvm/qemu) et embarque un module ruby compilé (le terminal de l'interface graphique). Aucun portage sous d'autres distributions n'est prévu. Cependant une exécution en mode chroot, sous tout système GNU/Linux d'architecture X86_64, est possible avec le mot de passe root ou via un programme setuid fourni (bientôt).
VDN peut facilement être déployé sur un réseau de type NFS. Un seul utilisateur l'installe (l'enseignant sans doute), et tous l'utilisent (1 seul disque pour tous). L'administrateur des systèmes hôte devra activer les instructions de virtualisation sur les machines de TP et ajouter les utilisateurs au groupe KVM (ce dernier point est fortement recommandé pour des raisons de performances).
Avant de lire la suite 2 dernières petites choses :
- Avant d'être une interface graphique, VDN est un ensemble de commandes (voir XXX). L'interface graphique n'est pas nécessaire au fonctionnement de VDN, elle permet juste une meilleure ergonomie dans certains cas.
- Sous VDN tout est script shell bash (exception faites pour l'interface graphique en Ruby/GTK2 et au programme setuid en C). Par exemple une machine est décrite dans un script : le script de configuration du réseau. Procéder ainsi permet à VDN de générer de gros réseaux distribués sur un cluster (bientôt). La majorité des opérations sont accessibles via l'interface graphique et renvoie vers l'édition de scripts. Si vous n'aimez pas l'éditeur de texte vi, cliquez “Préferences → Use nano text editor” (ou fixer votre variable d'environnement EDITOR).
Gestion des disques
Pédagogiquement nous avons un besoin d'une 30 de machines virtuelles pour chacun de nos 300 étudiants tous au long de leur formation.
Gérer 9000 machines virtuelles persistantes, à raison de 10 Go par machine virtuelle n'est pas envisageable.
En fait il se trouve qu'à l'usage les machines virtuelles nécessaires peuvent être classées, dans le cadre de nos TP, suivant les 2 types suivant :
- les “volumineuses” : qui nécessite un système complètement personnalisable par l'étudiant, voir même qui consiste à installer le système d'exploitation à partir d'un cédérom. Le volumes des modifications utilise éventuellement des Go.
- les “légères” : qui consiste à quelques modifications de quelques fichiers (quelques Mo), très utilisées dans les TP de configurations “réseaux”.
On cherche a éviter au maximum la persistance des “volumineuses” et dans le cas ou la persistance est nécessaire on cherche à factoriser l'espace occupé (principe du LiveCD).
Les “légères” sont encore plus optimisée, nous ne sauvegardons que les fichiers modifiés, sous forme compressée. C'est le mode privilégié de VDN (mode tgz)
Dans la réalité, il existe plusieurs mode de sauvegardes pour les volumineuses, plus ou moins optimisé en fonction du système virtuel ayant leur avantages et inconvénient :
- le mode “direct” : le disque complet est “donné” à l'étudiant. Aucune factorisation ou optimisation. Simple mais très volumineux, à réserver plutôt pour les machines “temporaire” (dans /tmp).
- le mod “cow” : le disque complet est accédé en lecture seule par les étudiant (disque “souche”) mais la couche “Copy On Write” proposé par QEMU est utilisé pour absorber les “blocs disques” modifiés. Ce mode est transparent pour le système d'exploitation mais possède 2 inconvénient principaux :
- n'optimise pas totalement la sauvegarde (les blocs disques utilisés puis ensuite libérés par le système d'exploitation (un fichier temporaire par exemple) seront sauvegardés).
- interdit la modification du disque “souche” sous peine d'invalider les systèmes l'utilisant à travers le mode “cow”. Ce dernier point a un impact fort si la persistance doit être assurée sur le long terme puisqu'il faudra prévoir un historique des systèmes souches.
Notons que les modes “direct” et “cow” ne permettent pas de spécialiser les systèmes. Nous entendons par spécialisation d'un système la capacité de ce dernier à s'autoconfigurer à l'amorçage :
- mots de passes aléatoires / authentification par clés ssh.
- récupération de fichiers.
- masquage/démasquage de services/logiciels.
- script d'initialisation personnalisé.
Ainsi qu'à l'arrêt :
- suppression de fichiers pour optimiser la place disque occupée
- compression de la sauvegarde (il est long de compresser des disques).
La spécialisation, dans le cas de la mise en oeuvre de nombreuses machines basées sur un unique disque, est souhaitable.
Devant les limites de ces modes nous avons ajouté 3 autres modes (cow+, overlay, tgz) qui optimise les sauvegardes et permettent de spécialiser les machines. Cependant ils ont également leurs limitations :
- sont dépendants du systèmes d'exploitation : en effet, ce sont les procédures d'amorçage et d'arrêt qui sont modifiées.
- dans le cas du mode tgz (celui qui compresse les modifications) les temps de compression/décompression limitent la taille possible des modifications (si nécessaire il est possible d'adjoindre un second disque à la machine virtuelle, géré en mode direct (via un fichier creux) pour lever cette limite).
- le mode “cow+” : rien de nouveau au niveau de la sauvegarde par rapport au mode “cow” si ce n'est qu'il est possible de supprimer (ou de vider) des fichiers à l'arrêt.
- le mode “overlay” : contrairement au mode cow, la couche absorbant les modifications est un système de fichiers sur disque auxiliaire. En procédant ainsi, un fichier supprimé libérera réellement la place dans le fichier de sauvegarde des modifications. Le mode “overlay” nécessite la modification de l'initramfs et utilise le systèmes overlayfs du noyau Linux. Ce mode est utilisée par les machines du réseau nagios dans lesquelles on souhaite compiler nagios.
- le mode “tgz” : comme le mode overlay mais sauvegarde le contenu du système overlay sous la forme d'une archive compressée (tgz). Les temps de compression/décompression de la sauvegarde limite la taille des modifications (quelques dizaine de Mo). Cepenant, si le volume des modifications est important mais localisé à quelques répertoires il est possible d'utiliser avec le mode “tgz” un second disque géré en mode direct (fichier creux). VDN prend en charge le déplacement transparent de ces répertoires sur ce second disque. Cette technique est utilisé par la machine virtuelle du réseau docker pour lequel les répertoires /var/lib/docker, /src, /home et /root sont déplacés sur le disque virtuel (le choix de l'aspect temporaire de ce second disque dépend des TP s'étalant quelques fois sur 2 ou plus semaines).
Le disque "souche"
Comme expliqué dans le chapitre précédent, réserver des Go de disque pour quelques milliers de machines virtuelles afin d'assurer la persistace des modifications des “lourds”.
Le principe du disque souche (un peu l'équivalent d'un Live CD) est de permette l'adjonction d'une couche “haute” absorbant et sauvegardant les modifications.
Un disque souche peut contenir un système quelconque si la couche haute est de type COW.
Un disque souche contenant le système Debian modifié fourni avec VDN permet d'obtenir une couche “haute” en overlayfs sauvegardée (tout ou partiellement) et compressée dans un fichier tgz (tar compressé).
Le choix du type de sauvegarde est à la charge du concepteur du réseaux.
Mais quelque soit le choix la gestion du disque souche expliqué plus haut est détaillée ici :
* Le réseau zoo
Dans le réseau zoo sont regroupé tous les systèmes souches. En démarrant un des systèmes du réseau zoo vous avait un accès direct au système “souche”.
- Attention, une modification sur un système souche invalide tous les systèmes COW dépendants !
- Attention, une modification sur un système souche est déconseillée pendant que des systèmes dépendant sont en cours d'utilisation !
Un fois le système démarré, vous accédez au moins à une console root vous permettant de faire les modifications.
Le réseau zoo est classique (fichier build). Vous pouvez facilement dupliquer un système.
Lors du lancement du système, si les disques HDA et HDB précisés n'existent pas ils seront créés (fichiers creux) au démarrage de la machine virtuelle.
Exemple :
La spécialisation des systèmes
Ce chapitre ne concerne que les modes “cow+”, “overlay” et “tgz”. Autrement dit ne fonctionne qu'avec la Debian fournie avec VDN.
La spécialisation à pour but d'offrir, à partir d'un même disque souche, des systèmes différents : services, fichiers, configurations, …
En fonction des différents modes cette spécialisation peut intervenir dans une ou plusieurs étapes de la phase de l'amorçage :
- dans l'initramfs (très tôt au boot pour monter par exemple l'overlay, injecter des fichiers liés aux services (systemd), établir des montage avec le second disque, …).
- dans /etc/rc.local : (re)génération des mots de passes aléatoire, établissement de l'authentification ssh par clés, exécution de scripts.
- dans des scripts externes, exécutables à partir de l'hôte servant à post configurer les systèmes (voir “Scripts de post configuration”) et/ou également injecter des fichiers.
Ce que contient cette phase de spécialisation est libre et définissable sur l'hôte.
La spécialisation de l'initramfs est essentiellement guidée par le contenu de variables associées à la machine et via les fichiers à importer de l'hôte (le répertoire vdn/networks/nomDuRéseau/nomMachine contenant l'arborescence des fichiers à importer, sous l'identité de root dans le système virtuel).
La spécialisation via /etc/rc.local peut en plus permettre d'installer des paquets supplémentaires, des utilisateurs, … même si nous lui préférons comme expliquer ci-dessous, utiliser les script de post-configuration.
Enfin la spécialisation via des scripts de post-configuration. Ces script externes à la machines (exécutés sur l'hôte) configure les machines par ssh, à la demande de l'utilisateur via le menu “Scripts” (ou la commande vdn-scripts
).
Ces scripts de post-configuration, fournis avec le réseau, peuvent servir à :
- placer le réseau dans une configuration initiale (scripts config*)
- placer le réseau dans une configuration finale (scripts repair*)
- tester le réseau en testant ses fonctionnalités (scripts test*)
Dans le cadre de TP de configuration de systèmes et de services réseaux ces scripts externes peuvent par exemple servir à valider un TP (ou une série de TP). Pour cela :
- le script configAll effectue une configuration de base d'une machine
- le scrip testAll effectue un test des différentes fonctionnalités attendues en fin de TP.
En lançant le script testAll
l'étudiant/l'enseignant suis la progression du TP. Idéalement en fin de TP tous les tests doivent passer.
L'équipe pédagogique peut se servir du script repairAll pour effectuer les configurations amenant aux fonctionnalités attendues afin de valider les tests. Ainsi on peut vérifier qu'après une mise à jour du système le TP reste fonctionnel. Si ce n'est pas le cas une adaptation du TP est sans doute nécessaire.
Ces scripts de post configuration permettent de valider les réseaux fournis avec VDN.
L'équipe pédagogique utilise quasi exclusivement ces scripts dans les réseau proposés avec VDN. L'injection de fichiers/scripts par l'initramfs ou /etc/rc.local reste des exceptions.
Les scripts de post configuration
Ces scripts déjà présentés plus haut, permettent de placer le réseau dans une configuration spécifique, de le réparer et de le tester (de façon automatique et systématique si on le souhaite).
Avec chaque réseau fournis par VDN sont fournis des scripts config*, repair* et test*.
Une validation automatique des TP peut est réalisée avant les séances (configAll; repairAll, testAll).
Étapes pour le développement d'un nouveau réseau
Lorsque l'on doit développer un nouveau réseau “from scratch” voici les étapes que nous suivont :
- 1. Au départ des objectifs pédagogiques (installation de systèmes, configuration de systèmes/réseaux) à définir le plus précisément possible.
- 2. Des objectifs pédagogique découle une architecture matérielle virtuelle au départ griffonnée sur une feuille ou un tableau.
- Les connexions réseaux sont mise en évidence à l'aide de hubs virtuels numérotés, les interfaces réseaux des machine virtuelles également (correspond à ethX).
- Les logiciels/services nécessaires sont listés
- Les besoins en RAM et en disque de chaque machine est estimé.
- 3. Choix de la stratégie de sauvegarde des différentes machines du réseau
- On évite si possibles les systèmes “direct” et “cow” dans le cas ou il faut assurer la persistance (volumineux). Pas de soucis si ce sont des systèmes temporaires (crées sous /tmp). Si ce n'est pas possible (systèmes autres que Debian devant survivre à un reboot de l'hôte) il faudra prévoir les quotas disque en conséquence et dans le cas de systèmes “cow” gérer l'archivage des systèmes souches. De préférence on cherchera à faire fonctionner l'objectif pédagogique sur Debian en mode “overlay” ou “tgz” (avec un second disque dur en mode “direct” si nécessaire).
- 4. Création du réseau
- Cette étape consiste à définir le script de construction du réseau définissant les machines qui le compose ainsi que leur interconnexions.
- 5. Intégration des services/logiciels dans le système souche (s'il existe)
- si les machines virtuelles utilisent des logiciels/services et que ces machines utilisent un système “souche” alors on a tout intérêt à installer ce logiciel/service dans le disque souche pour éviter aux étudiants d'avoir à le faire dans leur(s) disque(s) (factorisation des logiciels/services). Dans le cas d'un service que ne doit pas être activé sur tous les systèmes virtuels il faut le masquer (systemctl mask service).
- 6. Spécialisation des machines du réseau
- on définit les services à démasquer. Si possible on préférera utiliser les scripts de post configuration
- 7. Création de script de post configuration pour
- placer les machines dans un état initial (config*)
- tester les commandes amenant à valider les tests (repair*)
- tester le fonctionnement des objectifs à atteindre.
- 8. Définir (facultatif) une représentation graphique plus sexy du réseau.
- 9. Tester le réseau (en condition réelle avec des dizaines d'étudiant l'utilisant simultanément en surveillant l'usage NFS du réseau de l'hôte si utilisé).
- 10. Poster son réseau pour en faire bénéficier d'autres étudiants/enseignants.
Exemple :
Exemple de définition sommaire d'un réseau axé sur la configuration de systèmes
- 1. Objectifs pédagogiques
- le réseau doit permettre d'illustrer :
- la configuration de systèmes à distance (ssh)
- la configuration de services d'un Intranet (proftp, serveur LAMP interne, …)
- la séparation clair entre le réseau interne et Internet (firewall, règles de filtrage)
- la division nécessaire des réseaux internes (réseau production, DMZ, poste d'administratifs, …)
- …
- 2. Architecture du réseau
- 3. Choix de la stratégie de sauvegarde
Toutes des machines Debian, sans grosse modification ⇒ systèmes de type “tgz”.
- 4. Création du réseau
- avec l'interface graphique
- en ligne de commande
- 5. Installation des services/logiciels dans le système “souche”
- ouvrir le réseau “zoo” accueillant les systèmes de type “direct” et démarrer le système Debian.
- installation manuelle
- installation par script
- 6. Spécialisation des machines du réseau
- démasquage de services à l'amorçage
- 7. Création des scripts de post configuration
- 8. Définir (facultatif) une représentation graphique plus sexy du réseau.
- 9. Tester le réseau (en condition réelle avec des dizaines d'étudiant l'utilisant simultanément en surveillant l'usage NFS du réseau de l'hôte si utilisé).
- en “local”
- en “réseau” avec de nombreux étudiants en parallèle.
- 10. Poster son réseau pour en faire bénéficier d'autres étudiants/enseignants.