Traduction française de
INSTALL.md. L'original anglais fait foi : en cas de divergence, c'est lui qu'il faut corriger, et cette page à sa suite.
Quelle méthode utiliser, ce que chacune installe sur le système de fichiers, et ce que vous devez ou pouvez faire ensuite.
Marionnet est publié sous trois formes prêtes à
l'emploi, toutes alimentées par le même répertoire de release
sur www.marionnet.org et portant toutes le même
binaire. Celle qu'il faut prendre dépend du gestionnaire de
paquets de votre machine, pas de ce que vous comptez faire de Marionnet
:
| Votre machine | Prenez | § |
|---|---|---|
| Debian, Ubuntu et dérivées | le dépôt apt | § 2 |
| Fedora, famille RHEL (Rocky, AlmaLinux), openSUSE | le dépôt dnf/zypper | § 3 |
| tout le reste — ou vous ne voulez aucun gestionnaire de paquets | le tarball précompilé | § 4 |
| vous comptez modifier Marionnet | depuis les sources | § 6 |
Les systèmes sur lesquels cette release a réellement été installée, et les chiffres qui le disent, sont juste en dessous.
Quelle que soit la méthode, les images invitées et les noyaux UML se récupèrent séparément (§ 5) : ils pèsent des gibioctets et changent à leur propre rythme. Marionnet démarre sans eux et le dit.
Marionnet est un programme graphique : il lui faut un affichage X
(DISPLAY), et il en ouvre l'accès aux invités avec
xhost (§ 7.2).
Tout chemin relatif de cette page est relatif au répertoire
où se trouve ce fichier : doc-src/ dans les
sources, <prefix>/share/doc/marionnet/ sur une
machine où Marionnet est installé.
Le tableau ci-dessous n'est pas une déclaration d'intention : chacune
de ses lignes a été mesurée, sur la release que décrit
cette page, par les quatre bancs de Makefile.d/*.bench/ et
bin/scripts/marionnet-install.sh.bench/ — chacun installant
Marionnet dans un conteneur nu de la distribution concernée,
puis demandant à la machine ce qu'elle a obtenu. Les chiffres sont les
cas que ces bancs ont joués, et les échecs qu'ils ont trouvés.
| Système | glibc | tarball (§ 4) | apt (§ 2) | dnf/zypper (§ 3) |
|---|---|---|---|---|
| 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 | — | — | 58 / 0 |
| AlmaLinux 9 | 2.34 | — | — | 56 / 0 |
| Rocky Linux 10 | 2.39 | — | — | 59 / 0 |
| AlmaLinux 10 | 2.39 | — | — | 57 / 0 |
| Fedora 42 | 2.41 | — | — | 58 / 0 |
| openSUSE Leap 16.0 | 2.40 | — | — | 56 / 0 |
| openSUSE Leap 15.6 | 2.38 | — | — | non servie, voir plus bas |
Lire réussis / échoués. L'installeur lui-même est mesuré à part, sur les sept boîtes Debian et Ubuntu à la fois : 504 cas, aucun échec.
Ce que le tableau veut dire pour votre machine. Marionnet est un programme lié dynamiquement, et les noyaux UML qu'il exécute le sont aussi : ce qu'ils exigent du système où ils atterrissent est une glibc au moins aussi récente que celle contre laquelle ils ont été compilés, et cette exigence ne voyage que vers l'avant. Cette release est construite sur Debian 11 (glibc 2.31) pour le versant Debian et sur Rocky Linux 9 (glibc 2.34) pour le versant RPM — les plus anciennes boîtes de chaque famille que nous servons. Toute distribution au-dessus de ces planchers est servie par les mêmes artefacts ; vous n'avez pas de build à choisir pour votre version.
Le tarball précompilé (§ 4) porte ce plancher dans son propre
nom de fichier
(marionnet_<version>-r<rév>_<arch>_glibc<x.y>.tar.xz),
et marionnet-install.sh l'y lit : sur une machine dont la
glibc est plus ancienne, l'installeur le dit et refuse, plutôt que de
déplier quelque chose qui ne pourrait pas démarrer. Le .deb
et le .rpm disent la même chose dans les mots de leur
propre gestionnaire de paquets — libc6 (>= ...),
libc.so.6(GLIBC_...) — de sorte qu'apt et dnf les refusent
d'eux-mêmes.
openSUSE Leap 15.6, et ce qui lui barrait la route.
Sa glibc (2.38) n'a jamais été l'obstacle. uml-utilities,
qu'aucune distribution RPM n'empaquette et que ce projet compilait donc
lui-même, est lié à libreadline.so.8, or Leap 15.x livre
readline 7 ; le refus était celui de zypper, et il nommait cette
bibliothèque. Depuis le 2026-09-12, Marionnet ne dépend plus du tout de
ce paquet : les deux programmes qu'il lui fallait — le client mconsole
et le port-helper qu'exécute le noyau UML — sont construits depuis ce
dépôt, sans readline, et installés sous les noms
marionnet_uml_mconsole et
marionnet_uml_port_helper. La release publiée avant
cette date porte encore l'ancienne dépendance ; la première
release publiée après elle sert Leap 15.6. Leap 16.0, elle, était déjà
servie.
Plus ancien que le tableau. Ubuntu 18.04 et Debian 10 sont sous les deux planchers et ne sont pas servies. Rien n'empêche de construire Marionnet depuis les sources (§ 6) sur un système que les canaux binaires n'atteignent pas, pourvu que ses paquets satisfassent le § 6.
Les trois méthodes atteignent le site en https, et
un système Debian ou Ubuntu minimal — notamment une image de
conteneur nue — ne porte aucun magasin de certificats
(mesuré sur Debian 12 et 13 et sur Ubuntu 24.04 et 26.04 ; les images de
la famille RPM, elles, en ont un). Sans lui, apt ne lira
pas notre dépôt et l'installeur ne lira pas le catalogue, alors même que
le serveur est parfaitement debout :
sudo apt update && sudo apt install ca-certificates curlcurl est dans cette ligne pour la même raison : une
image slim n'a pas non plus de téléchargeur, et le § 2 récupère
la clef de l'archive avec (wget -O à la place de
curl -o fait tout aussi bien).
marionnet-install.sh nomme cette cause
plutôt que d'accuser le réseau, mais il ne peut pas la réparer :
installer ce paquet demande le gestionnaire de paquets en état de marche
qui est précisément en jeu.
Mesuré sur Debian 12, Debian 13, Ubuntu 24.04 et Ubuntu 26.04.
sudo install -d /etc/apt/keyrings
sudo curl -o /etc/apt/keyrings/marionnet.asc \
https://git.launchpad.net/marionnet/plain/marionnet-archive-keyring.asc
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 marionnetdownload/apt est un point d'entrée
stable : il suit la série de publication courante, si bien que
la ligne ci-dessus n'a pas à être modifiée quand la série change.
Le fichier Release du dépôt est signé, et c'est
signed-by= qui fait qu'apt le vérifie. La clef est :
Marionnet Archive Signing Key <loddo@lipn.univ-paris13.fr>
4A65 3434 0BF9 7733 E74C 9DFC 12E4 6000 225F 0E56
Elle vient de git.launchpad.net, et non
de www.marionnet.org : c'est tout l'intérêt. https ne
prouve que ceci, que le serveur n'a pas été usurpé ; qui contrôle ce
serveur réécrit les paquets et les empreintes qui en répondent.
Une signature déplace le point de confiance vers une clef privée qui n'y
vit pas.
Ce qu'elle protège : les machines déjà
installées. Elles ne relisent jamais cette page — à chaque
apt upgrade elles contrôlent contre la clef présente sur
leur propre disque, si bien que personne qui prendrait le serveur demain
ne peut leur pousser une mise à jour piégée, sur des machines où
Marionnet installe une règle sudoers. Ce qu'elle ne protège pas
: votre toute première installation, si vous apprenez tout d'une page
compromise, qui nommerait une autre clef et vérifierait parfaitement. La
sortie est de comparer l'empreinte ci-dessus avec une source qui
n'est pas cette page : le dépôt git (§ Où aller
ensuite), un polycopié imprimé, une machine où Marionnet tourne
déjà. Dans une salle de TP, l'empreinte lue à voix haute une fois en
début de semestre règle la question pour tout le monde.
Contrôlez ce que vous avez récupéré — cette étape n'est pas
facultative. Mesuré : git.launchpad.net répond
200 la plupart du temps et, environ une requête sur six, un
302 vers sa page de connexion OpenID, et curl
écrit dans le fichier ce qui lui est revenu. N'ajoutez
pas -L : cela suit la redirection et écrit
la page de connexion — un échec qui ressemble à une
réussite.
sudo apt install gnupg
gpg --show-keys /etc/apt/keyrings/marionnet.asc # doit afficher l'empreinte ci-dessusSi autre chose s'affiche — ou rien — récupérez-la de nouveau. apt n'a
pas besoin de gnupg pour vérifier le dépôt (il a son propre
vérificateur) ; vous en avez besoin, vous, pour lire ce que
vous avez récupéré.
apt install marionnet installe l'application et
le noyau 64 bits : marionnet-kernels est un
Recommends:, qu'apt installe par défaut — sans noyau, rien
ne démarre du tout. (--no-install-recommends est là pour
qui n'en veut pas.) Les images, elles, restent des
Suggests: : des gibioctets sont un choix, pas une
implication. Au § 3, dnf install marionnet n'apporte que
l'application, et c'est mesuré, pas négligé : dnf saute
en silence la dépendance faible sur le noyau (qui tire
glibc.i686), donc ce canal la laisse en
Suggests: et le dit après l'installation. Dans les deux
cas, le message d'après-installation mesure ce qui
manque encore et le nomme.
Ce ne sont pas des accessoires : sans image, l'application ne démarre rien. Un invité a besoin d'un système de fichiers et d'un noyau que ce système de fichiers déclare supporter, et Marionnet ne propose pas un système de fichiers dont aucun noyau supporté n'est installé. Rien n'échoue et rien n'est dit : le composant est simplement absent de la liste.
| Paquet | Ce qu'il porte — 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) ne sont pas
proposées |
marionnet-fs-guignol |
la petite image invitée, machine et routeur — le seul système de fichiers de routeur publié. Sans lui, aucun routeur ne peut être construit |
marionnet-kernels-i386 |
le noyau UML 32 bits linux-6.12.95-i386. Sans lui,
guignol et wheezy ne sont pas proposés, et avec eux
tout projet .mar antérieur à 2026 |
Un routeur coûte deux paquets, pas un. Mesuré dans
le .conf publié : guignol déclare
SUPPORTED_KERNELS='/3.2.[6-9]/ /-i386$/', que
linux-6.12.95 ne satisfait pas. Donc
marionnet-fs-guignol exige
marionnet-kernels-i386 — le noyau 64 bits ne le fera pas
tourner — et l'architecture étrangère ci-dessous n'est pas affaire de
vieux projets seulement : c'est ce que coûte un routeur aujourd'hui.
marionnet-kernels-i386 exige une architecture
étrangère activée sur votre machine, parce que l'interpréteur
du noyau 32 bits est /lib/ld-linux.so.2 et que seul
libc6:i386 possède ce chemin :
sudo dpkg --add-architecture i386 && sudo apt update
sudo apt install marionnet-kernels-i386Sans cela, apt refuse le paquet en nommant libc6:i386.
Activer une architecture étrangère est une décision : c'est pourquoi le
noyau 32 bits est un paquet à part.
Si un tarball Marionnet (§ 4) a d'abord été installé sur
cette machine, /etc/marionnet/marionnet.conf
existe déjà et dpkg demandera quoi en faire — et un
apt install non interactif échoue
là, parce que DEBIAN_FRONTEND=noninteractive gouverne
debconf, et non l'invite de conffile de dpkg. Pour garder la
configuration que vous avez déjà :
sudo apt install -o Dpkg::Options::=--force-confold marionnetLa version du fichier livrée par le paquet est alors laissée à côté,
sous le nom marionnet.conf.dpkg-dist. Les deux divergent
sur un point qui compte : un paquet installe sous /usr, un
tarball sous /usr/local.
Mesuré sur Fedora 42, Rocky Linux 10, AlmaLinux 10 et openSUSE Leap 16.
# 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
gpg --show-keys /etc/pki/rpm-gpg/RPM-GPG-KEY-marionnet # doit afficher l'empreinte du § 2
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-marionnet
# 2. le dépôt, puis l'application
sudo curl -o /etc/yum.repos.d/marionnet.repo \
https://www.marionnet.org/download/rpm/marionnet.repo
sudo dnf install marionnet # zypper install marionnet, sur openSUSEdownload/rpm est le point d'entrée stable, comme
download/apt l'est pour le § 2.
Même clef, même endroit, mêmes réserves qu'au § 2 — y compris la
redirection une requête sur six. La ligne du milieu du bloc ci-dessus
vient avant rpm --import à dessein :
importer est l'acte de faire confiance, donc regarder ensuite
serait regarder trop tard. Si gpg manque :
sudo dnf install gnupg2 (zypper install gpg2
sur openSUSE) ; ni dnf ni rpm n'en ont
besoin.
Ce qui diffère, c'est la forme de la vérification, pas sa
force. Là où apt a une signature sur Release qui couvre
tous les paquets par leur empreinte, rpm a deux
mécanismes, et la strophe demande les deux :
| Réglage | Ce qu'il vérifie |
|---|---|
gpgcheck=1 |
chaque paquet, par une signature que
rpmsign a logée dans le fichier lui-même |
repo_gpgcheck=1 |
l'index, par le
repodata/repomd.xml.asc posé à côté |
La strophe nomme la clef par un fichier local
(gpgkey=file:///etc/pki/rpm-gpg/…) et non par une URL —
d'où le fait que vous la récupériez vous-même ci-dessus :
dnf récupère gpgkey= lui-même et suit les
redirections, sans qu'on puisse l'en empêcher, si bien qu'une URL
pointant sur git.launchpad.net télécharge la page de
connexion une fois sur six et fait mourir l'installation sur
Failed to import OpenPGP keys, après avoir téléchargé tous
les paquets.
dnf peut encore vous montrer une empreinte et vous
demander s'il faut accepter la clef : il tient un trousseau à lui pour
repo_gpgcheck, que le rpm --import n'alimente
pas. Comparez ce qu'il affiche avec l'empreinte du § 2 avant de répondre
oui.
Sur la famille RHEL, activez d'abord EPEL :
gtksourceview3, l'une des dépendances d'exécution de
Marionnet, y vit et non dans les dépôts de base.
sudo dnf install epel-releaseLe dépôt porte aussi vde2, sans lequel
Marionnet ne peut pas tourner et qu'aucune distribution RPM
n'empaquette (mesuré sur Rocky 9 avec EPEL, CRB et epel-next, et sur
Fedora 42 et 44) ; il est construit ici à partir du paquet source
Debian. dnf le résout depuis le même répertoire, si bien
que vous n'avez pas à savoir qu'il existe — sauf sur openSUSE, qui livre
vde2 et dont c'est le paquet qui est utilisé. Un second
paquet, uml-utilities, était porté de la même façon
jusqu'au 2026-09-12 ; un répertoire publié avant cette date le contient
encore, et plus rien ne l'installe.
Les trois paquets de données sont les mêmes qu'au § 2, sous les mêmes
noms, et nécessaires aux mêmes choses. Le multilib étant natif ici, le
noyau 32 bits n'a pas besoin d'un équivalent du
dpkg --add-architecture ; mais RHEL 10 a supprimé
tout le multilib 32 bits, si bien que sur cette famille
marionnet-kernels-i386 n'est tout simplement pas
installable — c'est pourquoi il est un paquet séparé : que son refus
n'emporte pas celui de 64 bits. Il faut en prendre la conséquence : pas
de noyau 32 bits, donc pas de guignol ni de wheezy, donc pas de
routeur sur RHEL 10 (§ 2) — état temporaire, la publication
d'une image de routeur 64 bits étant prévue.
L'application est aussi publiée sous la forme d'un tarball
relocatable, nommé
marionnet_<version>-r<rev>_<arch>_glibc<x.y>.tar.xz.
Les deux derniers champs sont ceux qui décident : l'artefact tourne sur
une machine dont l'architecture est <arch> et dont la
glibc est au moins <x.y>, le
versionnement des symboles de la glibc ne garantissant la compatibilité
que dans ce sens-là. L'artefact publié est construit sur le plus
ancien système que nous servons (actuellement Debian 12, glibc
2.36) : il tourne donc sur toutes les distributions listées aux § 2 et §
3, et sur aucune plus ancienne — Rocky 9 et openSUSE Leap 15.6 le
refusent en nommant la glibc.
Cette forme n'est pas signée :
SHA256SUMS, que l'installeur contrôle pendant le
téléchargement, prouve que le fichier est arrivé entier, pas qui l'a
écrit — le catalogue voyage par la même route que les tarballs. Si cette
distinction compte pour vous, prenez le § 2 ou le § 3.
Le plus simple est de laisser l'installeur choisir et déplier pour vous :
wget https://www.marionnet.org/download/marionnet-install.sh/marionnet-install.sh
bash marionnet-install.sh --binary --with-deps--binary exige root (il appelle sudo si
vous n'êtes pas root). Pour voir ce qui est publié avant d'installer
quoi que ce soit, demandez le catalogue — y compris ce qu'il
refuse, et pourquoi :
bash marionnet-install.sh --binary --fetch-only --list--list se donne avec un mode : c'est le mode
qui dit si l'application, les données, ou les deux vous intéressent, et
le script refuse de le deviner (sous son autre nom,
marionnet-get-images, le mode est implicite — § 5). À la
main, si vous préférez :
xz -dc -T0 marionnet_<...>.tar.xz | tar xf -
cd marionnet_<...>/ && sudo ./install.sh --prefix /usr/localinstall.sh est le même script dans les deux cas
— l'installeur ne fait que lancer celui qui voyage dans le tarball. Il
copie bin/ et share/ sous le préfixe, écrit
/etc/marionnet/marionnet.conf (c'est ce qui permet au
tarball de vivre n'importe où) et installe la règle sudoers (§ 7). Par
défaut il nomme les paquets apt manquants sans rien
installer ; --with-deps les installe,
--no-deps ne regarde même pas. Son --help
liste le reste.
Les paquets dont Marionnet a besoin à l'exécution voyagent dans le
tarball comme donnée, un nom par ligne, dans
REQUIRED-PACKAGES-RUNTIME. Sur un système de la famille
Debian, à la main :
sudo apt install $(tr '\n' ' ' < REQUIRED-PACKAGES-RUNTIME)Quelle que soit la méthode qui a installé l'application, voici la commande qui propose les images et les noyaux publiés sous forme de liste à cocher, et récupère ce que vous avez coché :
marionnet-get-imagesElle montre comme déjà installée — cochée, et non modifiable
— toute image dont la date de modification correspond au
MTIME que son .conf enregistre, lequel est le
champ que user-mode-linux lui-même contrôle sur un backing
file.
Ne passez pas --prefix après une installation
par paquet. Sans --prefix, les images vont là où
le Marionnet installé ici les cherche — demandé à
marionnet --paths, seul lecteur de la cascade de
configuration — soit /usr/share/marionnet/... pour un
paquet et /usr/local/share/marionnet/... pour un tarball.
Un --prefix écrit à la main, c'est ainsi que des images
finissent dans un répertoire que l'application ne lit jamais : rien
n'échoue, et les images n'apparaissent simplement pas.
Deux des images (Debian wheezy, Debian trixie) sont délibérément hors
d'apt et de dnf : elles pèsent des gibioctets. La petite image
guignol et les noyaux sont aussi disponibles en paquets (§
2, § 3), si vous préférez que votre gestionnaire de paquets en soit
propriétaire.
Pour une salle de TP sans accès à Internet, faites une fois un miroir du répertoire de release et pointez toutes les machines sur la copie — un répertoire local et une URL sont le même argument :
marionnet-install.sh --fetch-only --from /srv/marionnet-mirrorPour qui compte modifier Marionnet. La chaîne d'outils est OCaml 5.4.1 par opam, plus camlp4 ; les images invitées et les noyaux viennent toujours du § 5.
git clone https://git.launchpad.net/marionnet && cd marionnet
make dependencies # paquets apt (build + exécution), switch opam, paquets opam
dune build # un clone frais n'a besoin de rien d'autre : préprocesseurs camlp4,
# stubs C, version.ml et meta.ml sont tous construits par dune
make install-final-as-root # elle appelle sudo elle-même, pour la seule étape qui l'exigeLancez les parties de make dependencies séparément
(make apt-dependencies, make opam-switch,
make opam-dependencies) si vous voulez les voir une à une.
Deux choses à savoir :
dune build n'est pas un typecheck du
projet entier — pour un exécutable, dune ne compile que ce que
marionnet.ml atteint. make check compile tous
les modules.make install-for-testing (et
make rebuild-for-final /
make rebuild-for-testing quand vous passez de l'un à
l'autre : le préfixe est compilé dans le binaire comme valeur par
défaut). À noter qu'un tel préfixe, qui vous appartient et non à root,
ne peut pas se voir accorder de règle sudoers — le § 7
dit pourquoi, et ce qui y fonctionne quand même.Marionnet construit ses taps réseau avec
iproute2, ce qui exige une règle sudoers
cadrée. Aucune méthode d'installation ne l'accorde
automatiquement, et les paquets s'en abstiennent délibérément : une
installation de paquet ne peut pas savoir à quel humain une machine
appartient. Lancez, en tant qu'administrateur :
sudo marionnet-sudoers.sh install <user>...Cela accorde le socle — bloc (a) — sans lequel rien
ne marche. L'install.sh du tarball l'installe pour vous
(sauf --no-sudoers). Pour tout retirer :
sudo marionnet-sudoers.sh uninstall.
Ce qui est accordé est une porte, pas une commande.
Aucun des trois blocs ne nomme plus ip,
iptables ni sysctl. Chacun nomme un petit
script — une porte — que l'on franchit par un verbe littéral,
lequel valide ses arguments en root et refuse tout le reste. Le bloc (a)
accorde quatre de ces verbes de marionnet-tap.sh — plus une
ligne pour marionnet-tun-device.sh, la porte qui rend
/dev/net/tun utilisable sur un hôte où il ne l'est pas —,
le bloc (b) vingt-quatre verbes de
marionnet-natbridge.sh priv, et le bloc (c) douze de
marionnet-lanbridge.sh priv. La raison n'est pas une
affaire de style : un tap et un pont sont nommés d'après un identifiant
de processus, si bien que les anciennes règles devaient se cadrer par un
* à l'intérieur d'un argument, et
sudo-rs — le sudo d'Ubuntu 26.04 — rejette le
fichier entier dès qu'il en rencontre un. Mesuré sur
ubuntu:26.04 : chacune de ces règles refusée, rien
d'installé.
Une porte doit appartenir à root, et tout répertoire
au-dessus d'elle aussi. Une règle NOPASSWD qui
nomme un script que son propriétaire peut remplacer est
un shell root pour ce propriétaire : install
refuse donc — en nommant le chemin fautif et le
chown/chmod qui le réparerait — plutôt que
d'accorder. Deux conséquences à connaître avant de taper la commande
:
make install-for-testing, un tarball déballé dans votre
répertoire personnel) ne peut pas être autorisée telle
quelle ;print et check y fonctionnent toujours, et
montrent les règles avec le refus écrit dedans — c'est ce qui les rend
utilisables sur une machine de développement.La commande est additive : accorder le droit à une
deuxième personne ne retire jamais celui de la première, et
sudo marionnet-sudoers.sh uninstall <utilisateur>
retire une autorisation en laissant les autres en place. Un compte qui
n'existe pas est refusé — sudoers le nommerait volontiers, et le droit
tomberait dans les mains du premier à qui l'on créerait ce login.
Un principal est un compte, ou un groupe dans l'orthographe de sudoers. La salle de TP en est la raison : celui qui prépare une salle ne connaît pas les logins des étudiants qui s'y assiéront.
sudo groupadd marionnet # si le site n'a pas de groupe à lui
sudo gpasswd -a <login> marionnet # (ou utilisez le groupe LDAP/AD existant)
sudo marionnet-sudoers.sh install %marionnetTout membre du groupe est alors autorisé, y compris celui qui
s'inscrira la semaine prochaine. Une chose à savoir sur une autorisation
de groupe : ALL est refusé — ce qu'un
fichier accorde doit avoir été décidé par quelqu'un, et cela engloberait
les comptes système. (Jusqu'à la version 1.0.423 il y en avait une
seconde : un groupe ne pouvait pas lier le tap à un login, si bien qu'un
membre pouvait créer un tap appartenant à quelqu'un
d'autre. C'est fini : le propriétaire du tap n'est plus écrit
dans la règle du tout, c'est le compte que sudo désigne
comme appelant.)
sudo -l -U <login> est la question sur les droits
effectifs ; marionnet-sudoers.sh check répond sur les
principaux que le fichier nomme, si bien qu'un membre
d'un groupe autorisé n'en est pas un. Nu, check est une
question sur le fichier : est-il à jour pour les
comptes qu'il nomme (0), accordé mais écrit par une version antérieure
de Marionnet (4), ou pas accordé du tout (1) ? Sur un
4, check --explain nomme ce qu'un
rafraîchissement changerait, en commandes gagnées et perdues — et
rafraîchir, c'est marionnet-sudoers.sh install, qui est
additif et ne retire le droit de personne.
Et une quatrième réponse, 5, qui ne parle pas du fichier du
tout. Un fichier peut être parfait et sudo le refuser quand
même, car dans sudoers la dernière règle qui matche
gagne : une entrée plus large analysée après la nôtre — un
simple student ALL=(ALL:ALL) ALL déposé dans
/etc/sudoers.d/student, qui trie après
marionnet — annule chaque ligne NOPASSWD sans
changer un octet de notre fichier. Réinstaller ne changerait rien ;
renommer le fichier large pour qu'il soit analysé en
premier est le remède :
sudo -ll ; ls /etc/sudoers.d/ # trouver l'entrée large
sudo mv /etc/sudoers.d/student /etc/sudoers.d/00-studentcheck interroge sudo lui-même, une question par bloc —
le verdict est par fichier, si bien qu'un voisin trié
après marionnet-lanbridge annule le LAN bridge et rien
d'autre. Il interroge en lançant un no-op inoffensif de la porte propre
à ce bloc, seule question qui ait un sens ici : sudo -l
répond « ce compte a-t-il le droit de le lancer », pas « sans mot de
passe ».
À lire avant d'accorder quoi que ce soit au-delà du socle. Les trois
blocs sont trois fichiers de /etc/sudoers.d/, accordés à
trois moments différents, et ils ne sont pas également
dangereux.
| Bloc | Accordé | Ce qu'il permet de faire à l'hôte |
|---|---|---|
| (a) taps fantômes | à l'installation, par l'administrateur | Créer et détruire des interfaces mtap*, leur donner
l'adresse fixe 172.23.0.254/32 et y router
172.23.*. Confiné aux mtap* — et le cadrage
est désormais fait en root, par la porte : les quatre
verbes de marionnet-tap.sh vérifient le nom qu'on leur
donne, et le propriétaire du tap est le compte que sudo
désigne comme appelant, pas un argument que n'importe qui peut écrire.
Ce tap est aussi la route par laquelle les clients X11 d'un invité
atteignent l'affichage de l'hôte — xterm sur une machine ou
un routeur, et surtout wireshark lancé
dans un routeur ou une machine pour capturer son propre trafic ;
Marionnet en ouvre la porte par xhost +172.23.0.254. Sans
ce bloc, Marionnet tourne en mode dégradé : pas de graphique depuis les
invités, pas de terminaux de routeur. |
| (b) NAT bridge | à l'exécution, depuis l'interface | Construire le pont privé mnbr* et faire du NAT pour les
invités derrière lui. |
| (c) LAN bridge | à l'exécution, depuis l'interface | Mettre la carte réseau de l'hôte dans un pont, pour que les invités soient sur le vrai réseau local. |
(b), en détail. Il crée un pont mnbr*
portant l'adresse .1/24 d'un réseau privé ; il met
net.ipv4.ip_forward à 1, ce qui vaut pour
toute la machine et non par interface (Marionnet ne le remet à 0 au
démontage que s'il l'a lui-même mis à 1) ; il ajoute une règle
MASQUERADE et deux règles FORWARD avec
iptables, toutes porteuses du commentaire
marionnet-natbridge:mnbr* — ce marqueur est
construit par la porte, à partir d'un nom de pont
qu'elle vient de valider, si bien qu'aucune règle préexistante de votre
pare-feu ne peut être ajoutée, modifiée ni supprimée par cette
autorisation. Ce qui est accordé ici, ce sont les vingt-quatre verbes de
marionnet-natbridge.sh priv, qui valident leurs arguments
en root — la porte, encore, et le marqueur ci-dessus fait partie de ce
qu'elle calcule au lieu de l'accepter. Facultativement, il démarre un
dnsmasq lié à ce seul pont (DHCP en
.100-.200, plus le DNS pour les invités) — c'est pourquoi
dnsmasq-base est une dépendance d'exécution.
Facultativement encore, l'IPv6 : une ULA /64, des
Router Advertisements émis par ce même dnsmasq, et du NAT66 sur
ip6tables — et comme le forwarding IPv6 n'est
pas par interface, l'activer fait de tout l'hôte un
routeur, or un routeur ignore les annonces qu'il reçoit ; une porte
minuscule et sans argument (marionnet-ipv6.sh) mémorise
donc et restitue accept_ra. La carte de l'hôte, ses
adresses et ses routes ne sont jamais nommées dans ce
bloc : elles ne peuvent pas être touchées par lui.
(c), en détail — c'est le réseau de l'hôte, et cela ne peut
pas être cadré. Un LAN bridge est la carte de
l'hôte asservie à mnlan0, avec l'adresse IPv4 et la route
par défaut de l'hôte déplacées sur le pont et l'adresse
MAC de la carte clonée dessus. Il y en a exactement un par machine (une
carte n'a qu'un maître), donc deux sessions Marionnet le partagent. À
peser avant de l'accorder :
marionnet-lanbridge.sh priv …) qui décide, en root, quelle
carte elle a le droit de toucher — celle qu'un pont LAN de Marionnet
revendique dans son alias, et aucune autre. Ce que l'autorisation vaut
encore, en clair : ce compte peut déplacer l'adresse IPv4 et la
route par défaut de cette machine sur un pont, une carte à la fois,
tant que ce pont la revendique. Aucun iptables n'est en
jeu, pas de NAT, et pas d'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), de même qu'une carte déjà asservie au pont de quelqu'un d'autre, ou une route par défaut ambiguë.
C'est le défaut, et il n'y a rien à faire pour
l'obtenir : un install nu n'accorde que (a), et aucun des
deux blocs de pont n'est jamais accordé à l'installation. Quand un
utilisateur démarre un composant bridge, Marionnet demande
son propre mot de passe sudo et installe ce bloc — (c)
est donc déjà réservé aux comptes qui peuvent faire du sudo à
l'exécution, bien après l'installation faite par l'administrateur.
Pour donner d'avance le NAT bridge à une salle, sans qu'aucun mot de passe soit demandé et sans que (c) entre jamais en jeu :
sudo marionnet-sudoers.sh install --enable-natbridge %marionnetet, symétriquement, pour retirer un bloc en laissant le socle tranquille :
sudo marionnet-sudoers.sh uninstall --disable-lanbridge # tous les comptes
sudo marionnet-sudoers.sh uninstall --disable-lanbridge <user>Retirer une autorisation n'empêche pas l'utilisateur suivant de la redemander, depuis l'interface, avec son propre mot de passe. Un administrateur qui ne veut pas qu'un LAN bridge soit construit sur cette machine — jamais, par personne — le dit une fois :
sudo marionnet-sudoers.sh deny --lanbridge # ou --natbridge, ou --bridgesTant que ce veto est en place : le bloc est refusé à tout le monde,
l'autorisation déjà en place est reprise (la laisser
ferait du veto un mensonge), et Marionnet le dit dans son
interface au lieu de demander un mot de passe. On le lève par
sudo marionnet-sudoers.sh allow --lanbridge — ce qui
n'accorde rien : un utilisateur doit toujours demander. N'importe qui
peut consulter l'état, sans aucun privilège :
marionnet-sudoers.sh policy # rc 0 si autorisé, 3 si interdit ; il dit lequelLe veto 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 un fichier de /etc/sudoers.d/
est en 0440 root, comme il se doit.
Le socle — bloc (a) — n'a pas de veto : c'est
l'administrateur qui l'accorde à la main, donc l'interdire reviendrait à
ne pas taper la commande. Et un veto arrête une erreur,
pas un administrateur déterminé, qui édite /etc/sudoers.d/
directement. Là où il mord, c'est la configuration ordinaire d'une salle
— un enseignant qui peut faire du sudo, des étudiants qui ne peuvent pas
— et c'est exactement là qu'un LAN bridge se construit par accident.
marionnet # ou : marionnet -r lab.mar, marionnet --exam, marionnet --helpmarionnet est le nom que tape chaque page de cette
documentation — le guide de l'enseignant, le mode examen, les exemples
du canal de contrôle, les scripts de TP. C'est un lien symbolique vers
marionnet.native, le nom que dune install
donne à l'exécutable : le même programme, sous le nom qu'emploie un
humain.
Deux commandes répondent à « cette installation est-elle bien celle que je crois ? », quelle que soit la méthode qui l'a posée :
marionnet -v # version et révision
marionnet --paths # où cette installation cherche images, noyaux et scripts--paths est la réponse à « les images n'apparaissent
pas » : il affiche les répertoires que la cascade de configuration
a effectivement résolus (§ 5).
Et une commande répond à « reste-t-il quelque chose à faire ? » — la même que les canaux apt et dnf lancent après l'installation, ce qui explique que vous en ayez peut-être déjà lu la sortie :
marionnet-setup-check.sh # en root, pour que le fichier sudoers soit examiné aussiElle mesure au lieu de réciter : elle ne dit rien quand rien ne manque, et quand quelque chose manque, elle nomme quoi — l'état de la règle sudoers (§ 7.1), les images et les noyaux absents, la commande qui les rapatrierait. Sur une autorisation périmée, elle affiche les commandes exactes qu'un rafraîchissement gagnerait et perdrait, sur cette machine, au lieu de citer un exemple qui pourrait n'être vrai qu'ailleurs.
sudo apt purge marionnet marionnet-kernels marionnet-kernels-i386 marionnet-fs-guignolsudo dnf remove marionnet marionnet-kernels marionnet-kernels-i386 marionnet-fs-guignol
(sudo zypper remove ..., sur openSUSE)README qu'il contient
liste ce qu'il faut supprimer, préfixe par préfixe.Dans les trois cas, la règle sudoers n'ayant jamais été accordée par
l'installation, elle n'est pas retirée par la désinstallation :
sudo marionnet-sudoers.sh uninstall.
| Symptôme | Ce que c'est |
|---|---|
server down, no route, wrong URL? alors que le site est
debout |
pas de magasin de certificats — § 1 |
apt dit que le dépôt est ignoré, et apt-get update sort
quand même avec 0 |
même cause, ou la ligne du sources.list a été modifiée
; apt rapporte cela comme 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 (§ 2) et comparez l'empreinte |
| apt continue de proposer le paquet alors qu'il vient de refuser le dépôt | il réutilise l'index qu'il avait déjà :
sudo rm -rf /var/lib/apt/lists/* puis
apt update |
Failed to import OpenPGP keys, ou dnf annonce que le
dépôt n'a aucun paquet |
le fichier de clef du § 3 est absent, n'a pas été accepté, ou n'est pas une clef du tout — récupérez-le de nouveau et contrôlez l'empreinte avant d'importer |
| le tarball est refusé, en nommant une glibc | votre distribution est plus ancienne que le plancher de compilation — § 4 |
marionnet-kernels-i386 est refusé, en nommant
libc6:i386 |
dpkg --add-architecture i386 — § 2 |
| Marionnet démarre mais les images invitées n'apparaissent pas | elles ont été déposées sous un préfixe que l'application ne lit pas
— § 5, puis marionnet --paths |
| Unsatisfied dependency au démarrage | vde2 ou graphviz manque ;
l'install.sh du tarball nomme ce qui manque,
--with-deps l'installe |
| une machine virtuelle refuse de démarrer, les taps ne peuvent pas être construits | la règle sudoers — § 7 |
rien ne s'ouvre quand un invité lance wireshark ou
xterm |
le bloc (a) n'est pas accordé (§ 7.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 de bout en bout — § 7. Typique d'une installation sous un préfixe qui vous appartient |
| la règle est installée, et sudo demande quand même un mot de passe | une entrée plus large de /etc/sudoers.d/ est analysée
après la nôtre et gagne — § 7.1, état 5 |
visudo ou sudo rejette le fichier entier
sur Ubuntu 26.04 |
des règles écrites par un Marionnet antérieur aux portes :
sudo marionnet-sudoers.sh install <utilisateur> les
réécrit — § 7 |
| le contrôle répète que l'autorisation est périmée, quoi que vous fassiez | un Marionnet plus ancien que celui livré avec cette page, sur une
distribution RPM : son contrôle avait besoin de diff, que
ces images ne portent pas, et lisait l'outil manquant comme un
périmé — la mise à jour est le remède |
Ces pages sont installées à côté de celle-ci ; sauf mention
contraire, elles sont en anglais. Elles vivent dans
doc-src/ du dépôt des sources, qui est aussi là où est
publiée la clef d'archive des § 2 et § 3 :
git clone https://git.launchpad.net/marionnet| Page | À lire pour |
|---|---|
INSTALL.md |
cette même page en anglais — c'est elle qui fait foi |
teacher-guide.md |
préparer un TP, conduire la séance, la noter |
scripting/README.md |
piloter Marionnet depuis un script, par le canal de contrôle |
exam-mode.md |
ce qu'une session d'examen enregistre |
project-format-v3.md |
le format de projet .mar |