virli/subject/2/project-part1.md
2018-11-07 12:24:46 +01:00

4.1 KiB

Palier 1 : Restreindre l'environnement (2 points)

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 cgroups-v2) dont vous allez avoir besoin pour limiter l'utilisation de ressources.

Puis, mettez en place ces limites :

  • pas plus d'1 GB de mémoire utilisée ;
  • 1 seul CPU au maximum ;
  • 100 PIDs ;
  • ...

En bonus, vous pouvez gérer les cas où le noyau sur lequel s'exécute votre moulinette ne possède pas tous ces CGroups, au lieu de planter, ne rien faire n'est pas forcément une mauvaise solution.

Palier 2 : Réduire les capabilities (2 points)

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 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
  c7d68d1cb4737125a84cd69f55add202

  bash# ping 9.9.9.9
  ping: icmp open socket: Permission denied
</div>

Astuces : `prctl(2)`, `capabilities(7)`, `capget(2)`, `capset(2)`, ...

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)  {.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  {.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
strict minimum. Recréez un environnement minimaliste, comme on a pu en voir
dans la partie sur les *chroot*.

**Ne mettez pas cet environnement dans votre tarball de rendu, il vous
  sera seulement utile pour faire des tests.**


## 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 !

<div lang="en-US">
```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 : 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) ;
  • ...

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)

Pour moulinéter plusieurs étudiants en parallèle, vous allez avoir besoin de plusieurs environnements identiques. Plutôt que de recopier cet environnement, de le nettoyer, de le recréer, pour chaque étudiant, ajoutez à votre moulinette un support pour LVM : utilisez des snapshots pour figer votre environnement et le dupliquer facilement pour chaque étudiant.

L'usage est laissé à votre discrétion : vous pouvez ajouter un/des paramètres à 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.