diff --git a/subject/2/Makefile b/subject/2/Makefile index 3e5ce0a..94f0b3d 100644 --- a/subject/2/Makefile +++ b/subject/2/Makefile @@ -1,4 +1,4 @@ -SOURCES = subject.md project-part1.md project-part2.md rendu.md end.md +SOURCES = subject.md project-part1.md project-part2.md sample.md rendu.md end.md PANDOCOPTS = --latex-engine=xelatex \ --standalone \ --normalize \ diff --git a/subject/2/project-part1.md b/subject/2/project-part1.md index 71d50dc..797f27b 100644 --- a/subject/2/project-part1.md +++ b/subject/2/project-part1.md @@ -1,4 +1,4 @@ -### Palier 1 : Restreindre l'environnement (2 points) +## Palier 1 : Restreindre l'environnement (2 points) {.unnumbered} Après avoir mis en place les bases de votre programme, commencez par créer les différentes hiérarchies (si vous avez un noyau récent, vous pouvez utiliser les @@ -17,28 +17,28 @@ moulinette ne possède pas tous ces *CGroup*s, au lieu de planter, ne rien faire n'est pas forcément une mauvaise solution. -### Palier 2 : Réduire les *capabilities* (2 points) +## Palier 2 : Réduire les *capabilities* (2 points) {.unnumbered} Réduisez au maximum les *capabilities*, de telle sorte qu'il ne soit pas possible de faire un ping dans l'environnement restreint :
```shell -42sh# ping 8.8.8.8 -PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. -64 bytes from 8.8.8.8: icmp_seq=1 ttl=56 time=3.93 ms -64 bytes from 8.8.8.8: icmp_seq=2 ttl=56 time=3.97 ms -^C ---- 8.8.8.8 ping statistics --- -2 packets transmitted, 2 received, 0% packet loss, time 1002ms -rtt min/avg/max/mdev = 3.931/3.954/3.978/0.067 ms + 42sh# ping 9.9.9.9 + PING 9.9.9.9 (9.9.9.9) 56(84) bytes of data. + 64 bytes from 9.9.9.9: icmp_seq=1 ttl=56 time=3.93 ms + 64 bytes from 9.9.9.9: icmp_seq=2 ttl=56 time=3.97 ms + ^C + --- 9.9.9.9 ping statistics --- + 2 packets transmitted, 2 received, 0% packet loss, time 1002ms + rtt min/avg/max/mdev = 3.931/3.954/3.978/0.067 ms -42sh# ./mymoulette /bin/bash - bash# curl http://www.linuxcontainers.org/ | md5sum - 59e714c4331e71ac3529a6502994ef1d + 42sh# ./mymoulette /bin/bash + bash# curl http://www.linuxcontainers.org/ | md5sum + c7d68d1cb4737125a84cd69f55add202 - bash# ping 8.8.8.8 - ping: icmp open socket: Permission denied + bash# ping 9.9.9.9 + ping: icmp open socket: Permission denied ```
@@ -48,14 +48,14 @@ Aidez-vous du visualisateur de *capabilities* de la partie 4, pour voir si vous êtes sur la bonne voie. -### Palier 3 : Utilisable par un utilisateur (1 point) +## Palier 3 : Utilisable par un utilisateur (1 point) {.unnumbered} Jouez avec les attributs étendus pour qu'un utilisateur non-privilégié puisse exécuter votre moulinette. Ajoutez la/les commande(s) à votre Makefile ou script d'installation. -### Création d'un environnement d'exécution minimal +## Création d'un environnement d'exécution minimal {.unnumbered} Plutôt que d'utiliser votre système hôte au complet, avec tous ses programmes et toutes ses bibliothèques, il faudrait utiliser un système contenant le @@ -66,15 +66,40 @@ dans la partie sur les *chroot*. sera seulement utile pour faire des tests.** -### Palier 4 : Isolation du pauvre (1 point) +## Palier 4 : Isolation du pauvre (1 point) {.unnumbered} Nous n'avons pas encore vu de meilleure méthode pour mieux isoler l'environnement que de faire un `chroot`, ajoutez à votre programme cette isolation rudimentaire. Et rendez-vous au prochain cours pour avoir une meilleure isolation ! +
+```shell + 42sh$ which firefox + /usr/bin/firefox + 42sh# ./mymoulette ./newrootfs/ /bin/bash + bash# which firefox + which: no firefox in (/usr/bin:/usr/local/bin:/bin:/opt/bin) +``` +
-### Palier 5 (bonus) : automatisation de la création de l'environnement (5 points) + +## Palier 5 : seccomp (2 points) {.unnumbered} + +Filtrez les appels systèmes de telle sorte qu'aucun programme exécuté dans +votre bac à sable ne puisse plus lancer les appels systèmes suivants : + +* `nfsservctl(2)` ; +* `personality(2)` ; +* `pivot_root(2)` ; +* ... + +N'hésitez pas à en utiliser d'autres pour vos tests ;) + +Astuces : `seccomp(2)`, `seccomp_init(3)`, `seccomp_load(3)`, ... + + +## Palier bonus : Automatisation de la création de l'environnement (5 points) {.unnumbered} Pour *moulinéter* plusieurs étudiants en parallèle, vous allez avoir besoin de plusieurs environnements identiques. Plutôt que de recopier cet environnement, @@ -86,3 +111,7 @@ L'usage est laissé à votre discrétion : vous pouvez ajouter un/des paramètre votre *moulette* pour indiquer le volume LVM à utiliser ou le définir en dur ou encore séparer la création de l'environnement et de la snapshot initiale dans un programme distinct. + +Si votre noyau dispose d'un UnionFS (AUFS ou OverlayFS par exemple), ou que +vous disposez d'une partition `btrfs`, vous pouvez utiliser l'une de ces +méthodes pour ajouter une couche en écriture, à la place de LVM. diff --git a/subject/2/project-part2.md b/subject/2/project-part2.md index 111ece7..962280b 100644 --- a/subject/2/project-part2.md +++ b/subject/2/project-part2.md @@ -1,7 +1,7 @@ -### Palier 5 : Une vraie isolation (3 points) +## Palier 6 : Une vraie isolation (2 points) {.unnumbered} En plus du `chroot`, assignez de nouveaux *namespaces* au processus que vous -allez lancer : `cgroups`, `IPC`, `mount`, `net`, `PID`, `UTS`, `user`. +allez lancer : `cgroups`, `IPC`, `mount`, `net`, `PID`, `UTS`. Il est requis que le nouveau processus ne puisse pas s'échapper de ses *namespaces* ! @@ -9,7 +9,17 @@ Il est requis que le nouveau processus ne puisse pas s'échapper de ses Astuce : `unshare(2)`. -### Palier 6 : Empêcher les fuites d'information (2 points) +## Palier bonus : Révolution des utilisateurs (2 points) {.unnumbered} + +Utilisez le *namespace* `user` pour vous permettre de ne plus avoir besoin de +lancer votre moulinette en tant que `root` ou avec plus de *capabilities* que +nécessaire dans vos attributs étendus. + +Vous aurez besoin de déplacer le code écrit pour les premiers paliers (cgroups, +caps, ...), après vous être dissocié de cet espace de noms. + + +## Palier 7 : Empêcher les fuites d'information (2 points) {.unnumbered} Démontez tous les systèmes de fichiers qui ne sont pas nécessaires au fonctionnement de votre conteneur et remontez les partitions @@ -20,33 +30,69 @@ opération est nécessaire afin de terminer l'étape d'isolation. Astuce : `mount(2)`. -### Palier 7 : Identification du conteneur (1 point) +## Palier 7 bis : Volume attaché au code à moulinéter (1 point) {.unnumbered} + +Ajoutez une option à votre moulinette afin de lier le dossier (qui se trouve +sur la machine hôte) contenant le code d'un étudiant, à l'intérieur du +conteneur. Cette option est similaire à l'option `--volume`/`-v` de Docker : + +L'option devra attendre le répertoire contenant le code de l'étudiant, et le +monter dans `/home/student` : + +
+``` + 42sh$ ./mymoulette ./newrootfs/ /bin/bash + bash# ls /home/student/ + bash# + 42sh$ ./mymoulette -v /var/lib/git/login_x/42sh/ ./newrootfs/ /bin/bash + bash# ls /home/student/ + src/ tests/ AUTHORS configure Makefile.am README TODO + bash# +``` +
+ +Astuce : `mount(2)`, `mkdir(2)`. + + +## Palier 8 : Identification du conteneur (1 point) {.unnumbered} Maintenant que vous avez votre conteneur, personalisez-le un peu en lui donnant un nom unique. Astuce : `sethostname(2)` +
+``` + 42sh$ ./mymoulette ./newrootfs/ hostname + ush9ukohh3Ch + 42sh$ ./mymoulette ./newrootfs/ hostname + shie6aif2aiH +``` +
-### Palier 8 : `pivot_root` (4 points) + +## Palier 9 : `pivot_root` (3 points) {.unnumbered} Effectuez un `pivot_root(2)` de telle sorte qu'il ne reste plus de trace du système de fichiers hôte. Astuce : `pivot_root(2)`, `umount(2)`. +Attention : vos filtres `seccomp` filtrant l'appel système `pivot_root(2)`, +vous devrez donc ne les appliquer qu'après cette étape. -### Palier 9 : Bac à sable connecté (4 points) + +## Palier 10 : Bac à sable connecté (2 points) {.unnumbered} Partant d'une liste d'interfaces sur la machine hôte similaire à :
``` -42sh$ ip link -1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1 - link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 -2: eth0: mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 - link/ether 90:2b:34:5e:fa:a7 brd ff:ff:ff:ff:ff:ff + 42sh$ ip link + 1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + 2: eth0: mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 + link/ether 90:2b:34:5e:fa:a7 brd ff:ff:ff:ff:ff:ff ```
@@ -54,23 +100,23 @@ Vous devrez pouvoir `ping`er votre conteneur depuis votre hôte :
``` -42sh$ ip address -1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 -[...] -2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 -[...] -3: veth3e06cad@if82: mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default - link/ether 42:a2:a0:89:54:ef brd ff:ff:ff:ff:ff:ff - inet 10.10.10.41/24 brd 10.10.10.255 scope global veth3e06cad - valid_lft forever preferred_lft forever -42sh$ ping 10.10.10.42 -PING 10.10.10.42 (10.10.10.42) 56(84) bytes of data. -64 bytes from 10.10.10.42: icmp_seq=1 ttl=56 time=3.90 ms -64 bytes from 10.10.10.42: icmp_seq=2 ttl=56 time=3.78 ms -^C ---- 10.10.10.42 ping statistics --- -2 packets transmitted, 2 received, 0% packet loss, time 1003ms -rtt min/avg/max/mdev = 3.789/3.847/3.906/0.085 ms + 42sh$ ip address + 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 + [...] + 2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 + [...] + 3: veth3e06cad@if82: mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default + link/ether 42:a2:a0:89:54:ef brd ff:ff:ff:ff:ff:ff + inet 10.10.10.41/24 brd 10.10.10.255 scope global veth3e06cad + valid_lft forever preferred_lft forever + 42sh$ ping 10.10.10.42 + PING 10.10.10.42 (10.10.10.42) 56(84) bytes of data. + 64 bytes from 10.10.10.42: icmp_seq=1 ttl=56 time=3.90 ms + 64 bytes from 10.10.10.42: icmp_seq=2 ttl=56 time=3.78 ms + ^C + --- 10.10.10.42 ping statistics --- + 2 packets transmitted, 2 received, 0% packet loss, time 1003ms + rtt min/avg/max/mdev = 3.789/3.847/3.906/0.085 ms ```
@@ -79,15 +125,3 @@ tandis que la machine hôte a l'IP `10.10.10.41`. Astuces : vous pouvez utiliser la `libnetlink(3)` ou même faire des appels aux programmes `ip(8)`, `brctl(8)`, ... - - -### Palier 10 (bonus) : seccomp (2 points) - -Filtrez les appels systèmes de telle sorte qu'aucun programme exécuté dans -votre bac à sable ne puisse plus lancer les appels systèmes suivants : - -* `nfsservctl(2)` ; -* `personality(2)` ; -* `pivot_root(2)`. - -Astuce : `seccomp(2)`. diff --git a/subject/2/sample.md b/subject/2/sample.md new file mode 100644 index 0000000..6d49a14 --- /dev/null +++ b/subject/2/sample.md @@ -0,0 +1,59 @@ +Exemples +======== + +## Arguments de la ligne de commande + +
+``` + 42sh$ ./mymoulette -h + MyMoulette, the students' nightmare, now highly secured + Usage: ./mymoulette [-v student_workdir] environment moulette_prog [moulette_arg [...]] + environment is the path to the directory containing the new rootfs + moulette_prog will be the first program to be launched, must already be in the environment + student_workdir is the directory containing the code to grade +``` +
+ + +## Réseau accessible + +
+``` + 42sh$ ip address show veth0l + 2: veth0l@if82: mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default + link/ether 42:a2:a0:89:54:ef brd ff:ff:ff:ff:ff:ff + inet 10.10.10.41/24 brd 10.10.10.255 scope global veth3e06cad + valid_lft forever preferred_lft forever + + 42sh$ ./mymoulette ./newrootfs/ /usr/bin/ip address show veth0r + 2: veth0r@if82: mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default + link/ether 42:a2:a0:89:55:ef brd ff:ff:ff:ff:ff:ff + inet 10.10.10.42/24 brd 10.10.10.255 scope global veth3e06cad + valid_lft forever preferred_lft forever + + 42sh$ ping -c 1 10.10.10.42 + PING 10.10.10.42 (10.10.10.42) 56(84) bytes of data. + 64 bytes from 10.10.10.42: icmp_seq=1 ttl=56 time=3.90 ms + + --- 10.10.10.42 ping statistics --- + 1 packets transmitted, 1 received, 0% packet loss, time 1003ms + rtt min/avg/max/mdev = 3.789/3.847/3.906/0.085 ms +``` +
+ +
+``` + 42sh$ ./mymoulette ./newrootfs/ /usr/bin/curl http://www.linuxcontainers.org/ | md5sum + c7d68d1cb4737125a84cd69f55add202 +``` +
+ + +## Capabilities limitées + +
+``` + 42sh$ ./mymoulette ./newrootfs/ /bin/ping 9.9.9.9 + ping: icmp open socket: Permission denied +``` +
diff --git a/subject/2/subject.md b/subject/2/subject.md index 1366af1..4a52428 100644 --- a/subject/2/subject.md +++ b/subject/2/subject.md @@ -1,14 +1,14 @@ --- -title: Virtualisation légère -- Projet n^o^ 2 +title: Virtualisation légère -- Projet author: Pierre-Olivier *nemunaire* Mercier institute: EPITA -date: EPITA -- SRS 2018 +date: EPITA -- SRS 2019 ... Le laboratoire des assistants a besoin de votre expertise afin de renforcer la sécurité et la réactivité de son système de correction automatisé. -Votre projet consistera à réaliser la partie d'isolation de la moulinette des +Votre mission consistera à réaliser la partie d'isolation de la moulinette des ACUs : dans un premier temps vous ferez en sorte de restreindre un groupe de processus pour qu'il ne puisse pas faire de déni de service sur notre machine ; puis dans une seconde partie, vous vous assurerez de l'isolation de chaque @@ -17,7 +17,7 @@ puis dans une seconde partie, vous vous assurerez de l'isolation de chaque \vspace{1em} Il n'y a pas de restriction sur le langage utilisé, vous pouvez tout aussi bien -utiliser du C, du C++, du Python, du shell, etc. +utiliser du C, du C++, du Python, etc. L'usage de bibliothèques **non relatives** au projet est autorisé : le but de ce sujet est d'évaluer votre compréhension et votre utilisation de la @@ -28,6 +28,11 @@ plomberie, n'hésitez pas à l'utiliser ! \vspace{1em} Ce projet est à rendre à au plus tard le dimanche -26 novembre 2017 à 23 h 42. +25 novembre 2018 à 23 h 42. \tableofcontents + +\newpage + +Paliers +=======