Installer Marionnet

Quelle méthode choisir, ce que chacune installe, et ce qu’il reste à faire ensuite. Pour les seules commandes, sans les explications : INSTALL-quick-guide.FR.md.

À quoi sert cette page

Marionnet est publié sous trois formes prêtes à l'emploi : un dépôt apt, un dépôt dnf/zypper et une archive précompilée. Les trois viennent du même répertoire de publication, sur www.marionnet.org, et contiennent le même programme. Le choix dépend donc seulement du gestionnaire de paquets de votre machine.

Quelle que soit la méthode, deux étapes suivent : récupérer les images et les noyaux (§ 2), puis accorder la règle sudoers (§ 3). Cette page explique aussi pourquoi chaque précaution existe, et quoi faire quand quelque chose ne marche pas (§ 6).

Image
le disque d'une machine virtuelle : Debian trixie, Debian wheezy, ou guignol, la petite image qui sert aussi de routeur.
Noyau UML
le noyau Linux qui fait tourner une machine virtuelle de Marionnet comme un programme ordinaire de votre machine. Il en existe deux : linux-6.12.95 (64 bits) et linux-6.12.95-i386 (32 bits).
Archive précompilée
l'application déjà compilée, dans un fichier .tar.xz (un tarball), pour les distributions qui n'ont pas de dépôt Marionnet.
Version publiée
l'ensemble des fichiers mis en ligne ensemble : application, paquets, images, noyaux.
Règle sudoers
l'autorisation qui permet à Marionnet de créer ses interfaces réseau sur votre machine. Elle tient en trois fichiers de /etc/sudoers.d/, les blocs (a), (b) et (c) du § 3.
Porte
un petit script, appartenant à root, que la règle sudoers autorise à la place des commandes ip ou iptables. Il vérifie ses arguments avant d'agir.

L'installation en un coup d'œil

1. l'application      § 1.A dépôt apt
        │             § 1.B dépôt dnf/zypper
        │             § 1.C archive précompilée
        │             § 1.D depuis les sources
        ▼
2. images et noyaux   § 2 marionnet-get-images
        │
        ▼
3. règle sudoers      § 3 marionnet-sudoers.sh install
        │
        ▼
4. lancement          § 4 marionnet

À l'étape 1, les quatre méthodes sont des alternatives : une seule vous concerne. Les étapes 2, 3 et 4 valent ensuite pour toutes.

Sans images ni noyaux, Marionnet démarre, mais il le signale et ne peut lancer aucune machine virtuelle. Ils pèsent plusieurs gibioctets et changent à leur propre rythme : c'est pourquoi ils se récupèrent à part (§ 2).

Marionnet est un programme graphique. Il lui faut un affichage X (DISPLAY), dont il ouvre l'accès aux machines virtuelles avec xhost (§ 3.2).

Dans cette page, un chemin relatif part du répertoire où se trouve ce fichier : doc-src/ dans les sources, <prefix>/share/doc/marionnet/ sur une machine où Marionnet est installé.

Sur quels systèmes l'installation a été testée

Chaque ligne du tableau a été mesurée par des bancs d'essai : des scripts qui installent Marionnet dans un conteneur nu de la distribution, puis interrogent la machine sur ce qu'elle a obtenu. Ils sont dans le dépôt des sources, sous Makefile.d/*.bench/ et bin/scripts/marionnet-install.sh.bench/.

Système glibc archive (§ 1.C) apt (§ 1.A) dnf/zypper (§ 1.B)
Ubuntu 20.04 LTS (focal) 2.31 49 / 0 41 / 0 —
Ubuntu 22.04 LTS (jammy) 2.35 49 / 0 41 / 0 —
Ubuntu 24.04 LTS (noble) 2.39 49 / 0 41 / 0 —
Ubuntu 26.04 LTS 2.41 49 / 0 41 / 0 —
Debian 11 (bullseye) 2.31 49 / 0 41 / 0 —
Debian 12 (bookworm) 2.36 49 / 0 41 / 0 —
Debian 13 (trixie) 2.41 49 / 0 41 / 0 —
Rocky Linux 9 2.34 — — 60 / 0
AlmaLinux 9 2.34 — — 58 / 0
Rocky Linux 10 2.39 — — 61 / 0
AlmaLinux 10 2.39 — — 59 / 0
Fedora 42 2.41 — — 60 / 0
openSUSE Leap 15.6 2.38 — — 56 / 0
openSUSE Leap 16.0 2.40 — — 58 / 0

Chaque case se lit cas réussis / cas échoués. L'installeur marionnet-install.sh est mesuré à part, sur les sept systèmes Debian et Ubuntu : 504 cas, aucun échec.

Sur la famille RHEL 10, le score plein ne comprend pas de routeur : il n'y en a pas encore sur cette famille (§ 1.B).

Ce que le tableau veut dire pour votre machine. Marionnet et ses noyaux UML sont des programmes liés dynamiquement. Ils exigent une glibc au moins aussi récente que celle du système où ils ont été compilés, et jamais l'inverse. La version publiée est donc compilée sur le plus ancien système servi de chaque famille : Debian 11 (glibc 2.31) pour les paquets Debian et l'archive, Rocky Linux 9 (glibc 2.34) pour les paquets RPM. Toute distribution plus récente reçoit les mêmes fichiers, et vous n'avez aucune variante à choisir.

L'archive précompilée porte cette glibc minimale dans son nom de fichier (marionnet_<version>-r<rév>_<arch>_glibc<x.y>.tar.xz). marionnet-install.sh la lit là : sur une machine trop ancienne, il refuse et le dit, au lieu d'installer un programme qui ne démarrerait pas. Les paquets disent la même chose dans la langue de leur gestionnaire (libc6 (>= ...), libc.so.6(GLIBC_...)), et apt ou dnf les refusent d'eux-mêmes.

openSUSE Leap 15.6. Elle n'est servie que depuis la version publiée du 2026-09-13. Avant, Marionnet dépendait du paquet uml-utilities, compilé par le projet contre readline 8, alors que Leap 15.x fournit readline 7 : zypper refusait le paquet. Les deux programmes qu'il fallait de ce paquet, le client mconsole et le port-helper du noyau UML, sont maintenant compilés avec Marionnet, sans readline, sous les noms marionnet_uml_mconsole et marionnet_uml_port_helper.

Plus ancien que le tableau. Ubuntu 18.04 et Debian 10 ont une glibc trop ancienne et ne sont pas servies. Vous pouvez toujours y compiler Marionnet depuis les sources (§ 1.D), pourvu que leurs paquets suffisent.

1. Installer l'application : une seule méthode, au choix

Choisissez une des quatre méthodes 1.A à 1.D, selon votre machine ; les autres ne vous concernent pas. Les § 2, 3 et 4 valent ensuite pour toutes les méthodes.

Votre machine Prenez §
Debian, Ubuntu et dérivées le dépôt apt § 1.A
Fedora, famille RHEL (Rocky, AlmaLinux), openSUSE le dépôt dnf/zypper § 1.B
toute autre distribution, ou aucun gestionnaire de paquets voulu l'archive précompilée § 1.C
vous voulez modifier Marionnet les sources § 1.D

Avant toute méthode, sur une Debian ou une Ubuntu minimale

Une installation minimale n'a ni certificats ni curl. Installez-les d'abord, sinon rien ne peut lire le site.

Les trois méthodes lisent le site en https. Or une Debian ou une Ubuntu minimale, par exemple une image de conteneur, n'a aucun magasin de certificats (mesuré sur Debian 12 et 13, Ubuntu 24.04 et 26.04 ; les images RPM en ont un). Sans lui, apt ne lit pas le dépôt et l'installeur ne lit pas la liste des fichiers publiés, alors que le serveur répond.

sudo apt update && sudo apt install ca-certificates curl

curl est dans la même commande parce qu'une image slim n'a pas non plus de quoi télécharger, et le § 1.A en a besoin pour récupérer la clef (wget -O convient aussi bien que curl -o).

marionnet-install.sh reconnaît ce cas et le nomme, plutôt que d'accuser le réseau. Il ne peut pas le réparer lui-même : il faudrait pour cela le gestionnaire de paquets qui ne fonctionne pas encore.

1.A Debian et Ubuntu : le dépôt apt

Récupérer la clef du projet et vérifier son empreinte, déclarer le dépôt, installer marionnet. Mesuré sur Debian 12 et 13, Ubuntu 24.04 et 26.04.

# 1. la clef : récupérée, regardée (voir « La clef »), et alors seulement crue
sudo install -d /etc/apt/keyrings
sudo curl -o /etc/apt/keyrings/marionnet.asc \
     https://git.launchpad.net/marionnet/plain/marionnet-archive-keyring.asc
sudo apt install gnupg
# doit afficher l'empreinte ci-dessous
gpg --show-keys /etc/apt/keyrings/marionnet.asc

# 2. le dépôt, puis l'application
echo 'deb [signed-by=/etc/apt/keyrings/marionnet.asc] https://www.marionnet.org/download/apt/ ./' \
  | sudo tee /etc/apt/sources.list.d/marionnet.list
sudo apt update
sudo apt install marionnet

L'adresse download/apt suit toujours la série de versions en cours : vous n'aurez pas à modifier cette ligne quand la série changera.

La clef

Le dépôt est signé, et signed-by= demande à apt de vérifier la signature avec cette clef :

Marionnet Archive Signing Key <loddo@lipn.univ-paris13.fr>
4A65 3434 0BF9 7733 E74C  9DFC 12E4 6000 225F 0E56

Elle se récupère sur git.launchpad.net, et non sur www.marionnet.org. https prouve seulement que vous parlez au bon serveur ; quelqu'un qui prendrait le contrôle de ce serveur pourrait réécrire les paquets et les empreintes publiées à côté. La signature, elle, dépend d'une clef privée qui n'est pas sur ce serveur.

Dans une salle de TP, l'enseignant lit l'empreinte à voix haute en début de semestre : la question est réglée pour tout le monde.

Vérifiez la clef avant la ligne du dépôt, comme côté RPM (§ 1.B). Dès que signed-by= nomme le fichier, apt croit ce qu'il contient.

git.launchpad.net répond le plus souvent 200, mais environ une fois sur six il renvoie (302) vers sa page de connexion, et curl enregistre alors cette réponse dans le fichier. N'ajoutez pas -L : il suivrait le renvoi et enregistrerait la page de connexion, un échec qui a l'air d'une réussite.

Si gpg --show-keys affiche autre chose, ou rien, récupérez la clef de nouveau. Dans un script de déploiement, répétez le curl jusqu'à ce que gpg --show-keys affiche l'empreinte. apt n'a pas besoin de gnupg pour vérifier le dépôt ; c'est vous qui en avez besoin, pour lire ce que vous avez récupéré.

Les paquets

apt install marionnet installe l'application et le noyau 64 bits : marionnet-kernels est une recommandation (Recommends:), qu'apt suit par défaut. --no-install-recommends permet de s'en passer. Les images restent des suggestions (Suggests:) : plusieurs gibioctets se choisissent.

Côté RPM (§ 1.B), dnf install marionnet n'apporte que l'application. dnf saute sans rien dire la dépendance faible sur le noyau (qui tire glibc.i686) : ce canal la laisse donc en suggestion, et le dit après l'installation. Dans les deux cas, le message affiché après l'installation mesure ce qui manque encore et le nomme.

Sans image, aucune machine virtuelle ne démarre. Guignol est la seule image en paquet ; les images Debian (wheezy, trixie) viennent du § 2. Une machine virtuelle a besoin d'une image et d'un noyau que cette image déclare accepter.

Une image dont aucun noyau accepté n'est installé n'apparaît pas dans Marionnet. Rien n'échoue, aucun message ne s'affiche : elle est simplement absente de la liste.

Paquet Ce qu'il contient, et ce qui manque sans lui
marionnet-kernels le noyau UML 64 bits linux-6.12.95. Sans lui, les images récentes (Debian trixie, récupérée au § 2) ne sont pas proposées
marionnet-fs-guignol la petite image, machine et routeur, la seule image de routeur publiée. Sans elle, aucun routeur
marionnet-kernels-i386 le noyau UML 32 bits linux-6.12.95-i386. Sans lui, ni guignol ni wheezy ne sont proposés, ni aucun projet .mar antérieur à 2026

Un routeur demande deux paquets. Le fichier .conf de guignol déclare SUPPORTED_KERNELS='/3.2.[6-9]/ /-i386$/', que linux-6.12.95 ne satisfait pas. marionnet-fs-guignol demande donc marionnet-kernels-i386.

Ce noyau 32 bits demande à son tour une architecture étrangère activée sur votre machine : son interpréteur est /lib/ld-linux.so.2, et seul libc6:i386 fournit ce fichier. Pour le routeur, les deux paquets :

sudo dpkg --add-architecture i386 && sudo apt update
sudo apt install marionnet-kernels-i386 marionnet-fs-guignol

Sans l'architecture étrangère, apt refuse le paquet en nommant libc6:i386. L'activer est une décision que vous prenez : c'est pourquoi le noyau 32 bits est un paquet à part.

Si une archive précompilée (§ 1.C) a déjà été installée sur cette machine, /etc/marionnet/marionnet.conf existe déjà, et dpkg demande quoi en faire. Une installation non interactive échoue à cette question : DEBIAN_FRONTEND=noninteractive ne concerne que debconf, pas cette question de dpkg. Pour garder votre configuration :

sudo apt install -o Dpkg::Options::=--force-confold marionnet

La version du paquet est alors déposée à côté, sous le nom marionnet.conf.dpkg-dist. Les deux fichiers diffèrent sur un point qui compte : un paquet installe sous /usr, une archive sous /usr/local.

Quelle que soit la méthode, continuez au § 2 (images et noyaux), puis au § 3 (règle sudoers) et au § 4 (lancement).

1.B Fedora, famille RHEL et openSUSE : le dépôt dnf/zypper

Sur la famille RHEL, activer EPEL. Puis récupérer la clef, vérifier son empreinte et l'importer, déclarer le dépôt, installer marionnet et les paquets de données. Mesuré sur Fedora 42, Rocky Linux 10, AlmaLinux 10 et openSUSE Leap 16.

Sur la famille RHEL, activez d'abord EPEL : l'une des dépendances de Marionnet, gtksourceview3, s'y trouve et non dans les dépôts de base.

sudo dnf install epel-release

Les bancs d'essai activent aussi CRB (sudo dnf config-manager --set-enabled crb). Si dnf signale une dépendance qu'il ne sait pas résoudre, c'est la prochaine chose à activer. Puis, sur tout système de cette famille :

# 1. la clef : récupérée, regardée, et alors seulement importée
sudo install -d /etc/pki/rpm-gpg
sudo curl -o /etc/pki/rpm-gpg/RPM-GPG-KEY-marionnet \
     https://git.launchpad.net/marionnet/plain/marionnet-archive-keyring.asc
# doit afficher l'empreinte du § 1.A
gpg --show-keys /etc/pki/rpm-gpg/RPM-GPG-KEY-marionnet
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-marionnet

# 2. le dépôt, puis l'application (Fedora et famille RHEL)
sudo curl -o /etc/yum.repos.d/marionnet.repo \
     https://www.marionnet.org/download/rpm/marionnet.repo
sudo dnf install marionnet

Sur openSUSE, zypper ne lit pas /etc/yum.repos.d/. Après la même étape de clef, donnez-lui l'adresse du dépôt au lieu du fichier .repo :

sudo zypper addrepo --gpgcheck https://www.marionnet.org/download/rpm/ marionnet
sudo zypper install marionnet

Comme download/apt au § 1.A, l'adresse download/rpm suit toujours la série en cours.

La clef, de ce côté-ci

La clef est la même qu'au § 1.A, au même endroit, avec les mêmes précautions : le renvoi vers la page de connexion une fois sur six, et la répétition du curl dans un script.

On regarde la clef avant rpm --import : importer, c'est déjà faire confiance, et regarder après serait trop tard. Si gpg manque, installez gnupg2 (gpg2 sur openSUSE) ; ni dnf ni rpm n'en ont besoin.

La vérification a ici une autre forme, pas une autre force. apt vérifie une signature sur l'index, qui couvre tous les paquets par leur empreinte. rpm a deux mécanismes, et le fichier .repo demande les deux :

Réglage Ce qu'il vérifie
gpgcheck=1 chaque paquet, par une signature écrite dans le paquet lui-même
repo_gpgcheck=1 l'index, par le fichier repodata/repomd.xml.asc posé à côté

Le fichier .repo désigne la clef par un fichier local (gpgkey=file:///etc/pki/rpm-gpg/…), et non par une adresse : c'est pourquoi vous la récupérez vous-même. Avec une adresse, dnf téléchargerait la clef en suivant les renvois, sans qu'on puisse l'en empêcher. Une fois sur six, il obtiendrait la page de connexion, et l'installation s'arrêterait sur Failed to import OpenPGP keys, après le téléchargement de tous les paquets.

dnf peut encore afficher une empreinte et vous demander d'accepter la clef : il tient pour repo_gpgcheck un trousseau à lui, que rpm --import ne remplit pas. Comparez l'empreinte affichée avec celle du § 1.A avant de répondre oui.

Le dépôt fournit aussi vde2, sans lequel Marionnet ne fonctionne pas et qu'aucune distribution RPM ne propose (vérifié sur Rocky 9 avec EPEL, CRB et epel-next, et sur Fedora 42 et 44). Le projet le compile à partir du paquet source Debian, et dnf le trouve dans le même dépôt : vous n'avez rien à faire. openSUSE fournit son propre vde2, et c'est celui-là qui est installé.

Les paquets de données sont les trois du § 1.A, sous les mêmes noms et pour les mêmes raisons. dnf n'en installe aucun de lui-même :

# sur openSUSE : sudo zypper install ...
sudo dnf install marionnet-kernels marionnet-fs-guignol
# pas sur RHEL 10, voir ci-dessous
sudo dnf install marionnet-kernels-i386

Le noyau 32 bits n'a pas besoin ici d'un équivalent de dpkg --add-architecture : ces distributions installent les bibliothèques 32 bits à côté des 64 bits sans réglage préalable.

RHEL 10 a supprimé toutes les bibliothèques 32 bits : marionnet-kernels-i386 n'y est pas installable. Sans noyau 32 bits, ni guignol ni wheezy, donc pas de routeur sur la famille RHEL 10. C'est temporaire : une image de routeur 64 bits est prévue. C'est aussi pourquoi ce noyau est un paquet à part : son refus n'empêche pas d'installer le reste.

Quelle que soit la méthode, continuez au § 2 (images et noyaux), puis au § 3 (règle sudoers) et au § 4 (lancement).

1.C Toute autre distribution : l'archive précompilée

Une archive qui s'installe n'importe où, sans gestionnaire de paquets. marionnet-install.sh choisit la bonne et l'installe pour vous.

L'archive s'appelle marionnet_<version>-r<rév>_<arch>_glibc<x.y>.tar.xz. Les deux derniers champs décident de tout : elle tourne sur une machine d'architecture <arch> dont la glibc est au moins <x.y>. Elle est compilée sur le plus ancien système servi (aujourd'hui Debian 11, glibc 2.31, comme le dit son nom) ; Ubuntu 18.04 et Debian 10 la refusent donc, en nommant la glibc.

Cette forme n'est pas signée. Le fichier SHA256SUMS, que l'installeur vérifie pendant le téléchargement, prouve que l'archive est arrivée entière, pas qui l'a écrite : il vient du même serveur qu'elle. Si cette différence compte pour vous, prenez le § 1.A ou le § 1.B.

Le plus simple est de laisser l'installeur choisir l'archive et l'installer :

wget https://www.marionnet.org/download/marionnet-install.sh/marionnet-install.sh
bash marionnet-install.sh --binary --with-deps

--binary a besoin de root, et appelle sudo si vous ne l'êtes pas. Pour voir ce qui est publié avant d'installer quoi que ce soit, y compris ce que votre machine refuserait et pourquoi :

bash marionnet-install.sh --binary --fetch-only --list

--list s'accompagne d'un mode (--binary ici) : le mode dit si l'application, les images, ou les deux vous intéressent, et le script ne le devine pas. Sous son autre nom, marionnet-get-images, le mode est implicite (§ 2).

Vous pouvez aussi installer l'archive à la main :

xz -dc -T0 marionnet_<...>.tar.xz | tar xf -
cd marionnet_<...>/ && sudo ./install.sh --prefix /usr/local

install.sh est le même script dans les deux cas : l'installeur ne fait que lancer celui qui voyage dans l'archive. Il copie bin/ et share/ sous le préfixe, écrit /etc/marionnet/marionnet.conf (c'est ce qui permet à l'archive de vivre n'importe où) et accorde la règle sudoers (§ 3). Par défaut, il nomme les paquets apt manquants sans rien installer ; --with-deps les installe, --no-deps ne les cherche même pas. Son --help liste le reste.

La liste des paquets dont Marionnet a besoin pour tourner est dans l'archive, un nom par ligne, dans le fichier REQUIRED-PACKAGES-RUNTIME. Ce sont des noms Debian, les seuls que --with-deps sache installer. Sur une autre famille, installez vous-même leurs équivalents ; sur Fedora et la famille RHEL, préférez le § 1.B, car vde2 ne se trouve que dans le dépôt dnf de Marionnet. Sur un système de la famille Debian, à la main :

sudo apt install $(tr '\n' ' ' < REQUIRED-PACKAGES-RUNTIME)

Quelle que soit la méthode, continuez au § 2 (images et noyaux), puis au § 3 (règle sudoers) et au § 4 (lancement).

1.D Depuis les sources

Pour qui veut modifier Marionnet. Il faut OCaml 5.4.1 (par opam) et camlp4 ; les images et les noyaux viennent toujours du § 2.

Au départ, il ne faut que git et make : sur Debian ou Ubuntu, make dependencies installe le reste (opam, le compilateur C, les bibliothèques GTK).

git clone https://git.launchpad.net/marionnet && cd marionnet
# paquets apt (compilation et exécution), environnement et paquets opam
make dependencies
# dans chaque nouveau shell : mettre l'environnement opam dans le PATH
eval $(opam env)
# un clone frais n'a besoin de rien d'autre
dune build
# la cible appelle sudo elle-même, pour la seule étape qui l'exige
make install-final-as-root

Pour voir une à une les étapes de make dependencies, lancez-les séparément : make apt-dependencies, make opam-switch, make opam-dependencies.

Deux choses à savoir :

make install-for-testing accorde aussi la règle sudoers à votre compte. Les portes (§ 3) ne peuvent pas rester dans votre environnement opam, qui vous appartient : la cible les copie donc, en root, dans /usr/local/bin, puis accorde le bloc (a). Elle demande pour cela votre mot de passe sudo. make install-for-testing WITH_SUDOERS=no n'installe rien de privilégié.

Quelle que soit la méthode, continuez au § 2 (images et noyaux), puis au § 3 (règle sudoers) et au § 4 (lancement).

2. Les images et les noyaux UML, pour toutes les méthodes

marionnet-get-images présente les images et les noyaux publiés dans une liste à cocher, et installe ce que vous cochez, là où l'application les cherche.

Quelle que soit la méthode qui a installé l'application :

marionnet-get-images

C'est un autre nom de marionnet-install.sh (§ 1.C), installé avec l'application. Elle est nécessaire pour les images Debian ; si guignol vous suffit et que vous avez installé les paquets de données (§ 1.A, § 1.B), vous pouvez vous en passer.

Lancez-la sous votre compte (elle appelle sudo quand la destination n'est pas accessible en écriture) ou en root.

Pour une salle entière, ou dans un script de déploiement, marionnet-get-images --yes prend toute la sélection sans rien demander. --only <motif> et --exclude <motif> la restreignent.

Une image déjà installée apparaît cochée et grisée. La commande la reconnaît à sa date de modification, qui doit être celle qu'enregistre son fichier .conf (le champ MTIME) : c'est aussi ce que le noyau UML vérifie sur l'image de base d'une machine virtuelle.

Ne donnez pas --prefix après une installation par paquet. Sans --prefix, les images vont là où le Marionnet installé les cherche, ce que la commande demande à marionnet --paths : /usr/share/marionnet/... pour un paquet, /usr/local/share/marionnet/... pour une archive. Un --prefix écrit à la main dépose les images dans un répertoire que l'application ne lit jamais. Rien n'échoue, et les images n'apparaissent pas.

Les deux grandes images, Debian wheezy et Debian trixie, restent hors d'apt et de dnf à dessein : elles pèsent plusieurs gibioctets. La petite image guignol et les noyaux existent aussi en paquets (§ 1.A, § 1.B), si vous préférez que votre gestionnaire de paquets s'en occupe.

Une salle de TP sans accès à Internet. Faites une fois une copie (un miroir) du répertoire de publication. Le fichier SHA256SUMS liste tout ce qu'il contient, et sert de catalogue à l'installeur :

# une fois, sur une machine qui a accès à Internet (environ 1,5 Gio, compressés)
U=https://www.marionnet.org/download/marionnet-install.sh/1.0.x
mkdir -p /srv/marionnet-mirror && cd /srv/marionnet-mirror
wget "$U/SHA256SUMS"
awk -v u="$U" '{ print u "/" $2 }' SHA256SUMS | wget -i -
sha256sum -c SHA256SUMS

Puis faites pointer toutes les machines sur cette copie : l'installeur accepte un répertoire local comme une adresse. --fetch-only installe tous les noyaux et toutes les images publiés (environ 7 Gio une fois décompressés), et marionnet-install.sh est installé avec l'application, quelle que soit la méthode :

# --yes : aucune confirmation demandée, pour un script de déploiement
marionnet-install.sh --fetch-only --from /srv/marionnet-mirror --yes

3. La règle sudoers, pour toutes les méthodes

Marionnet crée ses interfaces réseau avec iproute2, ce qui demande une règle sudoers. Aucun paquet ne la pose : un paquet ne peut pas savoir à quels comptes la machine est destinée. L'administrateur la donne une fois.

En administrateur :

sudo marionnet-sudoers.sh install <login>...

Cette commande accorde le bloc (a), sans lequel Marionnet ne peut créer aucune interface réseau. L'install.sh de l'archive précompilée l'accorde pour vous (sauf avec --no-sudoers), comme make install-for-testing (§ 1.D). Pour tout retirer : sudo marionnet-sudoers.sh uninstall.

La règle autorise des portes, pas des commandes. Aucun des trois blocs ne nomme ip, iptables ou sysctl. Chacun nomme une porte, qui n'accepte qu'une liste fermée d'actions, et qui vérifie ses arguments en root avant d'agir.

Bloc Porte Actions autorisées
(a) marionnet-tap.sh, et marionnet-tun-device.sh (qui rend /dev/net/tun utilisable sur un hôte où il ne l'est pas) 4, plus 1
(b) marionnet-natbridge.sh priv, plus marionnet-dnsmasq.sh (le service DHCP et DNS) et marionnet-ipv6.sh 24, plus 3 et 2
(c) marionnet-lanbridge.sh priv 12

Les interfaces et les ponts de Marionnet portent dans leur nom un numéro de processus. Les anciennes règles devaient donc mettre un * à l'intérieur d'un argument. Or sudo-rs, le sudo d'Ubuntu 26.04, rejette tout le fichier dès qu'il en rencontre un : mesuré sur ubuntu:26.04, chacune de ces règles refusée, rien d'installé. Les portes ont réglé le problème.

Une porte doit appartenir à root, et chaque répertoire au-dessus d'elle aussi. Une règle NOPASSWD qui nomme un script que son propriétaire peut remplacer donne un shell root à ce propriétaire. install refuse donc dans ce cas, en nommant le chemin fautif et le chown ou le chmod qui le corrigerait.

Une archive précompilée installée dans votre répertoire personnel ne peut pas recevoir la règle telle quelle : ses portes sont sous un répertoire qui vous appartient. print et check y fonctionnent quand même, et montrent les règles avec le refus écrit dedans.

3.1 Accorder : un compte, plusieurs, ou une salle entière

Chaque install s'ajoute aux autorisations déjà données : autoriser une deuxième personne ne retire rien à la première. sudo marionnet-sudoers.sh uninstall <login> retire une autorisation et laisse les autres. Un compte qui n'existe pas est refusé : sudoers l'accepterait, et le droit irait au premier compte créé sous ce nom.

On peut autoriser un compte, ou un groupe, écrit comme dans sudoers (%groupe). C'est ce qu'il faut pour une salle de TP : celui qui la prépare ne connaît pas encore les comptes des étudiants.

# si le site n'a pas déjà un groupe à lui
sudo groupadd marionnet
# chaque compte (ou utilisez le groupe LDAP/AD existant)
sudo gpasswd -a <login> marionnet
sudo marionnet-sudoers.sh install %marionnet

Tout membre du groupe est alors autorisé, y compris celui qui s'inscrira la semaine prochaine. Des étudiants sans droit sudo auront aussi besoin du NAT bridge, accordé d'avance (§ 3.3).

ALL (tout le monde) est refusé : il engloberait les comptes système, et ce qu'un fichier accorde doit avoir été décidé par quelqu'un. Jusqu'à la version 1.0.423, un membre d'un groupe autorisé pouvait aussi créer une interface appartenant à quelqu'un d'autre. Ce n'est plus possible : le propriétaire de l'interface est le compte que sudo désigne comme appelant.

Vérifier une autorisation. sudo -l -U <login> donne les droits effectifs d'un compte. marionnet-sudoers.sh check ne connaît que les comptes et groupes que le fichier nomme : un membre d'un groupe autorisé n'en fait pas partie. Sans argument, check répond sur le fichier par son code de sortie :

Code Ce qu'il veut dire
0 le fichier est à jour pour les comptes qu'il nomme
1 rien n'est accordé
4 accordé, mais écrit par une version plus ancienne de Marionnet ; check --explain liste les commandes qu'une mise à jour gagnerait et perdrait, et marionnet-sudoers.sh install met à jour sans retirer le droit de personne
5 le fichier est bon, mais sudo ne l'applique pas (ci-dessous)

Le code 5. Dans sudoers, la dernière règle qui correspond l'emporte. Une règle plus large lue après la nôtre annule toutes nos lignes NOPASSWD sans changer un octet de notre fichier.

Un fichier /etc/sudoers.d/student contient student ALL=(ALL:ALL) ALL. Il est lu après marionnet (ordre alphabétique), et sudo demande un mot de passe à chaque action de Marionnet. Réinstaller ne change rien ; renommer le fichier large pour qu'il soit lu en premier règle le problème, puisque nos règles viennent alors en dernier et l'emportent :

# trouver la règle large
sudo -ll ; ls /etc/sudoers.d/
sudo mv /etc/sudoers.d/student /etc/sudoers.d/00-student

check pose la question à sudo lui-même, une fois par bloc, car la règle qui l'emporte se décide fichier par fichier : un voisin lu après marionnet-lanbridge annule le LAN bridge et rien d'autre. Il le fait en lançant une action sans effet de la porte de ce bloc. sudo -l ne suffirait pas : il dit si un compte a le droit de lancer la commande, pas s'il peut le faire sans mot de passe.

3.2 Les trois blocs, et ce que chacun fait à cette machine

À lire avant d'accorder autre chose que le bloc (a). Les trois blocs sont trois fichiers de /etc/sudoers.d/, accordés à des moments différents, et ils n'ont pas les mêmes effets sur la machine hôte.

Bloc Accordé Ce qu'il permet de faire à la machine hôte
(a) interfaces des machines virtuelles à l'installation, par l'administrateur Créer et détruire des interfaces mtap*, leur donner l'adresse 172.23.0.254/32 et y router 172.23.*.
(b) NAT bridge à l'utilisation, depuis Marionnet Construire un pont privé mnbr*, et traduire les adresses (NAT) des machines virtuelles qui sont derrière.
(c) LAN bridge à l'utilisation, depuis Marionnet Mettre la carte réseau de la machine hôte dans un pont, pour placer les machines virtuelles sur le vrai réseau local.

(a), en détail. Le bloc ne touche qu'aux interfaces mtap*, et c'est la porte qui le vérifie, en root : les quatre actions de marionnet-tap.sh contrôlent le nom qu'on leur donne, et le propriétaire de l'interface est le compte que sudo désigne comme appelant, pas un argument. Ces interfaces servent aussi de chemin aux applications graphiques des machines virtuelles : un xterm, ou surtout un wireshark lancé dans une machine virtuelle pour observer son propre trafic, s'affiche sur l'écran de l'hôte par ce chemin. Marionnet l'ouvre par xhost +172.23.0.254. Sans ce bloc, aucune application graphique ne s'ouvre depuis les machines virtuelles. Les routeurs, eux, n'ont pas d'applications graphiques : on y observe le trafic avec tcpdump.

(b), en détail. Le bloc :

Le routage IPv6 ne se règle pas interface par interface : l'activer fait de toute la machine hôte un routeur, et un routeur ignore les annonces qu'il reçoit. Une porte minuscule et sans argument, marionnet-ipv6.sh, enregistre donc la valeur de accept_ra et la remet en place.

La carte de l'hôte, ses adresses et ses routes ne sont jamais nommées dans ce bloc : il ne peut pas les toucher.

(c), en détail : c'est le réseau de la machine hôte, et on ne peut pas le cadrer. Un LAN bridge asservit la carte de l'hôte au pont mnlan0. L'adresse IPv4 et la route par défaut de l'hôte passent sur le pont, qui prend aussi l'adresse MAC de la carte. Il y en a un seul par machine (une carte n'a qu'un pont maître), et deux sessions de Marionnet le partagent.

À peser avant d'accorder (c) :

En clair, ce bloc permet à un compte de déplacer l'adresse IPv4 et la route par défaut de la machine sur un pont, une carte à la fois, tant que ce pont la revendique. Il n'y a ni iptables, ni NAT, ni IPv6 (pas géré du tout).

Le Wi-Fi est refusé : un point d'accès ne répond pas à plusieurs adresses MAC derrière une seule association. Sont refusées aussi une carte déjà asservie au pont de quelqu'un d'autre, et une route par défaut ambiguë.

3.3 Accorder (b) sans (c)

C'est la situation par défaut, et il n'y a rien à faire pour l'obtenir. Un install sans option n'accorde que (a), et les blocs de pont ne sont jamais accordés à l'installation. Quand un utilisateur démarre un NAT bridge ou un LAN bridge, Marionnet lui demande son propre mot de passe sudo, et installe le bloc. Le bloc (c) est donc réservé aux comptes qui ont le droit sudo.

Pour donner d'avance le NAT bridge à une salle, sans mot de passe et sans jamais accorder (c) :

sudo marionnet-sudoers.sh install --enable-natbridge %marionnet

Cette commande accorde aussi (a) : c'est la seule nécessaire. Pour retirer un bloc et garder (a) :

# pour tous les comptes
sudo marionnet-sudoers.sh uninstall --disable-natbridge
# pour un compte
sudo marionnet-sudoers.sh uninstall --disable-natbridge <login>

3.4 Interdire un bloc pour de bon

Retirer une autorisation n'empêche pas l'utilisateur suivant de la redemander depuis Marionnet, avec son propre mot de passe. Un administrateur qui ne veut aucun LAN bridge sur cette machine, jamais et pour personne, le dit une fois :

sudo marionnet-sudoers.sh deny --lanbridge     # ou --natbridge, ou --bridges

Tant que cette interdiction est en place :

sudo marionnet-sudoers.sh allow --lanbridge lève l'interdiction, sans rien accorder : un utilisateur doit toujours faire la demande. Tout le monde peut consulter l'état, sans privilège :

# code de sortie 0 si le bloc est permis, 3 s'il est interdit ; il dit lequel
marionnet-sudoers.sh policy

L'interdiction est un fichier de /etc/marionnet/, lisible par tous à dessein : Marionnet doit connaître la réponse avant de demander un mot de passe, et les fichiers de /etc/sudoers.d/ ne sont lisibles que par root.

Le bloc (a) n'a pas d'interdiction : c'est l'administrateur qui l'accorde à la main, et ne pas taper la commande suffit. Une interdiction arrête une erreur, pas un administrateur décidé, qui peut toujours éditer /etc/sudoers.d/. Elle est utile dans la configuration courante d'une salle, avec un enseignant qui a le droit sudo et des étudiants qui ne l'ont pas : c'est là qu'un LAN bridge se construit par accident.

4. Lancer Marionnet, et contrôler l'installation

marionnet                    # ou : marionnet -r lab.mar, marionnet --exam, marionnet --help

marionnet est le nom qu'emploient toutes les pages de cette documentation. C'est un lien symbolique vers marionnet.native, le nom que dune install donne à l'exécutable : le même programme.

Pour savoir si cette installation est bien celle que vous croyez, quelle que soit la méthode :

marionnet -v                 # version et révision
marionnet --paths            # où cette installation cherche images, noyaux et scripts

Si les images n'apparaissent pas, --paths affiche les répertoires où l'installation les cherche réellement (§ 2).

Pour savoir s'il reste quelque chose à faire, la commande est celle que les paquets apt et dnf lancent après l'installation ; vous en avez peut-être déjà lu la sortie :

# en root, pour que le fichier sudoers soit examiné aussi
marionnet-setup-check.sh

Elle ne dit rien quand rien ne manque. Sinon, elle nomme ce qui manque : l'état de la règle sudoers (§ 3.1), les images et les noyaux absents, la commande qui les récupérerait. Sur une autorisation périmée, elle affiche les commandes qu'une mise à jour gagnerait et perdrait, sur cette machine.

5. Désinstaller Marionnet

Dans les trois cas, la désinstallation laisse en place :

6. Quand quelque chose ne marche pas

Ce que vous voyez Ce que c'est
server down, no route, wrong URL?, alors que le site répond pas de certificats : § 1
apt dit que le dépôt est ignoré, et apt-get update renvoie quand même 0 même cause, ou la ligne du dépôt a été modifiée ; apt ne le signale que par un avertissement
Missing key <empreinte>, ou signature verification failed le fichier de /etc/apt/keyrings/ n'est pas la clef de l'archive : récupérez-la de nouveau (§ 1.A) et comparez l'empreinte
apt propose encore le paquet alors qu'il vient de refuser le dépôt il réutilise l'ancien index : sudo rm -rf /var/lib/apt/lists/* puis sudo apt update
Failed to import OpenPGP keys, ou dnf annonce un dépôt sans paquet le fichier de clef du § 1.B manque, n'a pas été accepté, ou n'est pas une clef : récupérez-le de nouveau et contrôlez l'empreinte avant de l'importer
l'archive précompilée est refusée, avec le nom d'une glibc votre distribution est plus ancienne que le système de compilation : § 1.C
marionnet-kernels-i386 est refusé, avec le nom libc6:i386 dpkg --add-architecture i386 : § 1.A
Marionnet démarre, mais les images n'apparaissent pas elles sont sous un préfixe que l'application ne lit pas : § 2, puis marionnet --paths
Unsatisfied dependency au démarrage vde2 ou graphviz manque ; l'install.sh de l'archive nomme ce qui manque, --with-deps l'installe
une machine virtuelle refuse de démarrer, les interfaces ne peuvent pas être créées la règle sudoers : § 3
rien ne s'ouvre quand on lance wireshark ou xterm dans une machine virtuelle le bloc (a) n'est pas accordé (§ 3.2), ou l'hôte n'a pas d'affichage X
marionnet-sudoers.sh install refuse, en nommant un chemin et un propriétaire une porte doit appartenir à root, avec tous ses répertoires parents : § 3. Typique d'une installation dans un répertoire qui vous appartient
la règle est installée, et sudo demande quand même un mot de passe une règle plus large de /etc/sudoers.d/ est lue après la nôtre et l'emporte : § 3.1, code 5
visudo ou sudo rejette tout le fichier sur Ubuntu 26.04 des règles écrites par un Marionnet antérieur aux portes : sudo marionnet-sudoers.sh install <login> les réécrit (§ 3)
le contrôle répète que l'autorisation est périmée, quoi que vous fassiez un Marionnet plus ancien que celui de cette page, sur une distribution RPM : son contrôle avait besoin de diff, absent de ces systèmes. Mettez Marionnet à jour

Où aller ensuite

Ces pages sont installées à côté de celle-ci. Elles se trouvent dans le répertoire doc-src/ du dépôt des sources, qui publie aussi la clef d'archive des § 1.A et § 1.B :

git clone https://git.launchpad.net/marionnet
Page À lire pour
INSTALL.md cette page en anglais
teacher-guide.FR.md préparer un TP, conduire la séance, la noter
scripting/README.FR.md piloter Marionnet depuis un script
exam-mode.FR.md ce qu'une session d'examen enregistre
project-format-v3.FR.md le format des projets .mar