Update TP3
This commit is contained in:
parent
5b03f090fe
commit
50cbff18eb
@ -1,7 +1,9 @@
|
|||||||
SOURCES = tutorial.md installation.md chroot.md pseudofs.md mount.md capabilities.md cgroups.md oom.md project-intro.md project-body.md project-rendu.md
|
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
|
||||||
PANDOCOPTS = --pdf-engine=xelatex \
|
PANDOCOPTS = --latex-engine=xelatex \
|
||||||
--standalone \
|
--standalone \
|
||||||
|
--normalize \
|
||||||
--number-sections \
|
--number-sections \
|
||||||
|
--smart \
|
||||||
-M lang=fr-FR \
|
-M lang=fr-FR \
|
||||||
-M fontsize=12pt \
|
-M fontsize=12pt \
|
||||||
-M papersize=a4paper \
|
-M papersize=a4paper \
|
||||||
|
@ -29,7 +29,7 @@ procédure suivante :
|
|||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Cette dernière commande monte le groupe de processus racine, pour le *cgroup*
|
Cette dernière commande monte l'arborescence de groupes relative à ce *cgroup*
|
||||||
*freezer*. Tous les dossiers contenus dans cette racine sont donc des
|
*freezer*. Tous les dossiers contenus dans cette racine sont donc des
|
||||||
sous-groupes.
|
sous-groupes.
|
||||||
|
|
||||||
@ -144,11 +144,12 @@ l'installer sur notre machine) :
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
Il nous faut ensuite créer une base de données pour y stocker nos
|
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 :
|
métriques. Voici comment on s'était débrouillé dans un précédent TP pour
|
||||||
|
interagir avec InfluxDB :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```shell
|
```shell
|
||||||
docker container exec -i mytsdb <<EOF
|
docker container exec -i mytsdb influxdb <<EOF
|
||||||
CREATE DATABASE metrics;
|
CREATE DATABASE metrics;
|
||||||
SHOW DATABASES;
|
SHOW DATABASES;
|
||||||
EOF
|
EOF
|
||||||
@ -163,15 +164,23 @@ Vérifiez que la base de données `metrics` a bien été créée.
|
|||||||
Dans un premier temps, commençons par afficher dans la console, la quantité de
|
Dans un premier temps, commençons par afficher dans la console, la quantité de
|
||||||
mémoire utilisée par le groupe monitoré.
|
mémoire utilisée par le groupe monitoré.
|
||||||
|
|
||||||
* Arguments de la ligne de commande :
|
|
||||||
- premier fils à lancer dans le groupe,
|
|
||||||
- intervalle de temps entre deux rafraîchissements ;
|
|
||||||
* *cgroup* `memory`;
|
|
||||||
* `memory.usage_in_bytes`.
|
|
||||||
|
|
||||||
Vous pouvez utiliser un programme comme `memhog` pour remplir rapidement votre
|
Vous pouvez utiliser un programme comme `memhog` pour remplir rapidement votre
|
||||||
mémoire.
|
mémoire.
|
||||||
|
|
||||||
|
```
|
||||||
|
42sh# mkdir /sys/fs/cgroup...
|
||||||
|
42sh$ echo $$ | sudo tee /sys/fs/cgroup.../tasks
|
||||||
|
42sh# ./monitor group_name memhog 500
|
||||||
|
~~~ 13595 ~~~ Current memory usage: 75194368/550502400 (13%)
|
||||||
|
~~~ 13595 ~~~ Current memory usage: 150290432/550502400 (27%)
|
||||||
|
~~~ 13595 ~~~ Current memory usage: 223690752/550502400 (40%)
|
||||||
|
~~~ 13595 ~~~ Current memory usage: 296828928/550502400 (53%)
|
||||||
|
~~~ 13595 ~~~ Current memory usage: 368001024/550502400 (66%)
|
||||||
|
~~~ 13595 ~~~ Current memory usage: 438517760/550502400 (79%)
|
||||||
|
~~~ 13595 ~~~ Current memory usage: 480329728/550502400 (87%)
|
||||||
|
~~~ 13595 ~~~ Current memory usage: 155648/550502400 (0%)
|
||||||
|
```
|
||||||
|
|
||||||
Si vous n'avez pas le *cgroup* *memory*, il est possible qu'il ne soit pas
|
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
|
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.
|
d'ajouter `cgroup_enable=memory` à la ligne de commande de votre noyau.
|
||||||
@ -180,7 +189,7 @@ d'ajouter `cgroup_enable=memory` à la ligne de commande de votre noyau.
|
|||||||
### Monitoring vers InfluxDB
|
### Monitoring vers InfluxDB
|
||||||
|
|
||||||
Maintenant, envoyons nos données vers la base
|
Maintenant, envoyons nos données vers la base
|
||||||
<https://docs.influxdata.com/influxdb/v1.3/guides/writing_data/> :
|
<https://docs.influxdata.com/influxdb/v1.6/guides/writing_data/> :
|
||||||
|
|
||||||
<div lang="en-US">
|
<div lang="en-US">
|
||||||
```
|
```
|
||||||
|
@ -36,7 +36,8 @@ 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,
|
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é.
|
jusqu'à ce que le système retrouve sa sérénité.
|
||||||
|
|
||||||
[^oom-algo]: ```c
|
[^oom-algo]: \
|
||||||
|
```
|
||||||
/*
|
/*
|
||||||
* oom_badness - calculate a numeric value for how bad this task has been
|
* oom_badness - calculate a numeric value for how bad this task has been
|
||||||
* @p: task struct of which task we should calculate
|
* @p: task struct of which task we should calculate
|
||||||
@ -54,7 +55,8 @@ jusqu'à ce que le système retrouve sa sérénité.
|
|||||||
* 5) we try to kill the process the user expects us to kill, this
|
* 5) we try to kill the process the user expects us to kill, this
|
||||||
* algorithm has been meticulously tuned to meet the principle
|
* algorithm has been meticulously tuned to meet the principle
|
||||||
* of least surprise ... (be careful when you change it)
|
* of least surprise ... (be careful when you change it)
|
||||||
*/```
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Esquiver l'OOM killer
|
## Esquiver l'OOM killer
|
||||||
|
@ -30,5 +30,9 @@ pour chaque exercice) :
|
|||||||
login_x-TP3/view_caps.c
|
login_x-TP3/view_caps.c
|
||||||
login_x-TP3/monitor.sh
|
login_x-TP3/monitor.sh
|
||||||
login_x-TP3/monitor_init.sh
|
login_x-TP3/monitor_init.sh
|
||||||
|
login_x-TP3/syscall_filter.c
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Les premières étapes du projet ne sont pas à rendre et feront l'objet
|
||||||
|
d'un rendu à part.
|
||||||
|
@ -121,25 +121,16 @@ afficher des informations sur un processus donné :
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
### `batinfo.sh`
|
### `rev_kdb_leds.sh`, `batinfo.sh`, `cpuinfo.sh`
|
||||||
|
|
||||||
Explorons le pseudo système de fichiers `/sys` pour écrire un script
|
Explorons le pseudo système de fichiers `/sys` pour écrire un script
|
||||||
qui va nous renvoyer des statistiques sur votre batterie.
|
qui va, en fonction de ce que vous avez de disponible :
|
||||||
|
|
||||||
|
* inverser l'état des diodes de notre clavier ;
|
||||||
|
* nous afficher des statistiques sur notre batterie ;
|
||||||
|
* nous afficher des statistiques la fréquence de notre CPU.
|
||||||
|
|
||||||
Voici un exemple d'utilisation :
|
#### `rev_kdb_leds.sh`
|
||||||
|
|
||||||
<div lang="en-US">
|
|
||||||
```shell
|
|
||||||
42sh$ ./rev_kdb_leds.sh input20
|
|
||||||
```
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
### `rev_kdb_leds.sh`
|
|
||||||
|
|
||||||
Explorons le pseudo système de fichiers `/sys` pour écrire un script
|
|
||||||
qui va inverser l'état des diodes de notre clavier.
|
|
||||||
|
|
||||||
Si vous avez :
|
Si vous avez :
|
||||||
|
|
||||||
@ -160,3 +151,55 @@ Voici un exemple d'utilisation :
|
|||||||
42sh$ ./rev_kdb_leds.sh input20
|
42sh$ ./rev_kdb_leds.sh input20
|
||||||
```
|
```
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
#### `batinfo.sh`
|
||||||
|
|
||||||
|
Voici un exemple d'utilisation :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```shell
|
||||||
|
42sh$ ./batinfo.sh
|
||||||
|
BAT0 Discharging
|
||||||
|
====
|
||||||
|
Capacity: 83% (Normal)
|
||||||
|
Voltage: 11.972000 V (minimal: 11.400000 V)
|
||||||
|
Energy: 18.290000/21.830000 Wh
|
||||||
|
Power: 7.937000 W
|
||||||
|
Remaining time: 2.304 h
|
||||||
|
|
||||||
|
BAT1 Unknown
|
||||||
|
====
|
||||||
|
Capacity: 83% (Normal)
|
||||||
|
Voltage: 11.972000 V (minimal: 11.400000 V)
|
||||||
|
Energy: 18.290000/21.830000 Wh
|
||||||
|
Power: 0.0 W
|
||||||
|
Remaining time: N/A
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
#### `cpuinfo.sh`
|
||||||
|
|
||||||
|
Voici un exemple d'utilisation :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```shell
|
||||||
|
42sh$ ./cpuinfo.sh
|
||||||
|
cpu0
|
||||||
|
====
|
||||||
|
Current frequency: 2100384 Hz
|
||||||
|
Current governor: powersave
|
||||||
|
Allowed frequencies: between 500000 - 2100000 Hz
|
||||||
|
Thermal throttle count: 0
|
||||||
|
|
||||||
|
cpu1
|
||||||
|
====
|
||||||
|
Current frequency: 2099871 Hz
|
||||||
|
Current governor: powersave
|
||||||
|
Allowed frequencies: between 500000 - 2100000 Hz
|
||||||
|
Thermal throttle count: 0
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
N'hésitez pas à rajouter toute sorte d'information intéressantes !
|
||||||
|
92
tutorial/3/seccomp.md
Normal file
92
tutorial/3/seccomp.md
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
\newpage
|
||||||
|
|
||||||
|
Secure Computing Mode
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Plus connue sous l'acronyme *seccomp*, cette fonctionnalité du noyau Linux
|
||||||
|
permet de restreindre les appels systèmes qu'un processus est autorisé à
|
||||||
|
utiliser. En cas d'appel non autorisé, le processus fautif est directement tué
|
||||||
|
(`SIGKILL`) par le noyau, ou, lorsque c'est précisé, un code `errno`
|
||||||
|
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
|
||||||
|
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
|
||||||
|
initialisation (ne dépendant en général pas de données sujettes à
|
||||||
|
l'exploitation de vulnérabilité) et doit commencer à entrer dans des portions
|
||||||
|
de code promptes aux vulnérabilités : c'est notamment le cas des moteurs de
|
||||||
|
rendus des navigateurs Firefox et Chrome.
|
||||||
|
|
||||||
|
|
||||||
|
## Prérequis
|
||||||
|
|
||||||
|
L'utilisation de `seccomp` nécessite d'avoir un noyau compilé avec l'option
|
||||||
|
`CONFIG_SECCOMP`.
|
||||||
|
|
||||||
|
Vous aurez également besoin de la bibliothèque `libseccomp` car l'appel système
|
||||||
|
`seccomp(2)` n'a pas de *wrapper* dans la libc, vous devrez donc passer par
|
||||||
|
cette bibliothèque.
|
||||||
|
|
||||||
|
|
||||||
|
## `MODE_STRICT`
|
||||||
|
|
||||||
|
Le mode traditionnel de *seccomp* est de ne permettre uniquement l'utilisation
|
||||||
|
des appels système `read(2)`, `write(2)` (sur les descripteurs de fichier déjà
|
||||||
|
ouvert), `_exit(2)` et `sigreturn(2)`.
|
||||||
|
|
||||||
|
Historiquement, avant la création de l'appel système `seccomp(2)`, on activait
|
||||||
|
ce mode via :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```c
|
||||||
|
prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Une fois passé cet appel système, toute entrée dans un appel système non
|
||||||
|
autorisé conduit à un `SIGKILL` du processus.
|
||||||
|
|
||||||
|
|
||||||
|
## `MODE_FILTER`
|
||||||
|
|
||||||
|
Plus modulable que le mode strict, le mode de filtrage permet une grande
|
||||||
|
amplitude en permettant au programmeur de définir finement quels appels
|
||||||
|
systèmes le programme est autorisé à faire ou non, et quel sentence est
|
||||||
|
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
|
||||||
|
des règles BPF (`Berkeley Packet Filter`). On passe ensuite ce filtre BPF en
|
||||||
|
argument de l'appel système :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```c
|
||||||
|
struct sock_filter filter[];
|
||||||
|
struct sock_fprog prog = {
|
||||||
|
.len = (unsigned short) (sizeof(filter) / sizeof(filter[0])),
|
||||||
|
.filter = filter,
|
||||||
|
};
|
||||||
|
seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
### Exercice
|
||||||
|
|
||||||
|
Écrivez un programme filtrant un appel système, à l'aide de `seccomp` :
|
||||||
|
|
||||||
|
<div lang="en-US">
|
||||||
|
```
|
||||||
|
42sh$ ./syscall_filter sleep 5
|
||||||
|
sleep: cannot read realtime clock: Operation not permitted
|
||||||
|
42sh$
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Dans cet exemple, l'appel système filtré est `nanosleep(2)`.
|
Loading…
Reference in New Issue
Block a user