tutorials: improve theme + use pandoc 2

This commit is contained in:
nemunaire 2018-11-16 02:38:41 +01:00
commit d25af4fdb2
65 changed files with 1283 additions and 1294 deletions

View file

@ -1,19 +1,6 @@
include ../pandoc-opts.mk
SOURCES = tutorial.md clair.md oci.md registry.md runc.md linuxkit.md rendu.md
PANDOCOPTS = --latex-engine=xelatex \
--standalone \
--normalize \
--number-sections \
--smart \
-M lang=fr-FR \
-M fontsize=12pt \
-M papersize=a4paper \
-M mainfont="Linux Libertine O" \
-M monofont="FantasqueSansMono-Regular" \
-M sansfont="Linux Biolinum O" \
-M colorlinks=true \
-M linkcolor="black" \
-M urlcolor="[rgb]{0.2,0.6,0.4}" \
--include-in-header=../header.tex
all: tutorial.pdf

View file

@ -1,7 +1,7 @@
\newpage
Une vision plus Clair de la sécurité ?
======================================
Une vision plus Clair de la sécurité
====================================
Nous avons vu, au travers de tous les précédents TP, que Docker nous apportait
un certain degré de sécurité d'emblée au lancement du conteneur. Cela peut sans
@ -86,9 +86,9 @@ Une fois lancé, la base nécessite d'être initialisée. L'opération peut pren
plusieurs minutes. Vous pouvez suivre l'avancement de l'ajout :
<div lang="en-US">
```shell
curl http://localhost:6060/v1/namespaces
curl http://localhost:6060/v1/namespaces/debian:9/vulnerabilities?limit=10
```bash
curl http://localhost:6060/v1/namespaces
curl http://localhost:6060/v1/namespaces/debian:9/vulnerabilities?limit=10
```
</div>
@ -100,8 +100,8 @@ conteneur, nous allons utiliser le programme
[`paclair`](https://github.com/yebinama/paclair) :
<div lang="en-US">
```shell
pip3 install paclair
```bash
pip3 install paclair
```
</div>
@ -109,11 +109,11 @@ Il nécessite un fichier de configuration pour être utilisé, essayez :
<div lang="en-US">
```yml
General:
clair_url: 'http://localhost:6060'
Plugins:
Docker:
class: paclair.plugins.docker_plugin.DockerPlugin
General:
clair_url: 'http://localhost:6060'
Plugins:
Docker:
class: paclair.plugins.docker_plugin.DockerPlugin
```
</div>
@ -121,33 +121,33 @@ Pour obtenir un rapport d'analyse, on commence par envoyer les couches de
l'image à `Clair` :
<div lang="en-US">
```shell
paclair --conf conf.yml Docker nemunaire/fic-admin push
```bash
paclair --conf conf.yml Docker nemunaire/fic-admin push
```
</div>
Puis on lui demande la génération d'un rapport `html` :
<div lang="en-US">
```shell
paclair --conf conf.yml Docker nemunaire/fic-admin analyse --output-format html --output-report file
```bash
paclair --conf conf.yml Docker nemunaire/fic-admin analyse --output-format html --output-report file
```
</div>
Si l'on souhaite uniquement avoir des statistiques dans la console :
<div lang="en-US">
```shell
42sh$ paclair --conf conf.yml Docker node:latest analyse --output-format stats
Unknown: 2
Negligible: 1
Medium: 5
High: 4
```bash
42sh$ paclair --conf conf.yml Docker node:latest analyse --output-format stats
Unknown: 2
Negligible: 1
Medium: 5
High: 4
```
</div>
## Exercice {.unnumbered}
## Exercice {-}
Déterminez le nombre de vulnérabilités dans les principales images officielles
du [Docker Hub](https://hub.docker.com/explore), notamment `nginx`, `golang`,

View file

@ -67,25 +67,25 @@ L'image la plus simple que l'on puisse réaliser pourrait être :
<div lang="en-US">
```yaml
kernel:
image: linuxkit/kernel:4.14.80
cmdline: "console=tty0 console=ttyS0"
init:
- linuxkit/init:c563953a2277eb73a89d89f70e4b6dcdcfebc2d1
- linuxkit/runc:83d0edb4552b1a5df1f0976f05f442829eac38fe
- linuxkit/containerd:326b096cd5fbab0f864e52721d036cade67599d6
onboot:
- name: dhcpcd
image: linuxkit/dhcpcd:v0.6
command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"]
services:
- name: getty
image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478
env:
- INSECURE=true
trust:
org:
- linuxkit
kernel:
image: linuxkit/kernel:4.14.80
cmdline: "console=tty0 console=ttyS0"
init:
- linuxkit/init:c563953a2277eb73a89d89f70e4b6dcdcfebc2d1
- linuxkit/runc:83d0edb4552b1a5df1f0976f05f442829eac38fe
- linuxkit/containerd:326b096cd5fbab0f864e52721d036cade67599d6
onboot:
- name: dhcpcd
image: linuxkit/dhcpcd:v0.6
command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"]
services:
- name: getty
image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478
env:
- INSECURE=true
trust:
org:
- linuxkit
```
</div>
@ -102,7 +102,7 @@ la partie `init`, elle sera alors lancé comme un équivalent de
<https://github.com/linuxkit/linuxkit/blob/master/pkg/getty/README.md#linuxkit-debug>
## *namespaces*
## `namespaces`
Chaque nouveau conteneur est donc lancé dans un espace distinct où il ne pourra
pas interagir avec les autres, ou déborder s'il s'avérait qu'il expose une
@ -117,9 +117,9 @@ Il reste possible de se dissocier également de ces namespaces, en précisant :
<div lang="en-US">
```yaml
- name: getty
image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478
net: new
- name: getty
image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478
net: new
```
</div>
@ -127,14 +127,14 @@ Ou inversement, pour persister dans le namespace initial :
<div lang="en-US">
```yaml
- name: getty
image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478
pid: host
- name: getty
image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478
pid: host
```
</div>
### Partage de *namespace*
### Partage de `namespace`
Dans le cas où l'on souhaite que deux conteneurs partagent le même *namespace*,
il faut passer le chemin vers la structure du noyau correspondante.
@ -144,11 +144,11 @@ On commence donc d'abord par créer le nouveau *namespace*, en prenant soin de
<div lang="en-US">
```yaml
- name: getty
image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478
net: new
runtime:
bindNS: /run/netns/mynewnetns
- name: getty
image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478
net: new
runtime:
bindNS: /run/netns/mynewnetns
```
</div>
@ -158,9 +158,9 @@ réutiliser plus tard ce chemin, en remplacement du mot clef `new` :
<div lang="en-US">
```yaml
- name: xxxx
image: linuxkit/xxxx:v0.6
net: /run/netns/mynewnetns
- name: xxxx
image: linuxkit/xxxx:v0.6
net: /run/netns/mynewnetns
```
</div>
@ -175,8 +175,8 @@ plates-formes pour aller y lancer des instances de cette image !
Pour construire l'image faite précédemment :
<div lang="en-US">
```shell
linuxkit build hello.yml
```bash
linuxkit build hello.yml
```
</div>
@ -185,8 +185,8 @@ partie `kernel`) ainsi qu'une image. Exactement ce qu'attend QEMU ! Pour
tester, n'attendons pas davantage pour lancer :
<div lang="en-US">
```shell
linuxkit run qemu -gui hello
```bash
linuxkit run qemu -gui hello
```
</div>
@ -199,8 +199,8 @@ serveur SSH aux `services` :
<div lang="en-US">
```yaml
- name: sshd
image: linuxkit/sshd:c4bc89cf0d66733c923ab9cb46198b599eb99320
- name: sshd
image: linuxkit/sshd:c4bc89cf0d66733c923ab9cb46198b599eb99320
```
</div>
@ -209,9 +209,9 @@ SSH pour se connecter. Voilà un bon début d'utilisation de la section `files`
<div lang="en-US">
```yaml
- path: root/.ssh/authorized_keys
source: ~/.ssh/id_rsa.pub
mode: "0600"
- path: root/.ssh/authorized_keys
source: ~/.ssh/id_rsa.pub
mode: "0600"
```
</div>
@ -230,21 +230,21 @@ une interface `virtual ethernet` :
<div lang="en-US">
```yaml
- name: db
image: mariadb:latest
net: new
runtime:
bindNS:
net: /run/netns/db
interfaces:
- name: vethin-db
add: veth
peer: veth-db
- name: db
image: mariadb:latest
net: new
runtime:
bindNS:
net: /run/netns/db
interfaces:
- name: vethin-db
add: veth
peer: veth-db
```
</div>
## Exercice
## Exercice {-}
Réalisez une recette `vault.yml` démarrant une instance du gestionnaire de
secrets [Hashicorp Vault](https://www.vaultproject.io/), utilisant une [base de

View file

@ -75,7 +75,7 @@ Dernière née de l'organisme, cette spécification fédère la notion de
aussi en envoyer.
## Pour aller plus loin
## Pour aller plus loin {-}
Si maintenant `docker` fait appel à un programme externe pour lancer
effectivement nos conteneurs, c'est que l'on peut changer cette implémentation

View file

@ -3,6 +3,8 @@ Registres
**Outils nécessaires :** `curl`, `gunzip`, `jq`, `tar`.
* * * * *
Dans cette partie, nous allons appréhender le fonctionnement d'un registre OCI,
et préparer le *rootfs* d'une image de base (Debian, Ubuntu, hello, ...) : en
nous préoccupant simplement de la couche la plus basse (qui ne contient pas de
@ -24,23 +26,23 @@ intéresse aujourd'hui !
Il n'en reste pas moins que le jeton est forgé pour un service donné (dans
notre cas `registry.docker.io`) et avec un objectif bien cerné (pour nous, on
souhaite récupérer le contenu du dépôt[^quiddepot] `hello-world` :
`repository:hello-world:pull`). Ce qui nous donne :
<span lang="en-US">`repository:hello-world:pull`</span>). Ce qui nous donne :
[^quiddepot]: Dans un registre, les fichiers qui composent l'image forment un
dépôt (*repository*).
<div lang="en-US">
```shell
42sh$ curl "https://auth.docker.io/token"\
> "?service=registry.docker.io&scope=repository:library/hello-world:pull" | jq .
```bash
42sh$ curl "https://auth.docker.io/token?service=registry.docker.io&"\
> "scope=repository:library/hello-world:pull" | jq .
```
```json
{
"token": "lUWXBCZzg2TGNUdmMy...daVZxGTj0eh",
"access_token": "eyJhbGciOiJSUzI1NiIsI...N5q469M3ZkL_HA",
"expires_in": 300,
"issued_at": "2012-12-12T12:12:12.123456789Z"
}
{
"token": "lUWXBCZzg2TGNUdmMy...daVZxGTj0eh",
"access_token": "eyJhbGciOiJSUzI1NiIsI...N5q469M3ZkL_HA",
"expires_in": 300,
"issued_at": "2012-12-12T12:12:12.123456789Z"
}
```
</div>
@ -50,8 +52,8 @@ registre.
Avec `jq`, on peut l'extraire grâce à :
<div lang="en-US">
```shell
| jq -r .token
```bash
| jq -r .token
```
</div>
@ -62,11 +64,11 @@ Une fois en possession de notre jeton, nous pouvons maintenant demander l'index
d'images à notre registre :
<div lang="en-US">
```shell
curl -s \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" \
"https://registry-1.docker.io/v2/library/hello-world/manifests/latest" | jq .
```bash
curl -s \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" \
"https://registry-1.docker.io/v2/library/hello-world/manifests/latest" | jq .
```
</div>
@ -81,11 +83,11 @@ Demandons maintenant le manifest correspondant à notre matériel et à notre
système d'exploitation :
<div lang="en-US">
```shell
curl -s \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: ${MEDIATYPE}" \
"https://registry-1.docker.io/v2/library/hello-world/manifests/${MANIFEST_DIGEST}" | jq .
```bash
curl -s \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: ${MEDIATYPE}" \
"https://registry-1.docker.io/v2/library/hello-world/manifests/${MANIFEST_DIGEST}" | jq .
```
</div>
@ -101,10 +103,10 @@ répertoire `blobs`, il ne s'agit en effet plus de manifest. Si les manifests so
Pour récupérer la configuration de l'image :
<div lang="en-US">
```shell
curl -s --location \
-H "Authorization: Bearer ${TOKEN}" \
"https://registry-1.docker.io/v2/library/hello-world/blobs/${CONFIG_DIGEST}" | jq .
```bash
curl -s --location \
-H "Authorization: Bearer ${TOKEN}" \
"https://registry-1.docker.io/v2/library/hello-world/blobs/${CONFIG_DIGEST}" | jq .
```
</div>
@ -112,9 +114,9 @@ Pour récupérer la configuration de l'image :
Enfin, armé du `digest` de notre couche, il ne nous reste plus qu'à la demander gentiment :
<div lang="en-US">
```shell
wget --header "Authorization: Bearer ${TOKEN}" \
"https://registry-1.docker.io/v2/library/hello-world/blobs/${LAYER_DIGEST}"
```bash
wget --header "Authorization: Bearer ${TOKEN}" \
"https://registry-1.docker.io/v2/library/hello-world/blobs/${LAYER_DIGEST}"
```
</div>
@ -126,40 +128,40 @@ Le type indiqué par le manifest pour cette couche était
tarball compressée au format gzip :
<div lang="en-US">
```shell
mkdir rootfs
tar xzf ${DL_LAYER} -C rootfs
```bash
mkdir rootfs
tar xzf ${DL_LAYER} -C rootfs
```
</div>
Et voilà, nous avons extrait notre première image, nous devrions pouvoir :
<div lang="en-US">
```shell
42sh# chroot rootfs /hello
Hello from Docker!
[...]
```bash
42sh# chroot rootfs /hello
Hello from Docker!
[...]
```
</div>
## Exercice {.unnumbered}
## Exercice {-}
Réalisez un script pour automatiser l'ensemble de ces étapes :
<div lang="en-US">
```shell
42sh$ cd $(mktemp)
```bash
42sh$ cd $(mktemp)
42sh$ ~/workspace/registry_play.sh library/hello
42sh$ ~/workspace/registry_play.sh library/hello
42sh$ find
.
./rootfs
./rootfs/hello
42sh$ find
.
./rootfs
./rootfs/hello
42sh# chroot rootfs /hello
Hello from Docker!
[...]
42sh# chroot rootfs /hello
Hello from Docker!
[...]
```
</div>

View file

@ -30,13 +30,13 @@ cela dépendra de votre avancée dans le projet) :
<div lang="en-US">
```
login_x-TP5/
login_x-TP5/docker-compose.yml
login_x-TP5/clair_config/config.yaml
login_x-TP5/nginx:mainline.html
login_x-TP5/registry_play.sh
login_x-TP5/config.json
login_x-TP5/vault.yml
login_x-TP5/pkg/...
login_x-TP5/
login_x-TP5/docker-compose.yml
login_x-TP5/clair_config/config.yaml
login_x-TP5/nginx:mainline.html
login_x-TP5/registry_play.sh
login_x-TP5/config.json
login_x-TP5/vault.yml
login_x-TP5/pkg/...
```
</div>

View file

@ -32,7 +32,13 @@ vous pouvez télécharger la dernière version :
d'alpine : `library/alpine` dans le registre Docker.
Si vous n'avez pas eu le temps de terminer l'exercice précédent, vous pouvez
utiliser `docker image save alpine | tar xv -C rootfs`.
utiliser :
<div lang="en-US">
```bash
docker image save alpine | tar xv -C rootfs
```
</div>
## Modèle de configuration
@ -42,8 +48,8 @@ fastidieux et répétitif, nous allons donc gagner du temps et utiliser la
commande suivante, qui nous créera un modèle que nous adapterons un peu :
<div lang="en-US">
```shell
runc spec
```bash
runc spec
```
</div>
@ -56,12 +62,12 @@ Pour savoir à quoi correspondent tous ces éléments, vous pouvez consulter :
Voici comment nous pouvons tester le fonctionnement de notre *bundle* :
<div lang="en-US">
```shell
42sh$ ls
rootfs/ config.json
```
42sh$ ls
rootfs/ config.json
42sh# runc run --bundle . virli1
/ # _
42sh# runc run --bundle . virli1
/ # _
```
</div>
@ -70,34 +76,34 @@ retrouver tout l'écosystème de `docker` ; ici il n'y a pas de gestion des
journaux, etc. :
<div lang="en-US">
```shell
42sh# runc list
ID PID STATUS BUNDLE CREATED OWNER
virli1 12345 running /tmp/work/runctest 2012-12-12T12:12:12.123456789Z root
```bash
42sh# runc list
ID PID STATUS BUNDLE CREATED OWNER
virli1 12345 running /tmp/work/runctest 2012-12-12T12:12:12.123456789Z root
42sh# runc state virli1
...
42sh# runc state virli1
...
```
</div>
## Attacher notre *home*
## Attacher notre `home`
Dans le modèle de `config.json`, il y a déjà de nombreux systèmes de fichiers
qui sont montés. Nous pouvons les filtrer avec :
<div lang="en-US">
```shell
42sh$ jq .mounts config.json
```bash
42sh$ jq .mounts config.json
```
```json
[
{
"destination": "/proc",
"type": "proc",
"source": "proc"
},
[...]
[
{
"destination": "/proc",
"type": "proc",
"source": "proc"
},
[...]
```
</div>
@ -106,25 +112,25 @@ ajouter un élément à cette liste, demandant de *bind* :
<div lang="en-US">
```json
{
"destination": "/home",
"type": "none",
"source": "/home",
"options": [
{
"destination": "/home",
"type": "none",
"source": "/home",
"options": [
"bind",
"ro"
]
}
}
```
</div>
## Exercice
## Exercice {-}
Serez-vous capable de continuer l'édition de votre `config.json` afin d'obtenir
les mêmes restrictions que votre projet de moulette ?
* CGroups : 1GB RAM, 100 PID, ...
* CGroups : 1\ GB RAM, 100\ PIDs, ...
* strict minimum de capabilities ;
* filtres `seccomp` ;
* carte réseau `veth` ;

View file

@ -1,22 +1,23 @@
---
title: Virtualisation légère -- TP n^o^ 5
subtitle: Docker Internals
author: Pierre-Olivier *Nemunaire* Mercier
author: Pierre-Olivier *nemunaire* [Mercier]{.smallcaps}
institute: EPITA
date: Mercredi 14 novembre 2018
abstract: |
Dans ce cinquième du TP, nous allons entrer dans les sous-bassements de
Docker !
\vspace{1em}
Tous les éléments de ce TP (exercices et projet) sont à rendre à
<virli@nemunai.re> au plus tard le dimanche 25 novembre 2018 à 23
h 42. Consultez la dernière section de chaque partie pour plus d'information
sur les éléments à rendre.
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
vous devrez m'envoyer vos rendus signés avec votre clef PGP. Pensez à
[me](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96)
faire signer votre clef et n'hésitez pas à [faire signer votre
clef](https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
...
Dans ce cinquième du TP, nous allons entrer dans les sous-bassements de Docker !
Tous les éléments de ce TP (exercices et projet) sont à rendre à
<virli@nemunai.re> au plus tard le dimanche 25 novembre 2018 à 23 h 42. Consultez la
dernière section de chaque partie pour plus d'information sur les éléments à
rendre.
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
vous devrez m'envoyer vos rendus signés avec votre clef PGP. Pensez à
[me](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96) faire
signer votre clef et n'hésitez pas à
[faire signer votre clef](https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
\tableofcontents