L'infrastructure immuable
Ep. 02

L'infrastructure immuable

Episode description

Dans ce deuxième épisode, on explore la notion d’infrastructure immuable, une approche alternative à l’utilisation d’outils de configuration par mutation. On y parle de l’immuabilité conventionnelle, de distributions Linux spécialisées comme Fedora Core OS, OpenSUSE MicroOS ou Flatcar Container Linux, ainsi que d’outils comme mkosi.

Musique d’intro : https://soundcloud.com/royaltyfreebackgroundmusic/creative-commons-music-edm-62 sous licence CC BY-NC-ND

Download transcript (.srt)
0:15

Bonjour à toutes et à tous, et bienvenue dans ce deuxième

0:17

épisode de Yakafokon.

0:20

Dans le précédent épisode, j'ai exposé les problèmes que je

0:22

voyais à l'utilisation d'Ansible dans le but d'administrer une

0:26

infrastructure codifiée par mutation, c'est-à-dire en

0:29

modifiant les machines en production.

0:32

Outre les problèmes de licence et d'attaques par chaines

0:34

d'approvisionnement, l'absence de garantie d'idempotence est

0:38

centrale pour comprendre l'approche alternative :

0:41

une infrastructure immuable.

0:44

Cet épisode est consacré à présenter différentes approches

0:47

à l'immuabilité, afin de mieux en cerner l'intérêt.

0:52

Mais tout d'abord : qu'est-ce qu'une infrastructure immuable ?

0:55

Il s'agit d'une infrastructure composée de serveurs immuables.

0:59

Bon, heu... en disant cela, on n'a pas fait beaucoup avancer le

1:03

schmilblick. Donc, qu'est-ce qu'un serveur immuable ?

1:07

Il s'agit d'un serveur qui applique le principe de sécurité

1:11

W xor X, c'est-à-dire qu'une donnée ne peut être

1:15

qu'inscriptible ou exécutable, mais jamais les deux

1:18

en même temps.

1:20

La démarche W xor X implique d'identifier et de séparer

1:25

le code, d'une part, et les données manipulées par les applications,

1:28

d'autre part.

1:30

Ainsi, les serveurs immuables font tourner du code qui ne peut

1:35

ou n'est pas censé être modifié.

1:38

Pas d'ajout de logiciel, pas de mise à jour, pas de corruption.

1:43

Rien.

1:44

Si un serveur immuable a besoin de faire l'une de ces

1:47

opérations, il faut passer par un mode opératoire qui est

1:51

spécifique à chaque manière d'implémenter l'immuabilité.

1:55

Généralement, cela implique un redémarrage de la machine,

1:59

voire la machine est détruite et remplacée par une nouvelle,

2:02

contenant les modifications désirées.

2:05

Ce mode opératoire peut vous sembler familier si vous

2:08

travaillez régulièrement avec des conteneurs.

2:11

Lorsqu'on veut modifier un conteneur, on fabrique une

2:14

nouvelle image.

2:15

Ensuite, on arrête le conteneur précédent et on démarre un

2:19

nouveau conteneur faisant tourner la nouvelle image.

2:22

Un serveur immuable peut donc ressembler, en certains égards,

2:26

à des conteneurs, le noyau en plus.

2:29

D'ailleurs, certaines approches à l'immuabilité

2:32

sont précisément cela.

2:34

Ce mode opératoire a déjà fait ses preuves avec les conteneurs,

2:39

apportant une meilleure reproductibilité des

2:41

déploiements, une meilleure auditabilité et facilitant les

2:46

retours en arrière.

2:48

Les serveurs immuables sont le pendant des conteneurs, mais à

2:52

l'échelle du système d'exploitation complet.

2:55

Mais voyons justement différentes approches à

2:56

l'immuabilité, afin de rendre les choses un peu concrètes et

2:59

pragmatiques.

3:01

L'immuabilité est devenue un terme à la mode, notamment grâce

3:05

au tao de Hashicorp qui l'érige au rang de principe fondamental.

3:11

De nombreuses entreprises ont donc franchi le pas vers des

3:13

formes d'immuabilité.

3:16

Certaines ont des garanties de sécurité ou de stabilité plus

3:20

fortes que d'autres.

3:22

L'approche immuable la plus faible est conventionnelle.

3:26

C'est-à-dire qu'il n'existe aucun moyen technique pour

3:28

forcer l'immuabilité ; c'est une convention.

3:33

Avec cette approche, nous ne sommes pas censé.es effectuer de

3:37

modification en se connectant aux serveurs, que ce soit

3:40

manuellement ou avec des outils de configuration.

3:44

À la place, nous concevons une nouvelle image système, et

3:48

réinstallons la machine à partir de cette image.

3:53

Néanmoins, rien ne nous empêche réellement de nous connecter à

3:56

une machine et d'effectuer une modification.

3:59

Cette modification serait éphémère et perdue la prochaine

4:04

fois que la procédure conventionnelle de modification

4:06

sera utilisée.

4:08

Cette approche présente l'avantage d'être extrêmement

4:11

simple à mettre en œuvre.

4:13

Nul besoin d'adopter une distribution Linux atypique

4:16

ou de nouveaux outils.

4:18

Les images peuvent être créées à l'aide d'outils DevOps assez

4:22

classiques, comme Packer ou mkosi.

4:27

Pour rappel, Packer vise à dériver une image système

4:30

afin d'en former une nouvelle.

4:32

mkosi permet de créer des images de toutes pièces

4:36

pour différentes distributions Linux.

4:39

Nous reviendrons plus tard sur cet outil, puisqu'il est aussi

4:41

utilisé pour les formes les plus fortes de l'immuabilité.

4:46

Il est ainsi possible de créer une image très générique, et

4:50

d'y installer tous les outils, scripts et fichiers de

4:54

configuration dont le serveur aura besoin.

4:57

Le résultat forme alors notre "golden image", c'est-à-dire

5:01

l'image système prête à l'emploi et à laquelle il ne sera plus

5:05

nécessaire de faire des modifications.

5:08

Un des défauts de cette approche est que le système n'est pas

5:11

vraiment immuable.

5:14

Il ne l'est qu'aux yeux de ses administrateurs

5:16

et administratrices.

5:18

Le système lui-même est en mesure de se modifier, y compris

5:22

si des logiciels sont compromis.

5:24

L'immuabilité conventionnelle n'a donc aucun apport de

5:27

sécurité particulier, en dehors de réduire la durée de la

5:31

persistance d'un attaquant ou d'une attaquante

5:33

dans le système.

5:35

Néanmoins, d'un point de vue DevOps, cette approche de

5:38

l'immuabilité offre déjà d'excellents avantages.

5:42

Les "golden images" sont des artefacts finaux.

5:46

Une fois construits, ils peuvent être déployés à l'identique en

5:50

développement, en préproduction et en production.

5:54

Il est donc possible de créer des circuits de tests et de

5:57

promotion de l'image.

5:59

Cette approche facilite aussi le déploiement de N instances

6:02

identiques, puisque c'est toujours la même image

6:05

qui est utilisée.

6:07

En outre, si une nouvelle image déployée présente un problème,

6:11

le retour en arrière à une version fonctionnelle se résume

6:14

à faire démarrer le serveur sur une version

6:16

précédente de l'image.

6:18

On peut donc conclure que cette approche est déjà intéressante

6:22

pour le DevOps, mais pas spécialement pour le SecDevOps.

6:27

Pour améliorer les choses, notamment la sécurité, on peut

6:32

tourner le regard vers des distributions Linux

6:34

en lecture seule.

6:36

Ces distributions visent à permettre le déploiement et

6:39

l'administration de systèmes dont les partitions contenant du

6:43

code sont montées en lecture seule dès le démarrage.

6:47

Avec ces distributions, les modifications s'effectuent

6:50

avant le démarrage.

6:53

Avec NixOS, le nouveau système est installé et configuré

6:57

avant le redémarrage.

7:00

Cela présuppose donc d'avoir un système déjà démarré, que ce

7:04

soit sur LiveCD ou depuis un système déjà installé.

7:08

Avec des distributions comme Fedora CoreOS ou openSUSE

7:11

MicroOS, le nouveau système est initialisé et configuré lors

7:16

de son premier démarrage, dans l'initramfs.

7:20

Finalement, certains systèmes, comme Kairos OS ou openSUSE

7:24

MicroOS sont configurés à chaque démarrage par Cloud Init.

7:30

Quelle que soit la distribution utilisée, les modifications

7:32

sont exprimées soit de manière déclarative,

7:35

soit de manière impérative.

7:39

La manière déclarative consiste à décrire l'état désiré du

7:42

système, et à laisser les outils interpréter ces descriptions et

7:45

effectuer les modifications.

7:48

La manière impérative consiste à faire tourner des scripts

7:51

arbitraires pour altérer le système.

7:54

Un exemple de manière déclarative est l'outil

7:57

Ignition. Ce dernier est intégré aux distributions Fedora

8:01

CoreOS, openSUSE MicroOS et Flatcar.

8:06

Avec Ignition, on écrit des fichiers JSON décrivant les

8:10

disques, les partitions, les systèmes de fichiers, les

8:13

répertoires à créer et les fichiers à copier, les

8:16

utilisateurs à initialiser, etc.

8:19

Pendant le premier démarrage de la machine, ce fichier est

8:22

consommé par Ignition qui s'exécute dans l'initramfs.

8:27

Le fichier peut être récupéré sur le réseau, sur un point de

8:31

montage ou intégré dans un fichier ISO personnalisé

8:34

de la distribution Linux.

8:37

En cas de modification de la configuration, on réinstalle la

8:41

machine, et la nouvelle configuration sera appliquée

8:44

lors du premier démarrage suivant la réinstallation.

8:48

Pour la manière impérative, on peut citer l'outil Combustion,

8:52

qui est utilisé par openSUSE MicroOS.

8:56

Ce dernier exécute, lors de l'initramfs du premier

8:59

démarrage, un script arbitraire.

9:02

À titre personnel, je considère que la manière déclarative est

9:07

préférable à la méthode impérative. J'admets volontiers

9:11

que la méthode impérative est plus flexible

9:14

et permet de tout faire.

9:16

Néanmoins, nous nous retrouvons alors individuellement

9:19

responsables des bugs et problèmes de sécurité éventuels

9:23

des scripts que nous avons développés.

9:26

En comparaison, l'approche déclarative repose sur un outil

9:30

commun dont nous sommes toutes et tous

9:32

collectivement responsables.

9:35

Cela permet de mutualiser les efforts, de bénéficier

9:38

collectivement des correctifs et améliorations proposées par

9:41

la communauté, tout en rendant abstraits les détails

9:45

d'implémentation qui peuvent varier dans le temps.

9:48

Dans le cas d'openSUSE MicroOS qui propose les approches

9:51

déclaratives avec ignition et cloud-init, je pense que

9:55

l'approche d'ignition est à la fois plus

9:57

simple et plus puissante.

10:00

Cloud-init s'exécute pendant le démarrage du système

10:03

d'exploitation, en plusieurs fois, à l'aide de différents

10:05

services systèmes.

10:08

Cela lui permet d'effectuer des actions une fois le réseau

10:10

obtenu ou une fois tous les services système démarrés.

10:14

Néanmoins, cela occasionne des complexités liés à

10:17

l'ordonnancement des actions. Par exemple, les fichiers sont

10:20

écrits sur le système de fichiers très tôt ; tellement

10:24

tôt que l'initialisation et le montage de nouvelles partitions

10:27

se fait ultérieurement.

10:29

Créer un fichier dans une nouvelle partition, mais avant

10:32

qu'un service spécifique ne se lance est un casse-tête.

10:37

Ignition s'exécute dans l'initramfs, avant que le

10:40

système d'exploitation ne démarre. Il est donc libre de

10:44

faire toutes les modifications qu'il souhaite, sans avoir à

10:47

réfléchir à l'état d'avancement du démarrage.

10:51

Et s'il a besoin d'intercaler des opérations pendant le

10:54

démarrage du système, il lui suffit d'ajouter des

10:57

services systemd.

11:00

Outre cette philosophie de configuration précédant ou

11:02

intervenant lors du démarrage, la plupart de ces distributions

11:07

intègrent des mécanismes d'installation de mises à jour

11:10

et de retour en arrière sophistiqués.

11:13

Comme les systèmes sont en lecture seule, les mises à jour

11:16

ne s'effectuent pas par altération du système. Elles

11:20

nécessitent un redémarrage afin de terminer tous les processus

11:23

anciens, et redémarrer tous les processus depuis le système

11:27

de fichiers mis à jour.

11:30

La préparation de cette mise à jour varie suivant la

11:33

distribution Linux.

11:35

MicroOS de openSUSE utilise le mécanisme de snapshots

11:40

du système de fichiers BTRFS.

11:43

Les mises à jour sont faites dans un nouveau snapshot, dérivé

11:46

du système actuellement en cours d'exécution, et qui est monté

11:50

avec l'autorisation en écriture.

11:53

Une fois l'ensemble des mises à jour et modifications faites,

11:56

ce snapshot est marqué en lecture seule, et le système est

11:59

redémarré pour utiliser ces napshot

12:01

comme son système de fichiers.

12:04

Pour revenir en arrière sur une modification cassante du

12:06

système, il suffit de faire démarrer la machine sur

12:10

le précédent snapshot.

12:12

Fedora CoreOS utilise une autre méthode reposant sur rpm-ostree.

12:19

Ostree est un peu l'équivalent de l'outil de versionnement git,

12:22

mais à l'échelle d'un système de fichiers.

12:25

Lorsqu'on veut faire une modification, comme

12:27

l'installation ou la mise à jour d'un programme, on ajoute un

12:31

commit à Ostree contenant ces modifications.

12:35

Lors du prochain démarrage, c'est ce nouveau commit qui est

12:38

utilisé et démarré. Pour cela, Ostree créé des hardlinks entre

12:43

les fichiers contenus dans le dépôt Ostree

12:46

et l'arborescence /usr.

12:49

Un retour en arrière consiste simplement à démarrer sur un

12:52

commit précédent.

12:54

D'un point de vue sécurité, le fait que le système

12:57

d'exploitation démarre avec ses partitions de code en lecture

13:00

seule semble à première vue améliorer nettement la sécurité.

13:05

Cela prévient certainement les modifications accidentelles.

13:09

Cela ne prévient cependant pas les modifications malveillantes.

13:13

Linux ne dispose de mécanismes de verrouillage du système, à

13:17

l'instar des niveaux de sécurité d'OpenBSD, qui empêchent de

13:21

remonter en écriture des partitions montées en

13:24

lecture seule.

13:26

Il est certes possible d'inhiber l'appel système mount avec

13:30

des Linux Security Modules ou seccomp-bpf, mais un processus

13:35

root non limité pourra tout de même effectuer ces

13:37

modifications.

13:39

Les développeurs d'Ostree travaillent sur un outil appelé

13:42

composefs qui ajoute du contrôle d'intégrité, grâce à

13:46

FS-Verity et des signatures cryptographiques sur les

13:49

fichiers gérés par Ostree.

13:52

Les développeurs d'Ostree travaillent notamment sur BootC,

13:55

qui est une nouvelle manière de déployer des systèmes

13:57

immuables, distribués sous la forme d'images OCI.

14:01

BootC utilise notamment composefs.

14:05

Il existe également des travaux pour combiner Linux Integrity

14:08

Measurement Architecture à Ostree, pour arriver à des fins

14:12

similaires.

14:14

Néanmoins, ces preuves cryptographiques sont en cours

14:17

d'intégration et en leur absence, l'immuabilité des

14:20

systèmes de fichiers de ces distributions n'est que

14:23

marginalement meilleure que celle des systèmes utilisant

14:26

une immuabilité conventionnelle.

14:28

Ce que ces distributions ont pour elles, en revanche, est une

14:31

excellente reproductibilité des déploiements, notamment si

14:35

l'on s'en tient à l'approche déclarative de la configuration,

14:38

ainsi que des processus de mises à jour et de retour en

14:41

arrière efficace et faciles à mettre en œuvre.

14:45

Pour ces raisons, Fedora CoreOS est parmi mes systèmes

14:49

d'exploitation favoris. Il est notamment utilisé pour héberger

14:52

ce podcast.

14:54

Mais est-il possible de faire mieux ? Peut-on concevoir des

14:58

systèmes apportant une réelle immuabilité avec des assurances

15:03

cryptographiques ?

15:05

La réponse est oui, et il est assez probable que les auditeurs

15:08

et auditrices soient en train d'utiliser un tel système pour

15:11

écouter ce podcast.

15:13

Android est un système d'exploitation dont

15:16

l'immuabilité est assurée par des vérifications de preuves

15:19

cryptographiques. C'est également le cas de Flatcar.

15:23

Pour cela, ces systèmes d'exploitation utilisent des

15:26

images de systèmes de fichiers, dont l'intégrité est vérifiée

15:30

avec dm-verity.

15:33

dm-verity est une fonctionnalité du noyau Linux qui vérifie en

15:37

direct et à chaque accès que les blocs d'un périphérique de

15:41

blocs, typiquement un disque dur, sont intègres.

15:45

S'ils ne le sont pas, la lecture de ce bloc est bloquée.

15:50

Grâce à cette approche, il n'est pas possible, même pour un

15:54

attaquant, de modifier le système de fichiers.

15:58

La contrepartie est que les modifications légitimes comme

16:01

les mises à jour ou l'installation de nouveaux logiciels

16:04

sont rendues relativement complexes.

16:07

En effet, puisque l'intégrité cryptographique couvre

16:11

l'ensemble du périphérique de bloc, il n'est pas aisé de

16:14

remplacer uniquement un seul ou quelques fichiers.

16:19

La solution la plus simple est de régénérer l'image en

16:21

intégralité.

16:23

Il existe d'autres méthodes, comme des diffs binaires ou

16:27

l'utilisation de couches à l'instar de ce qui est fait avec

16:30

OverlayFS pour les conteneurs.

16:34

Systemd est très actif dans l'écosystème des images Linux et

16:37

il propose de nombreux outils qui vont dans ce sens.

16:40

Ainsi, Systemd utilise des options de la ligne de commande

16:44

de démarrage du noyau pour spécifier les options

16:47

nécessaires pour dm-verity.

16:50

De même, Systemd gère des sysext ou system extensions, qui

16:56

sont une implémentation de couches permettant de faire de

16:59

l'ajout ou du remplacement de fichiers par superposition

17:02

d'images.

17:03

Il peut notamment être utilisé par les consoles SteamDeck pour

17:08

étendre le système quand l'installation d'applications de

17:11

manière non privilégiée, sous la forme de Flatpaks,

17:14

ne suffit pas.

17:16

Les system extensions peuvent être générées de plein de

17:19

manières différentes, mais un outil, lui aussi fourni par

17:22

l'écosystème Systemd mérite d'être mentionné : mkosi.

17:28

Nous en avons déjà parlé il y a quelques minutes pour la

17:30

conception d'images.

17:32

mkosi peut fabriquer autant des images système pour le système

17:36

entier, que pour des system extensions.

17:40

Il permet de faire des images reproductibles (sous certaines

17:43

conditions), et gère nativement dm-verity et même les

17:47

signatures pour Secure Boot.

17:49

Il trouve donc sa place autant dans l'escarcelle de personnes

17:52

voulant faire de l'immuabilité conventionnelle que dans celle

17:55

de personnes souhaitant mettre en oeuvre la forme

17:57

d'immuabilité la plus forte.

18:00

Voilà ! Je ne pense pas avoir fait le tour des systèmes

18:03

immuables. Tant s'en faut.

18:05

Néanmoins, j'imagine que cet épisode pourra servir de

18:08

première introduction.

18:10

Pour les auditeurs et les auditrices souhaitant en savoir

18:13

plus, je ne peux que recommander d'écouter les nombreuses

18:16

conférences sur ce sujet.

18:18

Je pense notamment à la salle Image-based Linux de FOSDEM

18:22

2023 ou à la conférence All Systems Go!.

18:27

Je n'ai aucun doute que l'immuabilité sera un élément

18:29

central de la sécurité système de la prochaine décennie.

18:33

C'est d'autant plus vrai que Secure Boot commence

18:36

à montrer ses limites.

18:37

J'ai d'ailleurs écrit un article à ce sujet dans MISC où je

18:41

fustigeais la recommandation de l'ANSSI relative à Secure Boot

18:44

dans son guide Linux.

18:47

Or, une roue de secours pour le démarrage sécurisé, après que

18:51

Secure Boot se soit révélé un tuyau percé, est l'emploi des

18:54

TPM, qui se trouvent être très friands des systèmes immuables,

18:58

puisqu'ayant toujours la même empreinte cryptographique !

19:01

Pour ma part, les systèmes d'exploitation immuable sont

19:04

dans mes pratiques SecDevOps depuis maintenant

19:07

de nombreuses années.

19:09

Chez la plupart de mes clients, je rencontre une légère

19:12

résistance à passer à des distributions Linux spécialisées

19:15

comme Fedora CoreOS ou Flatcar par appréhension d'avoir des

19:19

difficultés de recrutement.

19:21

J'arrive néanmoins assez facilement à les convaincre

19:24

d'utiliser au moins l'approche de l'immuabilité

19:26

conventionnelle, qui offre déjà des avantages assez nets de

19:30

reproductibilité des déploiements et d'auditabilité.

19:33

L'utilisation d'outils de configuration déclarative comme

19:36

cloud-init reste cependant une souffrance du quotidien,

19:40

comparé à Ignition.

19:42

De même, les mises à jour et les retours en arrière dans le

19:46

cas de l'immuabilité conventionnelle sont moins aisés qu'avec

19:50

des distributions conçues pour.

19:52

J'aspire à ce que ces distributions deviennent plus

19:55

présentes, et que les habitudes DevOps évoluent vers elles,

19:58

afin qu'elles puissent se départir des quelques verrues

20:01

violant le principe W xor X qui persistent encore.

20:05

J'espère donc vous avoir peut-être fait découvrir, ou

20:08

mieux, vous avoir convaincu d'adopter l'approche immuable !

20:12

Si c'est le cas, je vous conseille d'essayer Fedora Core

20:15

OS, plus facile, ou Flatcar, plus immuable, qui sont deux

20:19

superbes distributions.

20:21

Dans le prochain épisode, nous verrons que cette approche

20:24

comporte cependant quelques défis inattendus.

20:27

Un que je n'avais pas anticipé lorsque j'ai emprunté cette voie

20:30

est la gestion des secrets !

20:32

En effet, les gestionnaires de configuration par mutation sont

20:36

souvent utilisés pour déployer des secrets qu'ils stockent sous

20:38

une forme chiffrée dans le gestionnaire de version de code.

20:42

Or, avec l'approche immuable, on ne se connecte pas ou peu sur

20:46

les machines, puisqu'il n'est pas nécessaire de les modifier !

20:49

Aller, je ne vous en dis pas plus ; cet épisode est déjà bien

20:52

assez long !

20:53

Comme à chaque fois, je vous rappelle que vous pouvez

20:56

commenter, liker et même booster ce podcast sur le fédiverse.

21:01

Il vous suffit de copier/coller l'adresse de cet épisode dans

21:04

le champ de recherche de votre logiciel, puis d'interagir avec

21:06

le post.

21:08

N'hésitez pas à me dire si cet épisode vous a plu, ou à

21:11

apporter une critique constructive !

21:13

À bientôt !