Save tuto corrections

This commit is contained in:
nemunaire 2022-02-24 20:43:43 +01:00
parent f5ee6b8534
commit 10448a6c8d
115 changed files with 1425 additions and 1291 deletions

View file

@ -113,10 +113,13 @@ Puis on lui demande la génération d'un rapport `html` :
<div lang="en-US">
```bash
paclair --conf conf.yml Docker nemunaire/fic-admin analyse --output-format html --output-report file
paclair --conf conf.yml Docker nemunaire/fic-admin analyse \
--output-format html --output-report file
```
</div>
![Rapport d'analyse statique des vulnérabilités par Clair](paclair.png)
Si l'on souhaite uniquement avoir des statistiques dans la console :
<div lang="en-US">

View file

@ -4,7 +4,7 @@ Si vous n'avez pas déjà le binaire `linuxkit`, vous pouvez télécharger ici 
<https://github.com/linuxkit/linuxkit/releases/latest>.
Notez qu'étant donné qu'il est écrit en Go, aucune dépendance n'est nécessaire
en plus du binaire[^lollibc] ;-)
en plus du binaire[^lollibc] ;-)
[^lollibc]: à condition tout de même que vous utilisiez une libc habituelle.
@ -17,17 +17,17 @@ Le fichier utilisé pour construire notre image se décompose en plusieurs
parties :
- `kernel` : il est attendu ici une image OCI contenant le nécessaire pour
pouvoir utiliser un noyau : l'image du noyau, ses modules et un initramfs ;
pouvoir utiliser un noyau : l'image du noyau, ses modules et un initramfs ;
- `init` : l'ensemble des images OCI de cette liste seront fusionnés pour
donner naissance au *rootfs* de la machine. On n'y place normalement qu'un
gestionnaire de conteneur, qui sera chargé de lancer chaque conteneur au bon
moment ;
moment ;
- `onboot`, `onshutdown` et `services` : il s'agit de conteneurs qui seront
lancés par le système disponible dans l'`init`, au bon moment. Les conteneurs
indiqués dans `onboot` seront lancés **séquentiellement** au démarrage de la
machine, ceux dans `onshutdown` seront lancés lors de l'arrêt de la
machine. Les conteneurs dans `services` seront lancés simultanément une fois
que le dernier conteneur de `onboot` aura rendu la main ;
que le dernier conteneur de `onboot` aura rendu la main ;
- `files` : des fichiers supplémentaires à placer dans le rootfs.
Le format est documenté
@ -63,7 +63,7 @@ trust:
</div>
L'image `getty` est très pratique pour déboguer, car elle permet d'avoir un
shell sur la machine !
shell sur la machine !
On notera cependant que, positionné dans `services`, le shell que nous
obtiendrons sera lui-même exécuté dans un conteneur, nous n'aurons donc pas un
@ -143,7 +143,7 @@ réutiliser plus tard ce chemin, en remplacement du mot clef `new` :
Toute la puissance de `linuxkit` repose dans son système de construction et
surtout de lancement. En effet, il peut construire des images pour un grand
nombre de plate-forme, mais il est également possible d'utiliser les API de ces
plates-formes pour aller y lancer des instances de cette image !
plates-formes pour aller y lancer des instances de cette image !
Pour construire l'image faite précédemment :
@ -154,7 +154,7 @@ linuxkit build hello.yml
</div>
Cela va générer plusieurs fichiers dont un noyau (extrait de l'image de la
partie `kernel`) ainsi qu'une image. Exactement ce qu'attend QEMU ! Pour
partie `kernel`) ainsi qu'une image. Exactement ce qu'attend QEMU ! Pour
tester, n'attendons pas davantage pour lancer :
<div lang="en-US">
@ -227,7 +227,7 @@ choix](https://www.vaultproject.io/docs/configuration/storage/index.html)
Au démarrage, Vault devra déjà être configuré pour parler à sa base de données,
qui devra se trouver dans un conteneur isolé et non accessible d'internet. Il
faudra donc établir un lien `virtual ethernet` entre les deux conteneurs ; et
faudra donc établir un lien `virtual ethernet` entre les deux conteneurs ; et
ne pas oublier de le configurer (automatiquement au *runtime*, grâce à un
[`poststart`
*hook*](https://github.com/opencontainers/runtime-spec/blob/master/config.md#posix-platform-hooks)

View file

@ -8,8 +8,8 @@ tirant parti des conteneurs. Il se positionne comme un système de construction
de machine. En effet, grâce à lui, nous allons pouvoir générer des systèmes
complets, *bootable* dans QEMU, VirtualBox, VMware ou même sur des machines
physiques, qu'il s'agisse de PC ou bien même de Raspberry Pi, ou même encore
des images pour les différents fournisseurs de cloud !
des images pour les différents fournisseurs de cloud !
Bien entendu, au sein de ce système, tout est fait de conteneur ! Alors quand
Bien entendu, au sein de ce système, tout est fait de conteneur ! Alors quand
il s'agit de donner une IP publique utilisable par l'ensemble des conteneurs,
il faut savoir jouer avec les *namespaces* pour arriver à ses fins !
il faut savoir jouer avec les *namespaces* pour arriver à ses fins !

View file

@ -9,14 +9,14 @@ fragmentation de l'écosystème.
Trois spécifications ont été écrites :
- [`runtime-spec`](https://github.com/opencontainers/runtime-spec/blob/master/spec.md#platforms): définit les paramètres du démarrage d'un conteneur ;
- [`image-spec`](https://github.com/opencontainers/image-spec/blob/master/spec.md): définit la construction, le transport et la préparation des images ;
- [`runtime-spec`](https://github.com/opencontainers/runtime-spec/blob/master/spec.md#platforms): définit les paramètres du démarrage d'un conteneur ;
- [`image-spec`](https://github.com/opencontainers/image-spec/blob/master/spec.md): définit la construction, le transport et la préparation des images ;
- [`distribution-spec`](https://github.com/opencontainers/distribution-spec/blob/master/spec.md): définit la manière dont sont partagées et récupérées les images.
## `runtime-spec`
`runc` est l'implémentation de cette spécification ; elle a été extraite de
`runc` est l'implémentation de cette spécification ; elle a été extraite de
`docker`, puis donnée par Docker Inc. à l'OCI.
Pour démarrer un conteneur, la spécification indique qu'il est nécessaire
@ -82,5 +82,5 @@ effectivement nos conteneurs, c'est que l'on peut changer cette implémentation
? la réponse dans l'article :
<https://ops.tips/blog/run-docker-with-forked-runc/>
Et `containerd` dans l'histoire ?
Et `containerd` dans l'histoire ?
<https://hackernoon.com/docker-containerd-standalone-runtimes-heres-what-you-should-know-b834ef155426>

View file

@ -21,13 +21,13 @@ Hub](https://hub.docker.com/), le registre par défaut de `docker`, nous allons
devoir nous plier à leur mécanisme d'authentification : chaque requête au
registre doit être effectuée avec un jeton, que l'on obtient en s'authentifiant
auprès d'un service dédié. Ce service peut délivrer un jeton sans authentifier
l'interlocuteur, en restant anonyme ; dans ce cas, on ne pourra accéder qu'aux
images publiques. Ça tombe bien, c'est ce qui nous intéresse aujourd'hui !
l'interlocuteur, en restant anonyme ; dans ce cas, on ne pourra accéder qu'aux
images publiques. Ça tombe bien, c'est ce qui nous 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` :
<span lang="en-US">`repository:hello-world:pull`</span>). Ce qui nous donne :
Il n'en reste pas moins que le jeton est forgé pour un service donné (ici
`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` : <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*).
@ -58,7 +58,11 @@ Avec `jq`, on peut l'extraire grâce à :
```
</div>
**Attention :** le token expire ! Pensez à le renouveler régulièrement.
::::: {.warning}
Le token expire ! Pensez à le renouveler régulièrement.
:::::
En cas d'erreur inexplicable, vous pouvez ajouter un `-v` à la ligne de
commande `curl`, afin d'afficher les en-têtes. Prêtez une attention toute
@ -94,12 +98,12 @@ système d'exploitation :
curl -s \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: ${MEDIATYPE}" \
"https://registry-1.docker.io/v2/library/hello-world/manifests/${MANIFEST_DIGEST}" | jq .
"https://registry-1.docker.io/v2/library/hello-world/manifests/${MNFST_DGST}"
```
</div>
Nous voici donc maintenant avec le manifest de notre image. Nous pouvons
constater qu'il n'a bien qu'une seule couche, ouf !
constater qu'il n'a bien qu'une seule couche, ouf !
## Récupération de la configuration et de la première couche
@ -115,7 +119,7 @@ Pour récupérer la configuration de l'image :
```bash
curl -s --location \
-H "Authorization: Bearer ${TOKEN}" \
"https://registry-1.docker.io/v2/library/hello-world/blobs/${CONFIG_DIGEST}" | jq .
"https://registry-1.docker.io/v2/library/hello-world/blobs/${CONFIG_DIGEST}"
```
</div>
@ -132,9 +136,11 @@ wget --header "Authorization: Bearer ${TOKEN}" \
## Extraction
Le type indiqué par le manifest pour cette couche était
`application/vnd.docker.image.rootfs.diff.tar.gzip`, il s'agit donc d'une
tarball compressée au format gzip :
Le type indiqué par le manifest pour cette couche était :
application/vnd.docker.image.rootfs.diff.tar.gzip
Il s'agit donc d'une tarball compressée au format gzip :
<div lang="en-US">
```bash
@ -179,7 +185,7 @@ Pensez également à tester avec d'autres images, comme par exemple
`nemunaire/youp0m`. Il vous faudra alors extraire plusieurs couches.
Pour gérer les différentes couches, vous pouvez utiliser une stratégie
similaire au driver `vfs` : en extrayant chaque tarball l'une au dessus de
similaire au driver `vfs` : en extrayant chaque tarball l'une au dessus de
l'autre, en essayant de gérer les *whiteout files*. Ou bien en suivant le
driver `overlayfs`, en montant un système de fichier à chaque couche (dans ce
cas, votre script devra être lancé en `root`).

View file

@ -22,13 +22,13 @@ essayer de lancer un shell `alpine` avec un volume dans notre home.
Vous devriez avoir le binaire `runc` ou `docker-runc`. Si ce n'est pas le cas,
vous pouvez télécharger la dernière version :
<https://github.com/opencontainers/runc/releases>. La 1.0.0-rc92 est Ok.
<https://github.com/opencontainers/runc/releases>.
## Extraction du rootfs
À l'aide du script d'extraction de registre réalisé dans le TP 3, extrayons le
rootfs d'alpine : `library/alpine` dans le registre Docker.
À l'aide du script d'extraction de registre déjà réalisé, extrayons le
*rootfs* d'alpine : `library/alpine` dans le registre Docker.
Si vous n'avez pas eu le temps de terminer le script d'extraction, vous pouvez
utiliser :
@ -55,9 +55,7 @@ runc spec
Pour savoir à quoi correspondent tous ces éléments, vous pouvez consulter :
<https://github.com/opencontainers/runtime-spec/blob/master/config.md>
Nous verrons dans les prochains TP, plus en détails tout ce qui porte sur les
*namespaces*, rassurez-vous, il n'y a que très peu de champs à modifier
aujourd'hui.
Rassurez-vous, il n'y a que très peu de champs à modifier.
## Test brut
@ -143,8 +141,8 @@ stocker les photos (dossier `/srv/images`)[^chmod].
simple pour l'instant serait d'attribuer les permissions `0777` à la
source, temporairement.
Pour ce TP, considérez que vous avez réussi si vous voyez s'afficher :
Pour cette étape, Considérez que vous avez réussi si vous voyez s'afficher :
> `Ready, listening on :8080`
Il faudra attendre les TP suivants pour avoir du réseau dans notre conteneur.
On ne pourra pas tester davantage sans avoir du réseau dans notre conteneur.

View file

@ -10,10 +10,10 @@ machine hébergeant des conteneurs, car cela lui apporte des garanties quant à
l'effort de cloisonnement mis en place.
Mais doit-on pour autant s'arrêter là et considérer que nous avons réglé
l'ensemble des problématiques de sécurité liées aux conteneurs ?
l'ensemble des problématiques de sécurité liées aux conteneurs ?
Évidemment, non : une fois nos services lancés dans des conteneurs, il ne sont
pas moins exposés aux bugs et autres failles applicatives ; qu'elles soient
pas moins exposés aux bugs et autres failles applicatives ; qu'elles soient
dans notre code ou celui d'une bibliothèque, accessible par rebond, ...
Il est donc primordial de ne pas laisser ses conteneurs à l'abandon une fois
@ -23,7 +23,7 @@ image telle que Debian, Ubuntu ou Redhat n'apparaît que pour cela) ou bien
lorsqu'un des programmes ou l'une des bibliothèques que l'on a installés
ensuite est mise à jour.
Convaincu ? Cela sonne encore comme des bonnes pratiques difficiles à mettre en
Convaincu ? Cela sonne encore comme des bonnes pratiques difficiles à mettre en
œuvre, pouvant mettre en péril tout un système d'information. Pour s'en
protéger, nous allons avoir besoin de réaliser à intervalles réguliers une
analyse statique de nos conteneurs.
@ -42,9 +42,9 @@ automatiquement) les images que l'on publie sur un registre public, sans
oublier de mettre à jour l'image de base.
D'ailleurs, avez-vous vérifié qu'une mise à jour de l'image `nemunaire/youp0m`
n'était pas disponible depuis que vous avez commencé à l'utiliser ? Docker ne
n'était pas disponible depuis que vous avez commencé à l'utiliser ? Docker ne
vérifie jamais si une mise à jour des images que vous avez précédemment
téléchargées. Pensez donc régulièrement à appeler :
téléchargées. Pensez donc régulièrement à appeler :
<div lang="en-US">
```
@ -65,10 +65,11 @@ si vous n'en avez pas, nous verrons dans la section suivante `trivy` qui permet
de réaliser ses scans directement sur notre machine, sans passer par un
intermédiaire.
#### Attention {-}
::::: {.warning}
Par cette méthode, vous êtes limité à 10 scans par mois.
:::::
### Installation du plugin
@ -82,13 +83,14 @@ préalablement connecté à votre compte Docker avec la commande `docker login`.
Comme `docker scan` est un plugin, suivant la méthode d'installation que vous
avez suivie, il n'a pas forcément été installé. Si vous obtenez un message
d'erreur en lançant la commande, [voici comment récupérer le plugin et
l'installer manuellement :](https://github.com/docker/scan-cli-plugin#on-linux)
l'installer manuellement :](https://github.com/docker/scan-cli-plugin#on-linux)
<div lang="en-US">
```
mkdir -p ~/.docker/cli-plugins
curl https://github.com/docker/scan-cli-plugin/releases/latest/download/docker-scan_linux_amd64 \
-L -s -S -o ~/.docker/cli-plugins/docker-scan
curl -L -s -S -o ~/.docker/cli-plugins/docker-scan \
https://github.com/docker/scan-cli-plugin/releases/\
latest/download/docker-scan_linux_amd64
chmod +x ~/.docker/cli-plugins/docker-scan
```
</div>
@ -96,7 +98,7 @@ chmod +x ~/.docker/cli-plugins/docker-scan
### Utilisation
Une fois le plugin installé et la licence du service acceptée, nous pouvons
commencer notre analyse :
commencer notre analyse :
<div lang="en-US">
```
@ -112,7 +114,8 @@ Base image: alpine:3.14.2
✓ Tested 16 dependencies for known vulnerabilities, no vulnerable paths found.
According to our scan, you are currently using the most secure version of the selected base image
According to our scan, you are currently using the most secure version of
the selected base image
```
</div>
@ -128,10 +131,10 @@ Testing mysql...
✗ High severity vulnerability found in gcc-8/libstdc++6
Description: Insufficient Entropy
Info: https://snyk.io/vuln/SNYK-DEBIAN10-GCC8-469413
Introduced through: apt@1.8.2.3, mysql-community/mysql-community-client@8.0.26-1debian10, mysql-community/mysql-community-server-core@8.0.26-1debian10, mecab-ipadic@2.7.0-20070801+main-2.1, meta-common-packages@meta
Introduced through: apt@1.8.2.3, mysql-community/mysql-community-client@[...]
From: apt@1.8.2.3 > gcc-8/libstdc++6@8.3.0-6
From: mysql-community/mysql-community-client@8.0.26-1debian10 > gcc-8/libstdc++6@8.3.0-6
From: mysql-community/mysql-community-server-core@8.0.26-1debian10 > gcc-8/libstdc++6@8.3.0-6
From: mysql-community/mysql-community-client@8.0.26-1debian10 > gcc-8[...]
From: mysql-community/mysql-community-server-core@8.0.26-1debian10 > gcc-8[...]
and 7 more...
Image layer: Introduced by your base image (mysql:8.0.26)
@ -143,11 +146,12 @@ Base image: mysql:8.0.26
Tested 135 dependencies for known vulnerabilities, found 79 vulnerabilities.
According to our scan, you are currently using the most secure version of the selected base image
According to our scan, you are currently using the most secure version of
the selected base image
```
</div>
Ce dernier exemple est sans appel : `mysql` est une image officielle, et sa
Ce dernier exemple est sans appel : `mysql` est une image officielle, et sa
dernière version à l'écriture de ses lignes contient pas moins de 79
vulnérabilités dont 11 *high*.
@ -168,7 +172,7 @@ un certain nombre d'arguments, notamment le nom de l'image à analyser.
### Utilisation
Tentons à nouveau d'analyser l'image `mysql` :
Tentons à nouveau d'analyser l'image `mysql` :
<div lang="en-US">
```
@ -189,7 +193,7 @@ Les résultats sont un peu différents qu'avec `docker scan`, mais on constate
que l'image `mysql` contient vraiment de nombreuses vulnérabilités. Même si
elles ne sont heureusement pas forcément exploitable directement.
Voyons maintenant s'il y a des différentes avec l'image `nemunaire/fic-admin` :
Voyons maintenant s'il y a des différentes avec l'image `nemunaire/fic-admin` :
<div lang="en-US">
```
@ -217,7 +221,7 @@ vulnérabilités de l'image, a aussi fait une analyse des dépendances du binair
`/srv/admin`.
Trivy est en effet capable de rechercher des vulnérabilités par rapport aux
dépendances connues de certains langages : Python, PHP, Node.js, .NET, Java,
dépendances connues de certains langages : Python, PHP, Node.js, .NET, Java,
Go, ...
@ -225,7 +229,7 @@ Go, ...
Pour éviter de surcharger les serveurs de distributions de la base de données
de vulnérabilités, nous devrions utiliser un cache pour faire nos
analyses. Préférez lancer `trivy` avec les options suivantes :
analyses. Préférez lancer `trivy` avec les options suivantes :
<div lang="en-US">
```
@ -242,7 +246,7 @@ pouvoir l'exporter pour l'afficher dans un navigateur (par exemple pour le
mettre à disposition des développeurs, lors d'une analyse automatique).
Pour ce faire, on peut ajouter les options suivantes à la ligne de commande de
notre conteneur :
notre conteneur :
<div lang="en-US">
```bash
@ -253,8 +257,6 @@ notre conteneur :
En redirigeant la sortie standard vers un fichier, vous pourrez l'ouvrir dans
votre navigateur favori.
---
![Scan de vulnérabilités sur le registre Quay.io](quay-vulns.png){ width=90% }
![Scan de vulnérabilités sur le registre Quay.io](quay-vulns.png){ width=80% }
## Clair