diff --git a/slides/3-linux internals.odp b/slides/3-linux internals.odp index a4baef9..757ea39 100644 Binary files a/slides/3-linux internals.odp and b/slides/3-linux internals.odp differ diff --git a/tutorial/3/Makefile b/tutorial/3/Makefile index a085943..fa47449 100644 --- a/tutorial/3/Makefile +++ b/tutorial/3/Makefile @@ -1,6 +1,11 @@ include ../pandoc-opts.mk -SOURCES = tutorial.md installation.md chroot.md pseudofs.md capabilities.md cgroups.md oom.md seccomp.md project-intro.md project-body.md project-rendu.md +SOURCES = tutorial.md \ + intro.md installation.md pseudofs.md capabilities.md cgroups.md cgroups-influx.md \ + oom.md \ + seccomp.md \ + chroot-intro.md chroot.md chroot-ex-escape.md \ + project-rendu.md all: tutorial.pdf diff --git a/tutorial/3/capabilities.md b/tutorial/3/capabilities.md index 79172b5..1f30227 100644 --- a/tutorial/3/capabilities.md +++ b/tutorial/3/capabilities.md @@ -1,16 +1,14 @@ \newpage Les *capabilities* -================== - -## Présentation +------------------ Historiquement, dans la tradition UNIX, on distinguait deux catégories de -processus : +processus : -* les processus *privilégiés* : dont l'identifiant numérique de son utilisateur - est 0 ; -* les processus *non-privilégiés* : dont l'identifiant numérique de son +* les processus *privilégiés* : dont l'identifiant numérique de son utilisateur + est 0 ; +* les processus *non-privilégiés* : dont l'identifiant numérique de son utilisateur n'est pas 0. Lors des différents tests de permission fait par le noyau, les processus @@ -21,24 +19,25 @@ Depuis Linux 2.2 (en 1998), les processus privilégiés peuvent activer ou désactiver des *capabilities*, chacune donnant accès à un groupe d'actions privilégiées au sein du noyau. -On trouve par exemple : +On trouve par exemple : -* `CAP_CHOWN` : permet de modifier le propriétaire d'un fichier de manière - arbitraire ; -* `CAP_KILL` : permet de tuer n'importe quel processus ; -* `CAP_SYS_BOOT` : permet d'arrêter ou de redémarrer la machine ; -* `CAP_SYS_MODULE` : permet de charger et décharger des modules ; -* et beaucoup d'autres, il y en a environ 39 en tout (ça dépend de la - version du noyau) ! +* `CAP_CHOWN` : permet de modifier le propriétaire d'un fichier de manière + arbitraire ; +* `CAP_KILL` : permet de tuer n'importe quel processus ; +* `CAP_SYS_BOOT` : permet d'arrêter ou de redémarrer la machine ; +* `CAP_SYS_MODULE` : permet de charger et décharger des modules ; +* et beaucoup d'autres, il y en a environ 41 en tout (ça dépend de la + version du noyau) ! ### `ping` Pour émettre un ping, il est nécessaire d'envoyer des paquets ICMP. À la -différence des datagrammes UDP ou des segments TCP, il n'existe pas d'interface -exposée par le noyau aux utilisateurs pour envoyer des paquets ICMP. Pour le -faire, il est nécessaire de pouvoir écrire directement sur l'interface ; ça, -seul le super-utilisateur peut le faire. +différence des datagrammes UDP ou des segments TCP, il n'est pas forcément +simple d'envoyer des paquets ICMP lorsque l'on est simple utilisateur, car +l'usage du protocole ICMP dans une socket est restreint : il faut soit être +super-utilisateur, soit que le noyau ait été configuré pour autoriser certains +utilisateurs à envoyer des `ECHO_REQUEST`. Pour permettre à tous les utilisateurs de pouvoir envoyer des ping, le programme est donc généralement *Setuid root*. Cela permet à n'importe quel @@ -48,35 +47,88 @@ du programme. Les problèmes surviennent lorsque l'on découvre des vulnérabilités dans les programmes *Setuid root*. En effet, s'il devient possible pour un utilisateur d'exécuter du code arbitraire, ce code sera exécuté avec les privilèges de -l'utilisateur *root* ! Dans le cas de `ping`, on se retrouverait alors à +l'utilisateur *root* ! Dans le cas de `ping`, on se retrouverait alors à pouvoir lire l'intégralité de la mémoire, alors que l'on avait juste besoin d'écrire sur une interface réseau. -C'est donc à ce moment que les *capabilities* entrent en jeu : un processus (ou +C'est donc à ce moment que les *capabilities* entrent en jeu : un processus (ou même un thread) privilégié peut décider, généralement à son lancement, de réduire ses *capabilities*, pour ne garder que celles dont il a réellement besoin. Ainsi, `ping` pourrait se contenter de `CAP_NET_RAW`. +::::: {.warning} +Bien que ce paramètre existe [depuis +2011](https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=c319b4d76b9e583a5d88d6bf190e079c4e43213d), +ce n'est que [depuis 2020](https://github.com/systemd/systemd/pull/13141) que les distributions comme Fedora et Ubuntu +se mettent à fournir par défaut une configuration qui permette de se passer de +*capabilities* pour lancer `ping`.\ -## Les attributs de fichier étendus +Si vous vous rendez compte que votre binaire `ping` est dans ce cas, testez +depuis un conteneur, par exemple : -Une grosse majorité des systèmes de fichiers (ext[234], XFS, btrfs, ...) +
+``` + 42sh$ docker run -it --rm alpine + + (ctnr)# apk add --no-cache acl iputils + (1/4) Installing libacl (2.2.53-r0) + (2/4) Installing acl (2.2.53-r0) + (3/4) Installing libcap (2.50-r0) + (4/4) Installing iputils (20210202-r0) + + (ctnr)# su -s/bin/ash daemon + + (ctnr)$ _ +``` +
+ +Dans le conteneur le binaire `ping` est *setuid root*, vous pouvez faire des +tests en retirant le *setuid* : + +
+``` + (ctnr)# chmod u-s /bin/ping + + (ctnr)$ ping epita.fr + ping: socket: Operation not permitted +``` +
+ +Puis en ajoutant la *capability* : + +
+``` + (ctnr)# setcap cap_net_raw+p /bin/ping + + (ctnr)$ ping epita.fr + PING epita.fr (172.67.156.141) 56(84) bytes of data. +``` +
+ +Vous vous retrouverez dans le scénario attendu, tout en pouvant agir sur le +binaire `ping` sans avoir peur de casser votre distribution. +::::: + + +### Les attributs de fichier étendus + +Une grosse majorité des systèmes de fichiers (ext[234], XFS, btrfs, ...) permet d'enregistrer, pour chaque fichier, des attributs (dits attributs *étendus*, par opposition aux attributs *réguliers* qui sont réservés à l'usage du système de fichiers). -Sous Linux, les attributs sont regroupés dans des espaces de noms : +Sous Linux, les attributs sont regroupés dans des espaces de noms : -* *security* : espace utilisé par les modules de sécurité du noyau, tel que - SELinux, ... ; -* *system* : espace utilisé par le noyau pour stocker des objets système, tels - que les ACL POSIX ; +* *security* : espace utilisé par les modules de sécurité du noyau, tel que + SELinux, ... ; +* *system* : espace utilisé par le noyau pour stocker des objets système, tels + que les ACL POSIX ; * *trusted*: espace dont la lecture et l'écriture est limité au - super-utilisateur ; -* *user* : modifiable sans restriction, à partir du moment où l'on est le + super-utilisateur ; +* *user* : modifiable sans restriction, à partir du moment où l'on est le propriétaire du fichier. -Par exemple, on peut définir un attribut sur un fichier comme cela : +Par exemple, on peut définir un attribut sur un fichier comme cela :
```bash @@ -88,14 +140,16 @@ user.foo="bar" ```
-Encore plus fort, vous pouvez utiliser les ACL POSIX : +En tant que simple utilisateur, vous ne pouvez pas modifier des attributs en +dehors de l'espace *user*. Par contre, en *root*, vous pouvez définir et +changer les ACL POSIX :
```bash 42sh$ sudo chown root:root toto && sudo chmod o-r toto 42sh$ cat toto cat: toto: Permission denied -42sh$ sudo setfattr -m u:$USER:r toto +42sh$ sudo setfacl -m u:$USER:r toto 42sh$ cat toto Hello World! ``` @@ -104,7 +158,7 @@ Hello World! Bien que les droits UNIX traditionnels ne vous donnent pas accès au fichier, les ACL POSIX vous autorisent à le lire. -Vous pouvez voir ces attributs avec la commande : +Vous pouvez voir ces attributs bruts avec la commande :
```bash @@ -114,17 +168,19 @@ system.posix_acl_access=0sgAAEAD/////AgAEOgDAEAA/////xAABAD////8= ```
+Il s'agit d'une représentation d'une structure du noyau, pas forcément très +lisible en l'état. On utilisera `getfacl` pour la version lisible. -### `ping` + +#### `ping`\ De la même manière que l'on peut définir de façon plus fine les droits d'accès par utilisateur, un attribut de l'espace de nom *security* peut être défini pour accroître les *capabilities* d'un processus lorsqu'il est lancé par un -utilisateur non-privilégié. On peut alors voir le Setuid root comme -l'utilisation de cet attribut auquel on accroîtrait l'ensemble des -*capabilities*. +utilisateur non-privilégié. On peut voir le *setuid root* comme l'utilisation +de cet attribut, qui accroîtrait l'ensemble des *capabilities*. -Si votre distribution profite de ces attributs étendus, vous devriez obtenir : +Si votre distribution profite de ces attributs étendus, vous devriez obtenir :
```bash @@ -134,7 +190,8 @@ security.capability=0sAQAAAgAgAAAAAAAAAAAAAAAAAAA= ```
-Ou, dans sa version plus lisible : +Comme pour les ACL POSIX, une structure du noyau est enregistrée comme attribut +du fichier ; et on peut l'afficher dans sa version plus lisible :
```bash @@ -144,10 +201,10 @@ Ou, dans sa version plus lisible :
-## Exercice : visualisateur de capabilities d'un processus {-} +### Exercice : visualisateur de capabilities d'un processus {-} Écrivons maintenant un programme permettant de voir les *capabilities* -d'un processus : +d'un processus :
``` @@ -179,24 +236,27 @@ inheritable: 0x0 ```
-Astuces : `capget(2)`, X-macros, ... +Appelé sans argument, `view_caps` affichera les capabilities du processus +courant. + +Astuces : `capget(2)`, X-macros, ... -## Pour aller plus loin {-} +### Pour aller plus loin {-} -Je vous recommande la lecture des *man* suivants : +Je vous recommande la lecture des *man* suivants : -* `capabilities(7)` : énumérant tous les capabilities, leur utilisation, etc. ; -* `xattrs(7)` : à propos des attributs étendus. +* `capabilities(7)` : énumérant tous les capabilities, leur utilisation, etc. ; +* `xattrs(7)` : à propos des attributs étendus. -Et de ces quelques articles : +Et de ces quelques articles : -* [Secure Your Containers with this One Weird Trick](https://www.redhat.com/en/blog/secure-your-containers-one-weird-trick) +* [Linux Capabilities: Why They Exist and How They Work](https://blog.container-solutions.com/linux-capabilities-why-they-exist-and-how-they-work) * [Guidelines for extended attributes](https://www.freedesktop.org/wiki/CommonExtendedAttributes/) * [File-based capabilities](https://lwn.net/Articles/211883/) * [A bid to resurrect Linux capabilities](https://lwn.net/Articles/199004/) * [False Boundaries and Arbitrary Code Execution](https://forums.grsecurity.net/viewtopic.php?f=7&t=2522#p10271) -Pour revenir à Docker, par défaut, un certain nombre de *capabilities* sont -désactivées par défaut ; vous pouvez en ajouter et en retirer via les arguments -`--cap-add` et `--cap-drop` du `docker container run`. +Pour revenir à Docker, un certain nombre de *capabilities* sont désactivées par +défaut ; vous pouvez en ajouter et en retirer via les arguments `--cap-add` et +`--cap-drop` du `docker container run`. diff --git a/tutorial/3/cgroups-influx.md b/tutorial/3/cgroups-influx.md new file mode 100644 index 0000000..7ad614f --- /dev/null +++ b/tutorial/3/cgroups-influx.md @@ -0,0 +1,87 @@ +### Exercice (obligatoire pour les SRS -- optionnel pour les GISTRE) + +Poursuivons [notre script de monitoring](#script-monitoring) afin d'envoyer nos +résultats vers InfluxDB : nous l'appellerons `./telegraf.sh` + +#### Rappel d'InfluxDB\ + +Commençons par lancer le conteneur Docker d'InfluxDB (pour éviter de +l'installer sur notre machine) : + +
+```bash +docker container run --name mytsdb -d -p 8086:8086 influxdb:1.8 +``` +
+ +Il nous faut ensuite créer une base de données pour y stocker nos +métriques. Voici comment on s'était débrouillé précédemment pour interagir avec +InfluxDB : + +
+```bash +docker container exec -i mytsdb influx < + +Vérifiez que la base de données `metrics` a bien été créée. + + +#### Monitoring vers InfluxDB\ + +Maintenant, envoyons nos données vers la base + : + +
+```bash +curl -i -XPOST 'http://localhost:8086/write?db=metrics' --data-binary \ + "$my_cgroup_name memory.usage_in_bytes=$(cat .../my_cgroup_name/memory.usage_in_bytes)" +``` +
+ +Pour vérifier que les données ont bien été ajoutées, nous pouvons effectuer la +requête suivante dans notre client `influx` : + +
+```sql +SELECT * from "$my_cgroup_name"; +``` +
+ + +#### Monitorer davantage de données\ + +Liste non exhaustive de données à monitorer : + +* Nombre d'IOs effectué ; +* nombre d'octets lus/écrits sur les disques ; +* temps de calcul utilisé (`userspace`, `system`, tout confondu) ; +* ... + +Tous les cgroups existants dans le dernier noyau publié ont leur documentation +accessible ici : + +- v1 : +- v2 : + + +#### Permettre à l'utilisateur de monitorer des processus\ + +Maintenant, séparons notre script en deux parties afin qu'un utilisateur normal +(non-root) puisse utiliser la partie monitoring de notre script. + +Un premier script doit s'occuper de créer le(s) *cgroup*s et lui attribuer les +bons droits, tandis que le deuxième va effectuer le monitoring, sans privilèges +particuliers. + +##### Exemple {-} + +
+``` +42sh$ sudo ./telegraf_init.sh my_cgroup_name +42sh$ ./telegraf.sh my_cgroup_name memhog 500 +``` +
diff --git a/tutorial/3/cgroups.md b/tutorial/3/cgroups.md index 3e76a1c..fc396dd 100644 --- a/tutorial/3/cgroups.md +++ b/tutorial/3/cgroups.md @@ -1,50 +1,123 @@ \newpage -Utiliser les *cgroup*s -====================== +Les *cgroup*s +------------- Les *cgroup*s (pour *Control Group*s) permettent de collecter des statistiques -sur des groupes de processus (appelés tâches) et de leur attribuer des -propriétés. Par exemple, il est possible leur imposer des limites d'utilisation -de ressources ou d'altérer leur comportement. +sur des **groupes de processus** (voire même, des threads !) et de leur +attribuer des propriétés. Il est par exemple possible de leur imposer des +limites d'utilisation de ressources ou d'altérer leur comportement : quantité +de RAM, temps CPU, bande passante, ... +Apparue dès [Linux +2.6.24](https://kernelnewbies.org/Linux_2_6_24#Task_Control_Groups) +(en 2008 !), les *cgroup*s sont répartis en différents sous-systèmes +(*subsystem*), chacun étant responsable d'un type de ressources +spécifique : -## Premiers tests +- [`blkio` (`io` dans la v2) + :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/blkio-controller.html) + limites et statistiques de bande passante sur les disques ; +- `cpu` : cycles CPU minimum garantis ; +- [`cpuacct` (inclus dans `cpu` dans la v2) + :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/cpuacct.html) + statistiques du temps CPU utilisé ; +- [`cpuset` + :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/cpusets.html) + associe des tâches à un/des CPU particuliers (par exemple pour dédier un cœur + du CPU à un programme, qui ne pourra alors utiliser que ce CPU et pas les + autres) ; +- [`devices` + :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/devices.html) + règles de contrôle de création (`mknod`) et d'accès aux périphériques ; +- [`freezer` + :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/freezer-subsystem.html) + pour suspendre et reprendre l'exécution d'un groupe de tâches ; +- [`hugetlb` :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/hugetlb.html) statistiques et limitation de l'usage de la fonctionnalité `HugeTLB` (permettant d'obtenir des pages mémoires plus grande que 4 kB) ; +- [`memory` :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/memory.html) statistiques et limitation d'usage de la mémoire vive et de la *swap* ; +- [`net_cls` (v1 seulement) :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/net_cls.html) applique un `classid` à tous les paquets émis par les tâches du *cgroup*, pour filtrage par le pare-feu en sortie ; +- [`net_prio` (v1 seulement) :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/net_prio.html) surcharge la valeur de l'option de priorité `SO_PRIORITY`, ordonant la file d'attente des paquets sortants ; +- [`pids` :](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/pids.html) statistiques et limitation du nombre de processus ; +- ... Nous allons commencer par faire quelques tests avec le *cgroup* *freezer*, qui -permet d'interrompre l'exécution d'un groupe de processus et de la reprendre. +permet d'interrompre l'exécution d'un groupe de processus, puis de la reprendre +lorsqu'on le décide. -### Montage du *cgroup* +### Montage du *freezer* -En fonction de la configuration de votre système, il est possible que les -*cgroup*s ne soient pas montés au démarrage dans `/sys/fs/cgroup/`. Si vous n'avez -pas de dossier `freezer` ou si celui-ci est vide, montez-le en suivant la -procédure suivante : +En fonction de la configuration de votre système, vous allez vous trouver dans +l'une de ces trois situations : -
-```bash -mkdir /sys/fs/cgroup/freezer/ -mount -t cgroup -o freezer none /sys/fs/cgroup/freezer/ -``` -
+- Votre dossier `/sys/fs/cgroup` contient à la fois des fichiers `cgroup.*` et + éventuellement des dossiers : vous avez une distribution moderne qui utilise + la nouvelle version des `cgroup`s. -Cette dernière commande monte l'arborescence de groupes relative à ce *cgroup* -*freezer*. Tous les dossiers contenus dans cette racine sont donc des -sous-groupes. +- Votre dossier `/sys/fs/cgroup` contient d'autres dossiers au nom des + sous-systèmes que l'on a listé ci-dessus : il s'agit des `cgroup`s v1. + +- Votre dossier `/sys/fs/cgroup` est vide ou inexistant, vous pouvez choisir + d'utiliser la version de votre choix : + + Pour utiliser la v1 : + +
+ ```bash + mkdir /sys/fs/cgroup/freezer/ + mount -t cgroup -o freezer none /sys/fs/cgroup/freezer/ + ``` +
+ + + Pour utiliser la v2 : + +
+ ```bash + mkdir /sys/fs/cgroup/ + mount -t cgroup2 none /sys/fs/cgroup/ + ``` +
+ +::::: {.question} +Avant d'aller plus loin, notez que les exemples seront donnés pour les deux +versions des `cgroup`s à chaque fois. + +La principale différence entre les deux est la fusion des différents +sous-systèmes au sein d'une même arborescence. Dans la première version, chaque +sous-système disposait de sa propre arborescence et il fallait créer les +groupes et associer les tâches pour chaque sous-système. Avec la seconde +version, une seule création est nécessaire, quelque soit le nombre de +sous-systèmes que l'on souhaite utiliser. +::::: ### Création d'un nouveau groupe -La première étape dans l'utilisation d'un *cgroup* est de créer un groupe. +Les *cgroup*s sont organisé autour d'une arborescence de groupe, où chaque +groupe est représenté par un dossier. Il peut bien évidemment y avoir des +sous-groupes, en créant des dossiers dans les dossiers existants, etc.\ + +La première étape dans l'utilisation d'un *cgroup* est donc de créer un groupe. Pour ce faire, il suffit de créer un nouveau dossier dans un groupe existant, -par exemple la racine : +par exemple la racine. + +On commence par se rendre à la racine :
```bash -mkdir /sys/fs/cgroup/freezer/virli/ -ls /sys/fs/cgroup/freezer/virli/ +cd /sys/fs/cgroup/freezer/ # v1 +cd /sys/fs/cgroup/ # v2 +``` +
+ +Puis on crée notre groupe : + +
+```bash +mkdir virli +ls virli/ ```
@@ -53,19 +126,50 @@ Nous avons maintenant un nouveau groupe de processus `virli` dans le *cgroup* propriétés de son (ses) père(s). +### Sélection de contrôleur (v2 seulement) + +Du fait de l'unification de tous les sous-systèmes, si vous utilisez la seconde +version, vous allez devoir activer le ou les contrôleurs dont vous avez besoin +(tandis que dans la première version, on se rendait dans l'arborescence du +sous-système que l'on voulait). + +Pour activer le contrôleur *memory* dans notre groupe `virli`, nous utilisons +la commande suivante : + +
+```bash +echo "+memory" > virli/cgroup.subtree_control +``` +
+ +::::: {.warning} +Si vous obtenez l'erreur `No such file or directory`, c'est sans doute que vous +avez les `cgroup`s v1 activé quelque part. Vous devriez plutôt utiliser la +première version, le fait qu'elle soit active empêche l'utilisation de la v2 en +parallèle. +::::: + +On peut contrôler les contrôleurs actifs en consultant le fichier +`virli/cgroup.controllers`. + +Le contrôleur *freezer* est activé par défaut, il n'y a pas besoin de +l'activer. + + ### Rattachement de processus -Pour le moment, ce nouveau groupe ne contient aucune tâche. +Pour le moment, ce nouveau groupe ne contient aucun processus, comme le montre +le fichier `cgroup.procs` de notre groupe. Ce fichier contient la liste des +processus rattachés à notre *cgroup*. Ouvrons un nouveau terminal (c'est lui que l'on va geler), et récupérons son PID : `echo $$`. -La liste des processus rattachés à un *cgroup* se trouve dans le fichier `task` -du groupe. Pour ajouter une tâche à ce groupe, cela se passe de cette manière : +Pour ajouter une tâche à ce groupe, cela se passe de cette manière :
```bash -echo $PID > /sys/fs/cgroup/freezer/virli/tasks +echo $PID > /sys/fs/cgroup/{,freezer/}virli/cgroup.procs ```
@@ -75,7 +179,7 @@ En validant cette commande, nous avons déplacé le processus dans ce groupe, il n'est alors plus dans aucun autre groupe (pour ce *cgroup*, il ne bouge pas dans les autres *cgroup*s). -Malgré l'utilisation de la redirection `>` (et non `>>`), il s'agit belle et +Malgré l'utilisation de la redirection `>` (et non `>>`), il s'agit bel et bien d'un ajout au fichier et non d'un écrasement. Il faut garder en tête que le système de fichier est entièrement simulé et que certains comportements sont adaptés. @@ -84,15 +188,15 @@ adaptés. ### Consultation de l'état En affichant le contenu du dossier `virli`, nous pouvions constater que -celui-ci contenait déjà un certain nombre de fichiers. Certain d'entre-eux sont -en lecture seule et permettent de lire des statistiques instantanées sur le -groupe ; tandis que d'autres sont des propriétés que nous pouvons modifier. +celui-ci contenait déjà un certain nombre de fichiers. Certains d'entre-eux +sont en lecture seule et permettent de lire des statistiques instantanées sur +le groupe ; tandis que d'autres sont des propriétés que nous pouvons modifier. Nous pouvons consulter l'état de gel du groupe en affichant le contenu du fichier\ -`/sys/fs/cgroup/freezer/virli/freezer.state`. +`/sys/fs/cgroup/freezer/virli/freezer.state` ou `/sys/fs/cgroup/virli/cgroup.freeze`. -Pour plus d'information sur les différents fichiers présents dans ce *cgroup*, +Pour plus d'informations sur les différents fichiers présents dans ce *cgroup*, consultez [la documentation associée](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/freezer-subsystem.html). @@ -113,7 +217,8 @@ calcul à notre shell et ses fils :
```bash -echo FROZEN > /sys/fs/cgroup/freezer/virli/freezer.state +echo FROZEN > /sys/fs/cgroup/freezer/virli/freezer.state # v1 +echo 1 > /sys/fs/cgroup/virli/cgroup.freeze # v2 ```
@@ -122,57 +227,30 @@ l'exécution :
```bash -echo THAWED > /sys/fs/cgroup/freezer/virli/freezer.state +echo THAWED > /sys/fs/cgroup/freezer/virli/freezer.state # v1 +echo 0 > /sys/fs/cgroup/virli/cgroup.freeze # v2 ```
-## Exercice : script de monitoring +### Exercice : script de monitoring {- #script-monitoring} À nous maintenant de concevoir un script qui va enregistrer vers une base de -données des statistiques issues des *cgroup*s. - - -### Rappel d'InfluxDB - -Commençons par lancer le conteneur Docker d'InfluxDB (pour éviter de -l'installer sur notre machine) : - -
-```bash -docker container run --name mytsdb -d -p 8086:8086 influxdb -``` -
- -Il nous faut ensuite créer une base de données pour y stocker nos -métriques. Voici comment on s'était débrouillé dans un précédent TP pour -interagir avec InfluxDB : - -
-```bash -docker container exec -i mytsdb influx < - -Vérifiez que la base de données `metrics` a bien été créée. - - -### Monitoring instantané vers la console +données des statistiques issues des *cgroup*s, tel `telegraf`. Dans un premier temps, commençons par afficher dans la console, la quantité de mémoire utilisée par le groupe monitoré. +::::: {.code} Vous pouvez utiliser un programme comme [`memhog`](https://virli.nemunai.re/memhog.c) pour remplir rapidement votre mémoire. +:::::
``` 42sh# mkdir /sys/fs/cgroup... -42sh$ echo $$ | sudo tee /sys/fs/cgroup.../tasks +42sh$ echo $$ | sudo tee /sys/fs/cgroup.../cgroup.procs 42sh# ./monitor group_name memhog 500 ~~~ 13595 ~~~ Current memory usage: 75194368/550502400 (13%) ~~~ 13595 ~~~ Current memory usage: 150290432/550502400 (27%) @@ -185,79 +263,26 @@ mémoire. ```
+::::: {.warning} Si vous n'avez pas le *cgroup* *memory*, il est possible qu'il ne soit pas activé par défaut par votre système. Si vous êtes dans ce cas, essayez d'ajouter `cgroup_enable=memory` à la ligne de commande de votre noyau. +::::: -### Monitoring vers InfluxDB +### Fixer des limites {#Fixer-des-limites} -Maintenant, envoyons nos données vers la base - : - -
-```bash -curl -i -XPOST 'http://localhost:8086/write?db=metrics' --data-binary \ - "$my_cgroup_name memory.usage_in_bytes=$(cat .../my_cgroup_name/memory.usage_in_bytes)" -``` -
- -Pour vérifier que les données ont bien été ajoutées, nous pouvons effectuer la -requête suivante dans notre client `influx` : - -
-```sql -SELECT * from "$my_cgroup_name"; -``` -
- - -### Monitorer davantage de données - -Liste non exhaustive de données à monitorer : - -* Nombre d'IOs effectué ; -* nombre d'octets lu/écrit sur les disques ; -* temps de calcul utilisé ; -* trafic réseau généré ; -* ... - -Tous les cgroups existants dans le dernier noyau publié ont leur documentation -accessible ici : - - - -### Permettre à l'utilisateur de monitorer des processus - -Maintenant, séparons notre script en deux parties afin qu'un utilisateur normal -(non-root) puisse utiliser la partie monitoring de notre script. - -Un premier script doit s'occuper de créer le(s) *cgroup*s et lui attribuer les -bons droits, tandis que le deuxième va effectuer le monitoring, sans privilèges -particuliers. - -#### Exemple - -
-``` -42sh$ sudo ./monitor_init my_cgroup_name -42sh$ ./monitor my_cgroup_name memhog 500 -``` -
- - -## Fixer des limites - -Au delà de la simple consultation, les *cgroup*s peuvent servir à limiter la -quantité de ressources mise à disposition à un groupe de processus. +Au-delà de la simple consultation, les *cgroup*s peuvent servir à limiter la +quantité de ressources mises à disposition à un groupe de processus. Pour définir une limite, nous allons écrire la valeur dans le fichier correspondant à une valeur limite, comme par exemple -`memory.max_usage_in_bytes`, qui limite le nombre d'octets que notre groupe de -processus va pouvoir allouer au maximum : +`memory.max_usage_in_bytes`/`memory.max`, qui limite le nombre d'octets que +notre groupe de processus va pouvoir allouer au maximum :
``` +# cgroup v1 42sh$ cat /sys/fs/cgroup/memory/virli/memory.max_usage_in_bytes 0 # 0 = Aucune limite @@ -268,21 +293,26 @@ processus va pouvoir allouer au maximum : ```
-Chaque *cgroup*s défini de nombreux indicateurs et possède de nombreux +
+``` +# cgroup v2 +42sh$ cat /sys/fs/cgroup/virli/memory.max +max +# max = Aucune limite +42sh$ echo 4M > /sys/fs/cgroup/virli/memory.max +# Maintenant, la limite est à 4MB, vérifions... +42sh$ cat /sys/fs/cgroup/virli/memory.max +4194304 +``` +
+ +Chaque *cgroup*s définit de nombreux indicateurs et possède de nombreux limiteurs, n'hésitez pas à consulter la documentation associée à chaque *cgroup*. -## Pour aller plus loin {-} +### Pour aller plus loin {-} Pour tout connaître en détails, [la série d'articles de Neil Brown sur les -Control groups](https://lwn.net/Articles/604609/) est excellente ! - -Depuis les noyaux 4.5, il est possible d'utiliser la nouvelle version du -pseudo système de fichiers des *CGroup*s. Le principal changement vient du -regroupement au sein d'une seule hiérarchie des différents *CGroup*s que l'on -avait dans la v1. Davantage d'informations sont disponibles : - -* [Understanding the new control groups API](https://lwn.net/Articles/679786/) - ; -* [Kernel Document about Control Group v2](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html). +Control groups](https://lwn.net/Articles/604609/) est excellente ! Plus [cet +article sur la version 2](https://lwn.net/Articles/679786/). diff --git a/tutorial/3/chroot-ex-escape.md b/tutorial/3/chroot-ex-escape.md new file mode 100644 index 0000000..df9f332 --- /dev/null +++ b/tutorial/3/chroot-ex-escape.md @@ -0,0 +1,28 @@ +## Exercice (SRS seulement) {-} + +Écrivons maintenant un programme dont le seul but est de s'échapper du `chroot` : + +
+```bash +make escape +echo bar > ../foo +chroot . +``` +
+ +Dans le nouvel environnement, vous ne devriez pas pouvoir faire : + +
+```bash +cat ../foo +``` +
+ +Mais une fois votre programme `escape` exécuté, vous devriez pouvoir ! + +
+``` +(chroot) 42sh# ./escape + bash# cat /path/to/foo +``` +
diff --git a/tutorial/3/chroot-intro.md b/tutorial/3/chroot-intro.md new file mode 100644 index 0000000..b81822e --- /dev/null +++ b/tutorial/3/chroot-intro.md @@ -0,0 +1,12 @@ +\newpage + +En route vers la contenerisation +================================ + +Nous avons vu un certain nombre de fonctionnalités offertes par le noyau Linux +pour limiter ou autoriser ou contraindre différents usages des ressources de +notre machine. + +Il est temps maintenant de commencer à parler d'isolation, mais ... cela fait +déjà beaucoup à digérer pour aujourd'hui, alors on va se contenter de parler +d'un mécanisme que vous connaissez sans doute déjà. diff --git a/tutorial/3/chroot.md b/tutorial/3/chroot.md index 2458f94..a00a3a8 100644 --- a/tutorial/3/chroot.md +++ b/tutorial/3/chroot.md @@ -1,18 +1,15 @@ -\newpage - -L'isolation ... du pauvre -========================= +L'isolation ... à 1 € ? +----------------------- Depuis les premières versions d'Unix, il est possible de changer le répertoire -vu comme étant la racine du système de fichiers. En anglais : *change root*: -`chroot`. Le processus effectuant cette action ainsi que tous ses fils, verront -donc une racine différente du reste du système. +vu comme étant la racine du système de fichiers. En anglais : *change root*: +`chroot`. Le processus effectuant cette action ainsi que tous ses fils verront +donc une racine différente du reste du système.\ -## Mise en place de l'environnement - Pour se créer un environnement afin de changer notre racine, il va falloir -commencer par créer le dossier de notre nouvelle racine : +commencer par créer le dossier de notre nouvelle racine, peu importe où dans +l'arborescence :
```bash @@ -20,13 +17,21 @@ mkdir newroot ```
+ +Nous allons ensuite remplir ce dossier afin qu'il soit vraiment utilisable +comme une racine : rien n'est strictement obligatoire, on s'assure simplement +d'avoir de quoi bidouiller : un shell sera amplement suffisant pour commencer. + ### `busybox` -Queques mots, pour commencer, à propos du projet Busybox : c'est un programme -*linké* statiquement, c'est-à-dire qu'il ne va pas chercher ni charger de -bibliothèque dynamique à son lancement. Il se suffit donc à lui-même dans un -*chroot*, car il n'a pas de dépendances. Nous pouvons donc tester notre -première isolation\ : +Queques mots, pour commencer, à propos du projet Busybox : c'est un programme +couteau-suisse qui implémente tous les binaires vitaux pour avoir un système +fonctionnel et utilisable : `ls`, `sh`, `cat`, mais aussi `init`, `mdev` (un +`udev`-like, cela permet de découvrir les périphériques attachés afin de les +exposer dans `/dev` notamment). C'est un programme *linké* statiquement, +c'est-à-dire qu'il ne va pas chercher ni charger de bibliothèque dynamique à +son lancement. Il se suffit donc à lui-même dans un *chroot*, car il n'a pas de +dépendances. Nous pouvons donc tester notre première isolation :
```bash @@ -35,8 +40,11 @@ chroot newroot /busybox ash ```
-Jusque là ... ça fonctionne, rien de surprenant ! Mais qu'en est-il pour -`bash` : +Nous voici donc maintenant dans un nouveau shell (il s'agit d'`ash`, le shell +de `busybox`). + +Jusque là ... ça fonctionne, rien de surprenant ! Mais qu'en est-il pour +`bash` :
```bash @@ -46,10 +54,10 @@ chroot: failed to run command ‘bash’: No such file or directory ```
-De quel fichier est-il question ici ? +De quel fichier est-il question ici ? -### `debootstrap` +### `debootstrap`, `pacstrap` `debootstrap` est le programme utilisé par l'installeur des distributions Debian et ses dérivées. Il permet d'installer dans un dossier (en général, ce @@ -58,54 +66,76 @@ l'utilisateur lors de l'installation) le système de base.
```bash -debootstrap buster newroot/ http://httpredir.debian.org/debian/ +debootstrap bullseye newroot/ http://httpredir.debian.org/debian/ ```
-`pacstrap` est le programme équivalent pour Archlinux. - - -### *stage3* - -Les distributions *à l'ancienne* proposent encore de télécharger leur système -de base sous forme de tarball\ : +`pacstrap` est le programme équivalent pour Arch Linux. Alors que `debootstrap` +peut s'utiliser depuis n'importe quel environnement ou distribution, +`pacstrap` nécessite d'avoir installé et configuré `pacman` (le gestionnaire de +paquets d'Arch Linux), ce qui est le cas si vous êtes sous Arch Linux ou ses +dérivées.
```bash -wget http://gentoo.mirrors.ovh.net/gentoo-distfiles/releases/amd64/autobuilds/current-stage3-amd64/stage3-amd64-20201104T214503Z.tar.xz +pacstrap newroot/ +``` +
+ +Dans les deux cas, nous nous retrouvons avec un dossier `newroot` contenant une +distribution complète minimale, dans laquelle nous pouvons entrer : + +
+```bash +chroot newroot/ bash +``` +
+ + +### Archives *stage3*, *miniroot* + +Les distributions *à l'ancienne* proposent de télécharger leur système de base +sous forme de tarball : + + +#### Gentoo\ + +
+```bash +wget http://gentoo.mirrors.ovh.net/gentoo-distfiles/releases/amd64/autobuilds/current-stage3-amd64/stage3-amd64-20210630T214504Z.tar.xz tar xpf stage3-amd64-*.tar.xz -C newroot/ ```
+::::: {.more} L'avantage de télécharger l'archive de Gentoo est que l'on a déjà `gcc` dans un -environnement qui tient dans 300 MB. +environnement qui tient dans 200 MB. +::::: - -## Exercice {-} - -Écrivons maintenant un programme dont le seul but est de s'échapper du `chroot` : +Comme pour les autres distributions vues précédemment, nous pouvons entrer dans +notre nouvelle racine comme ceci :
```bash -make escape -echo bar > ../foo -chroot . +chroot newroot/ bash ```
-Dans le nouvel environnement, vous ne devriez pas pouvoir faire : + +#### Alpine\
```bash -cat ../foo +wget https://dl-cdn.alpinelinux.org/alpine/v3.14/releases/x86_64/alpine-minirootfs-3.14.2-x86_64.tar.gz +tar xpf alpine-minirootfs-*.tar.xz -C newroot/ ```
-Mais une fois votre programme `escape` exécuté, vous devriez pouvoir ! +Alpine se contentant de Busybox pour son système de base, nous n'avons pas +`bash`, mais on peut tout de même lancer `ash` :
-``` -(chroot) 42sh# ./escape - bash# cat /path/to/foo +```bash +chroot newroot/ ash ```
diff --git a/tutorial/3/installation.md b/tutorial/3/installation.md index eda1cfb..ff971bc 100644 --- a/tutorial/3/installation.md +++ b/tutorial/3/installation.md @@ -1,13 +1,12 @@ -\newpage - Prérequis -========= +--------- -## Noyau Linux +### Noyau Linux -Ce TP requiert un noyau Linux, dans sa version 3.8 au minimum. Il doit de plus -être compilé avec les options suivantes (lorsqu'elles sont disponibles pour -votre version) : +Pour pouvoir suivre les exemples et faire les exercices qui suivent, vous aurez +besoin d'un noyau Linux récent (une version 5.x sera très bien). Il doit de +plus être compilé avec les options suivantes (lorsqu'elles sont disponibles +pour votre version) :
``` @@ -31,7 +30,7 @@ General setup --->
-### Vérification via `menuconfig` +#### Vérification via `menuconfig`\ L'arbre ci-dessous correspond aux options qui seront *built-in* (signalées par une `*`) ou installées en tant que module (signalées par un `M`). En effet, @@ -42,7 +41,7 @@ Pour parcourir l'arbre des options du noyau, il est nécessaire d'avoir les sources de celui-ci. Les dernières versions stables et encore maintenues sont disponibles sur la page d'accueil de . -Dans les sources, on affiche la liste des options avec la commande : +Dans les sources, on affiche la liste des options avec la commande :
```bash @@ -51,7 +50,7 @@ make menuconfig
-### Vérification via `/boot/config-xxx` +#### Vérification via `/boot/config-xxx`\ Les distributions basées sur Debian ont pour habitude de placer le fichier de configuration ayant servi à compiler le noyau et ses modules dans le dossier @@ -60,7 +59,7 @@ fichiers initial (`initramfs-xxx`) et des symboles de débogage `System.map-xxx`. Ce fichier répertorie toutes les options qui ont été activées. Par rapport à -l'arbre présenté ci-dessus, vous devriez trouver : +l'arbre présenté ci-dessus, vous devriez trouver :
``` @@ -81,7 +80,7 @@ CONFIG_CGROUP_NET_CLASSID=y
-### Vérification via `/proc/config.gz` +#### Vérification via `/proc/config.gz`\ Dans la plupart des autres distributions, la configuration est accessible à travers le fichier `/proc/config.gz`. Comme vous ne pouvez pas écrire dans @@ -91,12 +90,12 @@ Vous devez retrouver les mêmes options que celles de la section précédente. -## Présence des en-têtes +### Présence des en-têtes Si vous utilisez un noyau standard fourni par votre distribution, les options requises seront a priori déjà sélectionnées et vous n'aurez donc pas à compiler -votre propre noyau. Néanmoins, durant ce TP, nous allons nous interfacer avec -le noyau, il est donc nécessaire d'avoir les en-têtes de votre noyau. +votre propre noyau. Néanmoins, nous allons nous interfacer avec le noyau, il +est donc nécessaire d'avoir les en-têtes de votre noyau. Sous Debian, vous pouvez les installer via le paquet au nom semblable à `linux-headers`. Le paquet porte le même nom sous Arch Linux et ses dérivés. diff --git a/tutorial/3/intro.md b/tutorial/3/intro.md new file mode 100644 index 0000000..cfafb77 --- /dev/null +++ b/tutorial/3/intro.md @@ -0,0 +1,12 @@ +\newpage + +Statistiques et contrôle des processus +====================================== + +Maintenant que nous avons pu voir en détail comment utiliser Docker, nous +allons tâcher d'apprendre comment il fonctionne en nous penchant sur un certain +nombre de fonctionnalités de Linux. + +Dans un premier temps, nous allons aborder la manière dont le noyau Linux +permet de contrôler les processus : que ce soit en collectant des informations +sur eux ou en imposant certaines restrictions. diff --git a/tutorial/3/oom.md b/tutorial/3/oom.md index b37da8b..30ffe54 100644 --- a/tutorial/3/oom.md +++ b/tutorial/3/oom.md @@ -15,7 +15,7 @@ mémoire est donc utilisée de manière plus efficace. . Mais évidemment, cela peut donner lieu à des situations où le noyau n'est plus -en mesure de trouver de bloc physiquement disponible, alors qu'ils avaient +en mesure de trouver de blocs physiquement disponibles, alors qu'ils avaient effectivement été alloués au processus. Pour autant, ce n'est pas une raison pour tuer ce processus, car il est peut-être vital pour le système (peut-être est-ce `init` qui est en train de gérer le lancement d'un nouveau daemon). On @@ -31,18 +31,19 @@ l'*Out-Of-Memory killer*. Selon un algorithme dont on raconte qu'il ne serait pas basé entièrement sur l'aléatoire[^oom-algo], un processus est tiré au sort (plus un processus occupe de mémoire et plus il a de chance d'être tiré au sort) par l'OOM killer. Le -sort qui lui est réservé est tout simplement une mort brutale. Pour permettre +sort qui lui est réservé est tout simplement une mort brutale, pour permettre au système de disposer à nouveau de mémoire disponible. Si cela n'est pas suffisant, un ou plusieurs autres processus peuvent être tués à tour de rôle, jusqu'à ce que le système retrouve sa sérénité. [^oom-algo]: -## Esquiver l'OOM killer -Au sein d'un *cgroup* *memory*, le fichier `memory.oom_control` peut être -utilisé afin de recevoir une notification du noyau avant que l'OOM-killer -ne s'attaque à un processus de ce groupe. +## Esquiver l'OOM killer ? + +Au sein d'un *cgroup* *memory*, les fichiers `memory.oom_control` (v1) ou +`memory.events` (v2) peuvent être utilisé afin de recevoir une notification du +noyau avant que l'OOM-killer ne s'attaque à un processus de ce groupe. Grâce à cette notification, il est possible de figer le processus pour l'envoyer sur une autre machine. Et ainsi libérer la mémoire avant que l'OOM @@ -50,3 +51,11 @@ killer ne passe. Jetez un œil à [cet article parru sur LWN](https://lwn.net/Articles/590960/) à ce sujet. + + +## À vous de jouer {-} + +Continuons l'exercice précédent où nous avions [fixé les +limites](#Fixer-des-limites) de mémoire que pouvez réserver les processus de +notre groupe. Que se passe-t-il alors si `memhog` dépasse la quantité de +mémoire autorisée dans le `cgroup` ? diff --git a/tutorial/3/project-rendu.md b/tutorial/3/project-rendu.md index 36bbc39..175eab2 100644 --- a/tutorial/3/project-rendu.md +++ b/tutorial/3/project-rendu.md @@ -1,7 +1,25 @@ +\newpage + +Rendu +===== + +Est attendu d'ici le TP suivant : + +- le rendu des exercice de ce TP ; +- vos réponses à [l'évaluation du cours](https://virli.nemunai.re/quiz/14). + +Pour les GISTRE (et en bonus pour les SRS), [un +projet](https://virli.nemunai.re/project-2.pdf) est à rendre pour le 13 +novembre. Consultez les modalités de rendu sur le sujet directement. + + ## Modalité de rendu -Un service automatique s'occupe de réceptionner vos rendus, de faire les -vérifications nécessaires et de vous envoyer un accusé de réception (ou de +En tant que personnes sensibilisées à la sécurité des échanges électroniques, +vous devrez m'envoyer vos rendus signés avec votre clef PGP. + +Un service automatique s'occupe de réceptionner vos rendus, de faire des +vérifications élémentaires et de vous envoyer un accusé de réception (ou de rejet). Ce service écoute sur l'adresse , c'est donc à cette adresse @@ -9,8 +27,10 @@ et exclusivement à celle-ci que vous devez envoyer vos rendus. Tout rendu envoyé à une autre adresse et/ou non signé et/ou reçu après la correction ne sera pas pris en compte. -Par ailleurs, n'oubliez pas de répondre à -[l'évaluation du cours](https://virli.nemunai.re/quiz/6). +Afin d'orienter correctement votre rendu, ajoutez une balise `[TP3]` au sujet +de votre courriel. N'hésitez pas à indiquer dans le corps du message votre +ressenti et vos difficultés ou bien alors écrivez votre meilleure histoire +drôle si vous n'avez rien à dire. ## Tarball @@ -25,15 +45,13 @@ pour chaque exercice) :
``` login_x-TP3/ -login_x-TP3/escape.c +login_x-TP3/escape.c # SRS login_x-TP3/procinfo.sh login_x-TP3/suspend_schedule.sh login_x-TP3/view_caps.c login_x-TP3/monitor.sh -login_x-TP3/monitor_init.sh +login_x-TP3/telegraf.sh # SRS +login_x-TP3/telegraf_init.sh # SRS login_x-TP3/syscall_filter.c ```
- -Les premières étapes du projet ne sont pas à rendre et feront l'objet -d'un rendu à part. diff --git a/tutorial/3/pseudofs.md b/tutorial/3/pseudofs.md index c575a58..b235fb0 100644 --- a/tutorial/3/pseudofs.md +++ b/tutorial/3/pseudofs.md @@ -1,14 +1,14 @@ \newpage Pseudos systèmes de fichiers -============================ +---------------------------- -## Rappels sur les points de montage +### Rappels sur les points de montage Les systèmes Unix définissent le système de fichiers comme étant un arbre unique partant d'une racine[^FHS] et où l'on peut placer au sein de son arborescence des points de montage. Ainsi, l'utilisateur définit généralement deux points de -montage : +montage : [^FHS]: Consultez pour @@ -26,27 +26,27 @@ et les fichiers des utilisateurs sont sur la troisième partition du premier disque. -## Présentation des pseudos systèmes de fichiers +### Présentation des pseudos systèmes de fichiers -D'autres points de montage sont utilisés par le système : `/dev`, `/proc`, -`/tmp`, ... Ces points de montage vont, la plupart du temps, être montés par le +D'autres points de montage sont utilisés par le système : `/dev`, `/proc`, +`/tmp`, ... Ces points de montage vont, la plupart du temps, être montés par le programme d'initialisation en utilisant des systèmes de fichiers virtuels, mis à disposition par le noyau. Ces systèmes sont virtuels, car ils ne correspondent à aucune partition d'aucun -disque : l'arborescence est créée de toute pièce par le noyau pour trier les +disque : l'arborescence est créée de toute pièce par le noyau pour trier les informations mises à disposition, mais il n'est pas toujours possible d'y apporter des modifications. -Linux emploie de nombreux systèmes de fichiers virtuels : +Linux emploie de nombreux systèmes de fichiers virtuels : -- `/proc` : contient, principalement, la liste des processus (`top` et ses +- `/proc` : contient, principalement, la liste des processus (`top` et ses dérivés se contentent de lire les fichiers de ce point de montage) ; -- `/proc/sys` : contient la configuration du noyau ; -- `/sys` : contient des informations à propos du matériel (utilisées notamment +- `/proc/sys` : contient la configuration du noyau ; +- `/sys` : contient des informations à propos du matériel (utilisées notamment par `udev` pour peupler `/dev`) et des périphériques (taille des tampons, - clignottement des DELs, ...) ; -- `/sys/firmware/efi/efivars` : pour accéder et modifier les variables de + clignottement des DELs, ...) ; +- `/sys/firmware/efi/efivars` : pour accéder et modifier les variables de l'UEFI ; - ... @@ -57,9 +57,9 @@ exemple, pour modifier les paramètres du noyau, on passe par le fichier `/etc/sysctl.conf` et du programme `sysctl`. -### Consultation et modification +#### Consultation et modification\ -La consultation d'un élément se fait généralement à l'aide d'un simple `cat` : +La consultation d'un élément se fait généralement à l'aide d'un simple `cat` :
``` @@ -68,7 +68,7 @@ freeze mem ```
-La modification d'un élément se fait avec `echo`, comme ceci : +La modification d'un élément se fait avec `echo`, comme ceci :
```bash @@ -76,15 +76,15 @@ La modification d'un élément se fait avec `echo`, comme ceci : ```
-Vous devriez constater l'effet de cette commande sans plus attendre ! +Vous devriez constater l'effet de cette commande sans plus attendre ! -## Exercices +### Exercices -### `procinfo` +#### `procinfo`\ Explorons le pseudo système de fichiers `/proc` pour écrire un script qui va -afficher des informations sur un processus donné : +afficher des informations sur un processus donné :
``` @@ -125,17 +125,17 @@ uts:[4026531838]
-### `batinfo.sh`, `cpuinfo.sh` +#### `batinfo.sh`, `cpuinfo.sh`\ Explorons le pseudo système de fichiers `/sys` pour écrire un script -qui va, en fonction de ce que vous avez de disponible : +qui va, en fonction de ce que vous avez de disponible : -* nous afficher des statistiques sur notre batterie ; -* nous afficher des statistiques la fréquence de notre CPU. +* afficher des statistiques sur notre batterie ; +* afficher des statistiques la fréquence du CPU. -#### `batinfo.sh` +##### `batinfo.sh`\ -Voici un exemple d'utilisation : +Voici un exemple d'utilisation :
``` @@ -158,13 +158,13 @@ Remaining time: N/A ```
-Pour les détails sur l'organisation de ce dossier, regardez : +Pour les détails sur l'organisation de ce dossier, regardez : . -#### `cpuinfo.sh` +##### `cpuinfo.sh`\ -Voici un exemple d'utilisation : +Voici un exemple d'utilisation :
``` @@ -185,33 +185,33 @@ Thermal throttle count: 0 ```
-N'hésitez pas à rajouter toute sorte d'information intéressantes ! +N'hésitez pas à rajouter toute sorte d'information intéressantes ! -### `rev_kdb_leds.sh`, `suspend_schedule.sh` +#### `rev_kdb_leds.sh`, `suspend_schedule.sh`\ Maintenant que vous savez lire des informations dans `/sys`, tentons d'aller -modifier le comportement de notre système. Au choix, réaliser l'un des scripts -suivant, en fonction du matériel dont vous disposez : +modifier le comportement de notre système. Au choix, réalisez l'un des scripts +suivants, en fonction du matériel dont vous disposez : * inverser l'état des diodes de notre clavier ; * mettre en veille votre machine, en ayant programmé une heure de réveil. -#### `rev_kdb_leds.sh` +##### `rev_kdb_leds.sh`\ -Si vous avez : +Si vous avez : * numlock On, * capslock Off, * scrolllock Off ; -Après avoir exécuté le script, nous devrions avoir : +Après avoir exécuté le script, nous devrions avoir : * numlock Off, * capslock On, * scrolllock On. -Voici un exemple d'utilisation : +Voici un exemple d'utilisation :
``` @@ -222,7 +222,7 @@ Voici un exemple d'utilisation : `input20` correspond à l'identifiant de votre clavier, sous `/sys/class/input/`. -#### `suspend_schedule.sh` +##### `suspend_schedule.sh`\ Votre script prendra en argument l'heure à laquelle votre machine doit être réveillée, avant de la mettre effectivement en veille. @@ -232,7 +232,7 @@ système de fichiers `/sys`. Il n'est pas question de faire appel à un autre programme (vous pourriez cependant avoir besoin de `date(1)` pour faire les calculs horaires). -Voici un exemple d'utilisation : +Voici un exemple d'utilisation :
``` @@ -242,11 +242,15 @@ Voici un exemple d'utilisation :
Vous aurez besoin de définir une alarme au niveau de votre RTC, via le -fichier : `/sys/class/rtc/rtcX/wakealarm`. +fichier : `/sys/class/rtc/rtcX/wakealarm`. +::::: {.warning} Attention au fuseau horaire utilisé par votre RTC, si votre système principal est Windows, elle utilisera sans doute le fuseau horaire courant. Sinon, ce sera UTC. +::::: -Un article très complet sur le sujet est disponible ici : +::::: {.more} +Un article très complet sur le sujet est disponible ici : +::::: diff --git a/tutorial/3/seccomp.md b/tutorial/3/seccomp.md index b1ae0fe..dc56a0b 100644 --- a/tutorial/3/seccomp.md +++ b/tutorial/3/seccomp.md @@ -12,7 +12,7 @@ particulier peut être renvoyé au programme. Depuis la version 3.17 du noyau, l'appel système `seccomp(2)` permet de faire entrer le processus courant dans ce mode. En effet, c'est le processus lui-même qui déclare au noyau qu'il peut désormais se contenter d'une liste réduite -d'appel système ; à l'inverse des politiques de sécurité comme SELinux ou +d'appels système ; à l'inverse des politiques de sécurité comme SELinux ou AppArmor, qui encapsulent les programmes pour toute la durée de leur exécution. *Seccomp* est particulièrement utile lorsqu'un processus a terminé son @@ -61,7 +61,7 @@ exécutée en cas de faute. Notons que les processus fils issus (`fork(2)` ou `clone(2)`) d'un processus auquel est appliqué un filtre `seccomp`, héritent également de ce filtre. -La construction de ce filtre est faite de manière programatique, via +La construction de ce filtre est faite de manière programmatique, via des règles BPF (`Berkeley Packet Filter`). On passe ensuite ce filtre BPF en argument de l'appel système : diff --git a/tutorial/3/tutorial.md b/tutorial/3/tutorial.md index 9ec5d6e..b5ae4f3 100644 --- a/tutorial/3/tutorial.md +++ b/tutorial/3/tutorial.md @@ -12,7 +12,7 @@ abstract: | \vspace{1em} Certains éléments de ce TP sont à rendre à au - plus tard le jeudi 12 novembre 2020 à 12 h 42. Consultez la + plus tard le mercredi 6 octobre 2020 à 23 h 42. Consultez la dernière section de chaque partie pour plus d'informations sur les éléments à rendre.