1 00:00:00,000 --> 00:00:03,760 Les ops règnent-ils en divinité sur leur système d'information ? 2 00:00:04,230 --> 00:00:07,860 Doivent-ils et elles pouvoir tout faire et tout connaitre ? 3 00:00:08,920 --> 00:00:11,480 Avec la généralisation du chiffrement de bout en bout, 4 00:00:11,710 --> 00:00:15,980 l'omniscience en a déjà pris un coup. Mais est-il nécessaire que 5 00:00:15,980 --> 00:00:19,990 les ops aient accès à un seul secret sur l’ensemble de leur 6 00:00:19,990 --> 00:00:21,580 système d’information ? 7 00:00:21,800 --> 00:00:24,280 Peut-on imaginer un système d'information sans que le 8 00:00:24,280 --> 00:00:28,550 moindre secret soit connu des ops ? Est-ce souhaitable ou même 9 00:00:28,550 --> 00:00:30,220 possible ? 10 00:00:30,290 --> 00:00:32,500 Je vais vous démontrer que cette approche est effectivement 11 00:00:32,500 --> 00:00:35,500 possible, automatisable, pragmatique et désirable. 12 00:00:36,070 --> 00:00:39,400 Bienvenue dans ce troisième épisode du podcast Yakafokon ! 13 00:00:39,400 --> 00:00:51,320 [Musique d'introduction] 14 00:00:51,320 --> 00:00:54,180 Nombreux sont les outils du DevOps qui permettent la 15 00:00:54,180 --> 00:00:56,040 manipulation des secrets. 16 00:00:56,200 --> 00:00:58,640 Il y a bien sûr les gestionnaires de secrets, comme 17 00:00:58,640 --> 00:01:01,590 Hashicorp Vault, OpenBao, Conjur, 18 00:01:01,590 --> 00:01:04,070 ou Bitwarden Secret Manager. 19 00:01:04,360 --> 00:01:06,830 Les secrets peuvent également être stockés dans la 20 00:01:06,830 --> 00:01:09,450 configuration, avec Ansible Vault 21 00:01:09,840 --> 00:01:11,670 ou autres databags chiffrés. 22 00:01:12,420 --> 00:01:15,510 Les plus téméraires peuvent même les stocker dans l'état 23 00:01:15,510 --> 00:01:18,160 d'outils, tels que Terraform ou OpenTofu. 24 00:01:18,980 --> 00:01:22,270 Pourtant, aucune de ces solutions n'est satisfaisante. 25 00:01:22,850 --> 00:01:27,180 Toutes impliquent directement ou indirectement que des ops aient 26 00:01:27,180 --> 00:01:28,680 accès à des secrets. 27 00:01:28,900 --> 00:01:33,210 Or, l'accès aux secrets devrait être accordé aux seuls acteurs 28 00:01:33,210 --> 00:01:35,560 en ayant le besoin fonctionnel. 29 00:01:35,560 --> 00:01:38,560 C'est ce qu'on appelle le besoin d'en connaitre. 30 00:01:39,140 --> 00:01:42,200 Dans un système d'information, ce sont les logiciels qui ont le 31 00:01:42,200 --> 00:01:45,690 besoin fonctionnel de ces secrets ; pour s'authentifier, 32 00:01:45,690 --> 00:01:46,530 pour signer des documents, 33 00:01:46,530 --> 00:01:48,720 pour déchiffrer des communications, etc. 34 00:01:49,570 --> 00:01:53,200 La problématique est donc de réussir à fournir aux logiciels 35 00:01:53,200 --> 00:01:56,680 les secrets dont ils ont besoin sans pour autant que les ops 36 00:01:56,680 --> 00:01:58,030 les connaissent. 37 00:01:58,490 --> 00:02:00,330 Ce n'est pas seulement le respect d'un principe de 38 00:02:00,330 --> 00:02:03,100 sécurité que de chercher à ce que les ops n'aient pas accès 39 00:02:03,100 --> 00:02:07,210 aux secrets. C'est aussi un problème très pragmatique lié à 40 00:02:07,210 --> 00:02:09,430 la gestion du cycle de vie des secrets. 41 00:02:09,900 --> 00:02:13,670 Lorsqu’un ou une ops perd son rôle, que ce soit par démission, 42 00:02:13,850 --> 00:02:16,190 changement d’équipe ou tout autre événement, il est 43 00:02:16,190 --> 00:02:19,190 nécessaire de révoquer et de remplacer tous les secrets en 44 00:02:19,190 --> 00:02:22,190 cours d’usage auxquels cette personne a pu avoir accès. 45 00:02:23,260 --> 00:02:25,480 Cela veut dire qu'il faut être en mesure de lister les secrets 46 00:02:25,480 --> 00:02:29,230 concernés, et de les changer, sans perturber la production ! 47 00:02:30,190 --> 00:02:33,150 En théorie, c’est une chose facile à faire, ou en tout cas 48 00:02:33,150 --> 00:02:35,800 automatisable, grâce aux outils d’infrastructure codifiée 49 00:02:35,800 --> 00:02:37,360 ou aux gestionnaires de secrets. 50 00:02:37,360 --> 00:02:40,820 Ces solutions présentent cependant toutes des problèmes, 51 00:02:40,820 --> 00:02:42,640 que nous allons étudier un à un. 52 00:02:43,280 --> 00:02:46,890 Pour commencer, parlons d’outils de configuration codifiée, comme 53 00:02:46,890 --> 00:02:50,750 Ansible Vault et Chef. Si vous ne les utilisez pas, c'est le 54 00:02:50,750 --> 00:02:53,050 moment de rappeler que ce podcast est chapitré ; vous 55 00:02:53,050 --> 00:02:54,680 pouvez sauter à la section suivante ! 56 00:02:54,920 --> 00:02:57,610 Ansible Vault et Chef utilisent tous deux des clés 57 00:02:57,610 --> 00:03:00,030 cryptographiques symétriques pour chiffrer les données 58 00:03:00,030 --> 00:03:03,370 sensibles. Pour Ansible Vault, le secret symétrique est calculé 59 00:03:03,370 --> 00:03:05,880 à partir d'un mot de passe. Pour simplifier, à partir de 60 00:03:05,880 --> 00:03:08,790 maintenant, je parlerai juste de clé symétrique, même pour les 61 00:03:08,790 --> 00:03:09,630 mots de passe. 62 00:03:09,850 --> 00:03:12,420 L'ops qui connait cette clé symétrique a donc accès à 63 00:03:12,420 --> 00:03:15,990 l'ensemble des données sensibles chiffrées par cette clé. Lors de 64 00:03:15,990 --> 00:03:18,710 son départ, il est donc nécessaire de renouveler non 65 00:03:18,710 --> 00:03:21,150 seulement cette clé symétrique, mais aussi toutes les données 66 00:03:21,150 --> 00:03:23,070 sensibles chiffrées avec cette clé. 67 00:03:23,380 --> 00:03:25,660 Le remplacement de toutes ces données sensibles peut être 68 00:03:25,660 --> 00:03:28,450 fastidieux, mais surtout, cela peut perturber la production ! 69 00:03:28,730 --> 00:03:31,150 Que se passe-t-il si je change le mot de passe permettant 70 00:03:31,150 --> 00:03:33,700 à mon application web de se connecter à la base de données ? 71 00:03:34,130 --> 00:03:36,390 Que se passe-t-il si je change la clé privée associée au 72 00:03:36,390 --> 00:03:38,410 certificat TLS protégeant un serveur web ? 73 00:03:39,050 --> 00:03:41,130 Dans tous ces cas, il va falloir préparer une fenêtre de 74 00:03:41,130 --> 00:03:43,840 maintenance, et la mise en production du nouveau secret. 75 00:03:44,400 --> 00:03:47,100 Avec de la chance, ça se passera bien... ou pas. 76 00:03:47,710 --> 00:03:50,240 Mais bon, l'auditoire fidèle se souviendra que, dans le premier 77 00:03:50,240 --> 00:03:53,840 épisode de ce podcast, on avait déjà écarté Ansible pour des 78 00:03:53,840 --> 00:03:54,790 raisons de sécurité. 79 00:03:55,070 --> 00:03:57,570 Si les outils de configuration codifiée ne sont pas terribles, 80 00:03:57,570 --> 00:03:59,650 peut-être que les outils d'infrastructure codifiée sont 81 00:03:59,650 --> 00:04:00,600 meilleurs ? 82 00:04:00,760 --> 00:04:03,600 En infrastructure codifiée, je vais essentiellement parler de 83 00:04:03,600 --> 00:04:05,320 Terraform et d'OpenTofu. 84 00:04:06,070 --> 00:04:08,630 Je ne parle pas d'OpenTofu uniquement pour des histoires de 85 00:04:08,630 --> 00:04:12,220 licence libre. Certes, les deux ont des bases très communes, 86 00:04:12,220 --> 00:04:15,320 mais OpenTofu a réellement une approche différente de celle de 87 00:04:15,320 --> 00:04:16,150 Terraform. 88 00:04:16,840 --> 00:04:19,750 Terraform et OpenTofu sont tous deux des outils fonctionnant sur 89 00:04:19,750 --> 00:04:22,960 le principe d'une machine à états. Chaque donnée, chaque 90 00:04:22,960 --> 00:04:25,770 ressource qu'ils manipulent sont stockées dans une base de 91 00:04:25,770 --> 00:04:27,550 données qu'on appelle l'état. 92 00:04:28,040 --> 00:04:30,760 Lorsque des changements sont codés dans la configuration de 93 00:04:30,760 --> 00:04:33,880 ces outils, ces changements sont comparés avec les informations 94 00:04:33,880 --> 00:04:36,850 de l'état, et des opérations sont entreprises afin de 95 00:04:36,850 --> 00:04:39,230 réconcilier la configuration et l'état. 96 00:04:39,840 --> 00:04:43,210 Terraform et OpenTofu peuvent manipuler des secrets. Par 97 00:04:43,210 --> 00:04:45,530 exemple, ils peuvent être utilisés pour créer des clés 98 00:04:45,530 --> 00:04:49,030 TLS, des clés SSH, des mots de passe temporaire, etc. 99 00:04:49,630 --> 00:04:52,330 Ces secrets finissent dans l'état, et l'état est stocké 100 00:04:52,330 --> 00:04:55,730 clair sur le disque dur ou dans une base de données distante. 101 00:04:56,400 --> 00:04:58,780 Parfois, cette base de données est chiffrée par le serveur ; 102 00:04:59,190 --> 00:05:02,160 parfois pas. Comme c'est fait côté serveur, on n'en sait 103 00:05:02,160 --> 00:05:03,190 réellement rien. 104 00:05:03,370 --> 00:05:06,250 Donc, pour le dire plus directement, quand on manipule 105 00:05:06,250 --> 00:05:08,760 des ressources ou des sources de données sensibles avec 106 00:05:08,760 --> 00:05:12,510 Terraform, on stocke des secrets en clair, à poil, sans 107 00:05:12,510 --> 00:05:14,070 protection. Aie ! 108 00:05:14,770 --> 00:05:18,380 Mais, j'ai dit "avec Terraform". C'est différent avec OpenTofu ? 109 00:05:18,940 --> 00:05:21,290 Eh bien, oui ! Et c'est probablement l'une des premières 110 00:05:21,290 --> 00:05:24,290 fonctionnalités vraiment importantes qui diffère entre 111 00:05:24,290 --> 00:05:26,250 Terraform et OpenTofu ! 112 00:05:26,570 --> 00:05:29,120 OpenTofu a introduit la possibilité de chiffrer l'état 113 00:05:29,120 --> 00:05:32,550 côté client avant le stockage sur disque dur ou dans une base 114 00:05:32,550 --> 00:05:33,460 de données distante. 115 00:05:34,010 --> 00:05:37,130 Pour chiffrer, on utilise une clé dérivée d'un mot de passe. 116 00:05:37,850 --> 00:05:41,240 Ce mot de passe est demandé à chaque exécution d'OpenTofu pour 117 00:05:41,240 --> 00:05:43,950 déchiffrer l'état, le modifier et le rechiffrer. 118 00:05:44,410 --> 00:05:47,010 À première vue, cela semble formidable de pouvoir enfin 119 00:05:47,010 --> 00:05:50,760 chiffrer l'état. Mais, en réalité, c'est le même problème 120 00:05:50,760 --> 00:05:52,670 qu'avec les outils de configuration codifiés qu'on 121 00:05:52,670 --> 00:05:53,850 vient juste de discuter. 122 00:05:54,110 --> 00:05:57,130 Une personne connaissant le mot de passe a accès à tous les 123 00:05:57,130 --> 00:06:00,080 secrets contenus dans l'état. Lorsque cette personne perd le 124 00:06:00,080 --> 00:06:02,610 besoin de connaitre ces secrets, il faut changer tous les 125 00:06:02,610 --> 00:06:05,820 secrets, et rechiffrer l'état avec un nouveau mot de passe. 126 00:06:06,400 --> 00:06:08,890 Hashicorp a bien identifié ce problème et a toujours refusé 127 00:06:08,890 --> 00:06:11,640 d'implémenter ce type de chiffrement. Néanmoins, une 128 00:06:11,640 --> 00:06:15,260 révolution a eu lieu avec la sortie de Terraform v1.10. 129 00:06:15,770 --> 00:06:19,290 Terraform v1.10 introduit la notion de ressources et de 130 00:06:19,290 --> 00:06:20,550 variables éphémères. 131 00:06:21,200 --> 00:06:24,200 Les ressources éphémères sont des ressources qui ne sont pas 132 00:06:24,200 --> 00:06:27,280 stockées dans l'état. Elles ont un cycle de vie différent des 133 00:06:27,280 --> 00:06:29,520 autres ressources, et les opérations qui peuvent être 134 00:06:29,520 --> 00:06:32,210 effectuées sur ces dernières sont plus limitées. 135 00:06:32,730 --> 00:06:35,400 Les valeurs des ressources éphémères ne peuvent notamment 136 00:06:35,400 --> 00:06:38,060 être utilisées que dans d'autres ressources éphémères 137 00:06:38,060 --> 00:06:39,250 ou dans des provisionneurs. 138 00:06:40,120 --> 00:06:42,840 Avec ces ressources, il est possible de générer et manipuler 139 00:06:42,840 --> 00:06:46,280 des secrets sans que l'état les stocke et que les ops ne 140 00:06:46,280 --> 00:06:47,470 puissent les apprendre. 141 00:06:48,330 --> 00:06:52,080 AWS, GCP et Azure ont tous déjà implémenté des ressources 142 00:06:52,080 --> 00:06:55,210 éphémères pour leurs KMS ou Key Management System. 143 00:06:56,030 --> 00:06:58,220 Il ne reste plus que la problématique de la diffusion de 144 00:06:58,220 --> 00:07:00,440 ces secrets aux logiciels ayant le besoin d'en connaitre ! 145 00:07:01,260 --> 00:07:03,720 Les diffuser par un provisionneur SSH est possible, 146 00:07:04,000 --> 00:07:07,870 mais... Dans une infrastructure immuable, se connecter en SSH 147 00:07:07,870 --> 00:07:10,940 aux machines est un contresens, comme discuté dans l'épisode 2 148 00:07:10,940 --> 00:07:11,800 de ce podcast. 149 00:07:12,490 --> 00:07:16,190 De surcroit, la connexion d'un provisionneur à une machine via 150 00:07:16,190 --> 00:07:19,290 SSH n'est pas sécurisée, car l'empreinte de la clé SSH du 151 00:07:19,290 --> 00:07:22,290 serveur n'est généralement pas vérifiée ou obtenue de façon 152 00:07:22,290 --> 00:07:25,680 intègre. Sans cela, difficile de dire si la clé n'a pas été 153 00:07:25,680 --> 00:07:27,270 compromise lors de son transfert ! 154 00:07:28,150 --> 00:07:30,630 Bon, en vrai, on peut imaginer quelques moyens de faire cette 155 00:07:30,630 --> 00:07:33,960 connexion SSH en toute sécurité, à l'aide de l'hyperviseur et de 156 00:07:33,960 --> 00:07:38,210 sockets de type AF_VSOCK, mais c'est un sujet assez avancé ; on 157 00:07:38,210 --> 00:07:40,150 pourra en reparler dans un futur épisode ! 158 00:07:40,150 --> 00:07:43,720 Diffuser les secrets par Cloud-init ou Ignition n'est pas 159 00:07:43,720 --> 00:07:44,910 non plus une bonne idée. 160 00:07:45,520 --> 00:07:48,190 Ignition, déjà présenté dans l'épisode sur l'infrastructure 161 00:07:48,190 --> 00:07:51,610 immuable, n'est pas censé contenir de secrets, comme le 162 00:07:51,610 --> 00:07:54,610 dit sa spécification, et rien n'est donc fait pour préserver 163 00:07:54,610 --> 00:07:57,610 la confidentialité des données qu'on met dans sa configuration. 164 00:07:57,960 --> 00:08:00,760 Mais au moins, avec Ignition, les choses sont claires. 165 00:08:01,720 --> 00:08:04,970 On ne peut pas en dire autant de Cloud-Init, qui ne dit rien à ce 166 00:08:04,970 --> 00:08:07,530 sujet et pousse donc clairement au crime. 167 00:08:08,650 --> 00:08:11,270 En réalité, et pour apporter un peu de nuances, le niveau de 168 00:08:11,270 --> 00:08:13,790 sécurité de Cloud-Init varie grandement en fonction des 169 00:08:13,790 --> 00:08:15,270 sources de données de Cloud-Init. 170 00:08:16,050 --> 00:08:18,480 Par exemple, la source de données « NoCloud », qui 171 00:08:18,480 --> 00:08:21,160 consiste à fournir les données par le biais de fichiers stockés 172 00:08:21,160 --> 00:08:24,890 sur un disque nommé CIDATA, expose toutes les données de 173 00:08:24,890 --> 00:08:27,890 configuration Cloud-Init à tous les processus du système ! 174 00:08:28,600 --> 00:08:32,150 Cloud-Init, en effet, impose que le disque CIDATA soit formaté 175 00:08:32,150 --> 00:08:36,410 soit en vfat, soit en ISO9660, et il le monte sans options de 176 00:08:36,410 --> 00:08:39,660 montage particulières. Le disque se retrouve donc monté avec les 177 00:08:39,660 --> 00:08:44,690 droits 755 et 644, donc en lecture par tous. OK, on peut 178 00:08:44,690 --> 00:08:47,690 améliorer ça avec AppArmor, mais de vous à moi, qui fait ça ? 179 00:08:48,600 --> 00:08:51,430 Ce n'est cependant pas la seule source de données peu sécurisée. 180 00:08:51,930 --> 00:08:55,690 Autre exemple : la source de données Amazon EC2. Celle-ci 181 00:08:55,690 --> 00:08:58,050 expose les données de configuration sur un service web 182 00:08:58,200 --> 00:09:02,090 accessible par une requête HTTP sur une adresse IP APIPA : 183 00:09:02,470 --> 00:09:06,630 l'adresse IP 169.254.169.254. 184 00:09:07,580 --> 00:09:09,990 N'importe quel processus de la machine peut donc effectuer une 185 00:09:09,990 --> 00:09:13,350 requête HTTP sur cette adresse pour obtenir la configuration ! 186 00:09:14,300 --> 00:09:17,450 Même en établissant une règle de pare-feu Netfilter pour 187 00:09:17,450 --> 00:09:20,080 n’autoriser l’accès à cette adresse IP que depuis un 188 00:09:20,080 --> 00:09:23,560 processus fonctionnant sous l’UID 0, on permet toujours à 189 00:09:23,560 --> 00:09:25,850 tous les processus root d’obtenir cette information. 190 00:09:26,500 --> 00:09:30,070 Or, cela va à l'encontre des travaux effectués ces quinze 191 00:09:30,070 --> 00:09:33,800 dernières années à désarmer root, avec les capabilities, les 192 00:09:33,800 --> 00:09:38,120 namespaces, seccomp-bpf, et les Linux Security Modules. Tous les 193 00:09:38,120 --> 00:09:40,960 processus tournant en root n'ont pas forcément le besoin de 194 00:09:40,960 --> 00:09:44,770 connaitre tous les secrets de chaque serveur ! Ici aussi, on 195 00:09:44,770 --> 00:09:48,210 peut améliorer ça avec SELinux, mais qui fait ça ? 196 00:09:49,240 --> 00:09:51,430 Après, je n'ai pas étudié l'ensemble des sources de 197 00:09:51,430 --> 00:09:54,070 données de Cloud-Init. Peut-être que certaines sont plus fiables 198 00:09:54,070 --> 00:09:57,000 que d'autres, mais cela élimine déjà pas mal de clouds pour 199 00:09:57,000 --> 00:09:59,240 lesquels il faudra une méthode alternative ! 200 00:09:59,950 --> 00:10:04,040 En parlant d'alternative, une a déjà été évoquée : les 201 00:10:04,040 --> 00:10:07,850 gestionnaires de secrets ou KMS, comme ceux proposés par certains 202 00:10:07,850 --> 00:10:10,750 fournisseurs de Cloud, ou auto-hébergeables, comme 203 00:10:10,750 --> 00:10:12,760 HashiCorp Vault ou OpenBao. 204 00:10:13,530 --> 00:10:16,150 Les gestionnaires de secrets permettent aux ops de stocker 205 00:10:16,150 --> 00:10:20,010 des secrets dans un logiciel. Celui-ci les distribuera ensuite 206 00:10:20,010 --> 00:10:22,300 aux autres logiciels ayant le besoin d'en connaitre. 207 00:10:22,980 --> 00:10:26,370 Immédiatement, deux problèmes sautent aux yeux. D'une part, 208 00:10:26,370 --> 00:10:29,710 les ops manipulent les secrets, et d'autre part, les logiciels 209 00:10:29,710 --> 00:10:32,490 ayant le besoin d'en connaitre doivent pouvoir s'authentifier 210 00:10:32,490 --> 00:10:35,560 auprès du gestionnaire de secrets pour avoir accès aux 211 00:10:35,560 --> 00:10:37,590 seuls secrets dont ils ont le besoin. 212 00:10:38,230 --> 00:10:41,270 Or, pour s'authentifier auprès du gestionnaire de secrets, il 213 00:10:41,270 --> 00:10:44,200 faut connaitre un secret : celui qui permet au logiciel de 214 00:10:44,200 --> 00:10:47,200 prouver qui il est ! On a donc un problème de poule et d'œuf : 215 00:10:47,360 --> 00:10:50,200 pour distribuer des secrets, il faut avoir déjà distribué un 216 00:10:50,200 --> 00:10:50,900 secret ! 217 00:10:51,290 --> 00:10:53,320 Ces deux problèmes sont contournables, mais ce n'est pas 218 00:10:53,320 --> 00:10:54,790 forcément trivial à faire. 219 00:10:55,350 --> 00:10:57,790 Pour le problème des ops manipulant les secrets, cela 220 00:10:57,790 --> 00:10:59,890 dépend de la nature du secret manipulé. 221 00:11:00,390 --> 00:11:03,730 Si c'est un secret symétrique utilisé par deux logiciels 222 00:11:03,730 --> 00:11:06,380 connectés au même gestionnaire de secrets, comme c'est le cas 223 00:11:06,380 --> 00:11:08,630 avec une application web qui se connecte à sa base de données, 224 00:11:09,430 --> 00:11:12,260 alors le gestionnaire de secrets peut aider. Il suffit au 225 00:11:12,260 --> 00:11:15,260 gestionnaire de générer lui-même le secret, et de le distribuer 226 00:11:15,260 --> 00:11:16,600 aux deux applications. 227 00:11:17,170 --> 00:11:20,140 Si c'est un secret symétrique, mais qu'un seul des logiciels 228 00:11:20,140 --> 00:11:23,080 est connecté au gestionnaire de secrets, alors il n'y a pas de 229 00:11:23,080 --> 00:11:27,000 bonne solution. Le secret passe forcément par les mains des ops. 230 00:11:27,590 --> 00:11:30,390 C'est un scénario qu'on veut absolument éviter, et la vraie 231 00:11:30,390 --> 00:11:32,820 bonne solution est de ne pas avoir recours à ce type de 232 00:11:32,820 --> 00:11:33,590 secrets. 233 00:11:34,150 --> 00:11:37,300 À la place, on peut utiliser des secrets asymétriques. 234 00:11:37,730 --> 00:11:41,130 Avec ce type de secrets, seules les clés publiques ont besoin 235 00:11:41,130 --> 00:11:44,540 d'être manipulées par les ops. Les clés privées sont générées 236 00:11:44,540 --> 00:11:47,390 directement par les logiciels ayant le besoin d'en connaitre, 237 00:11:47,700 --> 00:11:50,390 ou par les gestionnaires de secrets auxquels ils ont accès. 238 00:11:50,930 --> 00:11:52,950 Ce qui est intéressant, c'est que c'est une méthode de 239 00:11:52,950 --> 00:11:55,050 fonctionnement déjà très déployée. 240 00:11:55,690 --> 00:11:58,570 Tous les serveurs SSH fonctionnent ainsi. Quand on 241 00:11:58,570 --> 00:12:01,400 installe le package, les clés d'hôte sont générées directement 242 00:12:01,400 --> 00:12:04,670 par la machine qui fait tourner le serveur SSH. Les ops 243 00:12:04,670 --> 00:12:07,470 manipulent seulement les clés publiques d'hôtes afin de les 244 00:12:07,470 --> 00:12:10,070 mettre dans un fichier known_hosts ou dans un 245 00:12:10,070 --> 00:12:12,200 enregistrement DNS de type SSHFP. 246 00:12:13,060 --> 00:12:16,530 Un autre exemple très répandu est Let's Encrypt. Ou plus 247 00:12:16,530 --> 00:12:20,070 précisément le protocole ACME utilisé par Let's Encrypt, et 248 00:12:20,070 --> 00:12:21,980 toutes les autres autorités de certification qui font de la 249 00:12:21,980 --> 00:12:24,910 vérification en ligne automatisée en vue d'émettre des 250 00:12:24,910 --> 00:12:25,700 certificats. 251 00:12:26,230 --> 00:12:29,060 Quand on demande un certificat avec le protocole ACME, la clé 252 00:12:29,060 --> 00:12:31,980 privée est directement générée sur la machine qui demande le 253 00:12:31,980 --> 00:12:35,960 certificat. Le serveur ACME fait ensuite des vérifications pour 254 00:12:35,960 --> 00:12:38,960 s'assurer qu'il ne délivre pas un certificat à un attaquant. 255 00:12:39,630 --> 00:12:41,580 Pour cela, il s'assure que la machine qui demande le 256 00:12:41,580 --> 00:12:44,730 certificat contrôle bien le nom de domaine, ou l'adresse IP 257 00:12:44,730 --> 00:12:48,070 pointée par le nom de domaine, demandé dans le certificat. 258 00:12:49,080 --> 00:12:51,470 Après cette vérification, le serveur ACME délivre le 259 00:12:51,470 --> 00:12:53,030 certificat à la machine. 260 00:12:53,590 --> 00:12:56,650 À aucun moment dans ce processus la clé privée n'a été exposée 261 00:12:56,650 --> 00:12:59,060 aux ops ni à qui que ce soit qui n'a pas le besoin 262 00:12:59,060 --> 00:13:00,180 d'en connaitre ! 263 00:13:00,480 --> 00:13:03,410 Le protocole ACME permet donc d'obtenir un certificat qui 264 00:13:03,410 --> 00:13:06,180 associe cryptographiquement une clé publique à une identité. 265 00:13:06,760 --> 00:13:09,000 Avec ça, on peut s'authentifier auprès du gestionnaire de 266 00:13:09,000 --> 00:13:11,530 secrets. On peut même l'utiliser pour s'authentifier auprès 267 00:13:11,530 --> 00:13:13,920 de n'importe quel serveur, pour peu qu'il fasse confiance à 268 00:13:13,920 --> 00:13:16,540 l'autorité de certification qui a émis le certificat ! 269 00:13:17,120 --> 00:13:19,710 Grâce au protocole ACME, tout semble ainsi réuni pour 270 00:13:19,710 --> 00:13:22,710 permettre la distribution de secrets. Les secrets sont dans 271 00:13:22,710 --> 00:13:25,270 le gestionnaire de secrets. Le gestionnaire de secrets 272 00:13:25,270 --> 00:13:28,010 s'authentifie auprès des applications avec un certificat 273 00:13:28,010 --> 00:13:31,010 obtenu par ACME. Les applications s'authentifient 274 00:13:31,010 --> 00:13:33,490 elles aussi auprès du gestionnaire de secrets avec des 275 00:13:33,490 --> 00:13:34,730 certificats obtenus par ACME. 276 00:13:35,500 --> 00:13:36,840 Mais... 277 00:13:36,840 --> 00:13:39,840 Oui, il y a un mais. Sinon, ça ne serait pas drôle. Dans le cas 278 00:13:39,840 --> 00:13:43,180 de Hashicorp Vault et d'Openbao, son équivalent vraiment libre, 279 00:13:43,470 --> 00:13:46,860 il y a besoin d'un secret pour déverrouiller le gestionnaire de 280 00:13:46,860 --> 00:13:50,580 secrets, notamment lors de son démarrage ! En effet, à moins de 281 00:13:50,580 --> 00:13:54,040 pouvoir profiter d'un KMS préexistant, généralement fourni 282 00:13:54,040 --> 00:13:56,840 par la cloud faisant tourner nos applications, il va falloir 283 00:13:56,840 --> 00:13:59,720 desceller, c'est-à-dire déchiffrer, la base de données 284 00:13:59,720 --> 00:14:00,910 du gestionnaire de secrets. 285 00:14:01,490 --> 00:14:04,450 Et pour faire ce déchiffrement, il faut que les ops manipulent 286 00:14:04,450 --> 00:14:07,190 un secret symétrique ou des parts de secrets symétriques ! 287 00:14:07,830 --> 00:14:09,550 Retour à la case départ. 288 00:14:10,100 --> 00:14:12,920 Certes, il n'y a maintenant plus qu'un seul secret qui est 289 00:14:12,920 --> 00:14:16,060 manipulé sur toute l'infrastructure... et certes, 290 00:14:16,060 --> 00:14:18,250 c'est uniquement dans le cas où le fournisseur de cloud 291 00:14:18,250 --> 00:14:20,760 n'offrirait pas de KMS utilisable par le gestionnaire 292 00:14:20,760 --> 00:14:24,840 de secrets... mais... une personne qui a accès à ce secret 293 00:14:25,050 --> 00:14:28,360 a en réalité accès à tous les secrets de l'infrastructure ! 294 00:14:28,790 --> 00:14:31,300 C'est donc toujours tous les secrets de l'infrastructure 295 00:14:31,300 --> 00:14:34,300 qu'il faudra remplacer en cas de changement dans l'équipe ops ! 296 00:14:34,950 --> 00:14:38,210 Alors, est-ce qu'on peut faire mieux ? Est-ce qu'on peut faire 297 00:14:38,210 --> 00:14:41,530 une infrastructure complètement sécurisée, sans que le moindre 298 00:14:41,530 --> 00:14:43,160 ops manipule de secrets ? 299 00:14:43,610 --> 00:14:46,820 En réalité, on a déjà évoqué plus tôt dans cet épisode la 300 00:14:46,820 --> 00:14:50,120 voie que je propose de suivre : celle des serveurs SSH et des 301 00:14:50,120 --> 00:14:51,200 serveurs ACME. 302 00:14:51,200 --> 00:14:54,410 L'idée est de générer directement sur les serveurs 303 00:14:54,410 --> 00:14:57,410 l'ensemble des secrets dont ils ont besoin, et d'effectuer 304 00:14:57,410 --> 00:15:00,410 l'ensemble des authentifications à l'aide de certificats 305 00:15:00,410 --> 00:15:01,430 émis par ACME. 306 00:15:02,200 --> 00:15:04,770 Pour un certain nombre de services, cette approche demande 307 00:15:04,770 --> 00:15:07,640 quelques modifications de la configuration. Par exemple, 308 00:15:07,640 --> 00:15:09,960 l'authentification à la base de données se fera avec une 309 00:15:09,960 --> 00:15:13,370 authentification mTLS, c'est-à-dire avec un certificat 310 00:15:13,370 --> 00:15:15,350 client et un certificat serveur. 311 00:15:15,930 --> 00:15:18,380 Le déploiement de l'ensemble des certificats nécessaires à ces 312 00:15:18,380 --> 00:15:20,920 authentifications peut être entièrement automatisé avec un 313 00:15:20,920 --> 00:15:24,320 serveur ACME local. Personnellement, j'utilise Caddy 314 00:15:24,320 --> 00:15:26,490 à cette fin dans de nombreux systèmes d'information. 315 00:15:27,370 --> 00:15:30,630 Pour les services ne prenant pas en charge mTLS, et devant 316 00:15:30,630 --> 00:15:32,600 absolument utiliser des secrets symétriques, 317 00:15:32,790 --> 00:15:34,520 cela se complexifie un petit peu. 318 00:15:34,520 --> 00:15:37,850 Pour la génération des secrets symétriques, il y a plusieurs 319 00:15:37,850 --> 00:15:41,390 possibilités. J’en vois au moins une qui n’a besoin d’aucune 320 00:15:41,390 --> 00:15:43,900 infrastructure et une autre qui nécessite le déploiement de 321 00:15:43,900 --> 00:15:45,750 serveurs pour distribuer ces secrets. 322 00:15:46,470 --> 00:15:49,110 Pour permettre le partage d'un secret symétrique, par exemple 323 00:15:49,110 --> 00:15:51,880 entre un serveur d'application et un serveur de base de données 324 00:15:51,940 --> 00:15:55,140 ne prenant pas en charge mTLS ou entre deux pairs WireGuard 325 00:15:55,140 --> 00:15:59,350 utilisant une clé prépartagée, on peut utiliser TLS. 326 00:15:59,990 --> 00:16:03,130 L'idée est ici d'utiliser TLS non pas pour sécuriser une 327 00:16:03,130 --> 00:16:06,840 communication, mais pour établir un secret partagé ! C'est 328 00:16:06,840 --> 00:16:09,410 d'ailleurs ce qui est fait à chaque ouverture d'une nouvelle 329 00:16:09,410 --> 00:16:10,460 session TLS. 330 00:16:11,170 --> 00:16:14,182 Pour faire cela, il faut déployer un petit programme sur 331 00:16:14,182 --> 00:16:16,502 une des deux machines devant connaitre le secret partagé 332 00:16:16,500 --> 00:16:20,457 qui jouera le rôle de serveur TLS, et un autre petit programme 333 00:16:20,457 --> 00:16:25,154 sur l'autre machine qui jouera le rôle de client TLS. Lorsque 334 00:16:25,154 --> 00:16:28,788 le client TLS se connectera au serveur TLS, ils feront une 335 00:16:28,788 --> 00:16:32,480 poignée de main (ou handshake), et génèreront un secret qu'il 336 00:16:32,480 --> 00:16:37,520 est possible d'exporter selon la procédure de la RFC5705 ou de la 337 00:16:37,520 --> 00:16:43,371 section 7.5 de la RFC8446. Et boom ! On a un secret partagé 338 00:16:43,371 --> 00:16:44,777 entre les deux machines ! 339 00:16:45,097 --> 00:16:48,297 Ces programmes jouant le rôle de clients et serveurs TLS peuvent 340 00:16:48,297 --> 00:16:52,354 être développés en moins de 300 lignes de Go. Vous pourrez 341 00:16:52,350 --> 00:16:54,514 retrouver un lien vers un exemple d'implémentation dans 342 00:16:54,514 --> 00:16:55,577 les notes de ce podcast. 343 00:16:56,720 --> 00:16:59,260 L'autre solution pour le partage de secrets symétriques entre 344 00:16:59,260 --> 00:17:01,920 deux machines ou plus nécessite une infrastructure de 345 00:17:01,920 --> 00:17:03,750 distribution de clés et de secrets. 346 00:17:04,700 --> 00:17:08,600 Cette infrastructure consiste en une grappe de serveurs etcd. 347 00:17:09,420 --> 00:17:12,990 Etcd est un serveur de base de données de type clé/valeur avec 348 00:17:12,990 --> 00:17:15,630 un dispositif de contrôle d'accès par clé (ou chemin de 349 00:17:15,630 --> 00:17:19,780 clé). L'authentification entre les membres de la grappe etcd, 350 00:17:19,780 --> 00:17:23,040 et entre les clients etcd et les serveurs etcd se font tous en 351 00:17:23,040 --> 00:17:26,510 mTLS. En conséquence, toutes les interactions peuvent être 352 00:17:26,510 --> 00:17:29,170 sécurisées et authentifiées grâce à un déploiement d'un 353 00:17:29,170 --> 00:17:30,490 serveur ACME local. 354 00:17:31,210 --> 00:17:33,770 Grâce à cette infrastructure, un des serveurs ayant le besoin de 355 00:17:33,770 --> 00:17:37,170 connaitre le secret symétrique le génère localement. Il le 356 00:17:37,170 --> 00:17:39,550 chiffre ensuite à l'aide de la clé publique contenue dans les 357 00:17:39,550 --> 00:17:42,230 certificats de tous les autres serveurs ayant le besoin de 358 00:17:42,230 --> 00:17:45,230 connaitre ce secret. Les versions chiffrées sont ensuite 359 00:17:45,230 --> 00:17:48,230 publiées sur etcd. Chaque serveur ayant le besoin d'en 360 00:17:48,230 --> 00:17:51,110 connaitre pourra se connecter à etcd, récupérer la version 361 00:17:51,110 --> 00:17:54,020 chiffrée du secret symétrique, le déchiffrer grâce à leur clé 362 00:17:54,020 --> 00:17:57,020 privée associée à leur certificat émis par ACME. Et 363 00:17:57,020 --> 00:18:00,020 boom ! Tous les serveurs connaitront le même secret. 364 00:18:00,900 --> 00:18:03,690 Avec l’une ou l’autre de ces deux solutions de distribution 365 00:18:03,690 --> 00:18:06,740 de clés symétriques, les ops n’ont jamais eu connaissance ni 366 00:18:06,740 --> 00:18:10,100 manipulé des secrets. Lorsqu'ils ont été en transit, ils étaient 367 00:18:10,100 --> 00:18:12,760 chiffrés. Seules les machines ayant le besoin de connaitre ces 368 00:18:12,760 --> 00:18:14,330 secrets les ont manipulés. 369 00:18:14,870 --> 00:18:17,200 Voilà ! Dans cet épisode, je vous ai présenté un certain 370 00:18:17,200 --> 00:18:19,910 nombre de solutions et de non-solutions pour permettre de 371 00:18:19,910 --> 00:18:22,420 déployer des infrastructures codifiées sans que les ops ne 372 00:18:22,420 --> 00:18:26,030 manipulent le moindre secret ! Grâce à cette approche, les 373 00:18:26,030 --> 00:18:28,920 changements dans la composition des équipes ops n'ont aucune 374 00:18:28,920 --> 00:18:31,370 incidence sur la sécurité des secrets du système 375 00:18:31,370 --> 00:18:32,200 d'information. 376 00:18:32,730 --> 00:18:36,030 Pour récapituler, utiliser un outil de Configuration as Code 377 00:18:36,030 --> 00:18:39,510 comme Ansible, OpenTofu ou un gestionnaire de secrets comme 378 00:18:39,510 --> 00:18:43,310 Hashicorp Vault sans descellement par un KMS expose à 379 00:18:43,310 --> 00:18:47,100 ce qu'on appelle en anglais le secret sprawling. Cette 380 00:18:47,100 --> 00:18:49,630 expression indique une divulgation mal contrôlée des 381 00:18:49,630 --> 00:18:52,540 secrets, menant à leur divulgation à des acteurs 382 00:18:52,540 --> 00:18:55,240 n'ayant pas le besoin fonctionnel d'en connaitre, à 383 00:18:55,240 --> 00:18:56,490 commencer par les ops. 384 00:18:57,340 --> 00:19:00,070 À l'inverse, en utilisant des ressources éphémères de 385 00:19:00,070 --> 00:19:03,950 Terraform couplées à des sockets de type AF_VSOCK, il est 386 00:19:03,950 --> 00:19:06,340 possible d'utiliser l'hyperviseur comme rebond de 387 00:19:06,340 --> 00:19:10,370 confiance pour déposer des secrets générés par Terraform et 388 00:19:10,370 --> 00:19:12,590 déployés par un provisionneur SSH. 389 00:19:13,350 --> 00:19:16,380 Une autre solution évoquée est d'utiliser un gestionnaire de 390 00:19:16,380 --> 00:19:19,710 secrets comme Hashicorp Vault, si ce dernier est descellé de 391 00:19:19,710 --> 00:19:23,290 manière automatisée par un autre gestionnaire de secrets, comme 392 00:19:23,290 --> 00:19:26,380 un KMS du fournisseur cloud ou une autre instance d'un 393 00:19:26,380 --> 00:19:27,740 gestionnaire de secrets. 394 00:19:28,120 --> 00:19:31,100 Finalement, la solution universelle, celle qui 395 00:19:31,100 --> 00:19:34,100 fonctionne sans prérequis particulier, a été détaillée : 396 00:19:34,540 --> 00:19:38,530 générer les secrets en local, directement sur les machines qui 397 00:19:38,530 --> 00:19:42,090 en ont besoin. Idéalement, utiliser exclusivement des clés 398 00:19:42,090 --> 00:19:44,610 asymétriques est préférable ; pas besoin d'infrastructure 399 00:19:44,610 --> 00:19:48,310 particulière, en dehors d'un serveur ACME local. Lorsque ce 400 00:19:48,310 --> 00:19:51,100 n'est pas possible, nous avons vu des solutions de partage de 401 00:19:51,100 --> 00:19:54,480 secrets avec et sans infrastructure, qui sont plus 402 00:19:54,480 --> 00:19:57,110 complexes à mettre en œuvre, mais qui satisfont parfaitement 403 00:19:57,110 --> 00:19:58,920 au problème de confidentialité des clés. 404 00:19:59,410 --> 00:20:02,100 J'espère que cet épisode vous a plu. Je ne doute pas qu'il vous 405 00:20:02,100 --> 00:20:05,100 fera réagir ; n'hésitez pas à poster vos commentaires sur le 406 00:20:05,100 --> 00:20:06,990 lien disponible en description. 407 00:20:07,460 --> 00:20:09,790 Dans le prochain épisode, j’aborderai la sauvegarde 408 00:20:09,790 --> 00:20:13,340 sécurisée des serveurs, traitant notamment des mérites respectifs 409 00:20:13,340 --> 00:20:16,490 des approches « pull » et « push », et de la manière de 410 00:20:16,490 --> 00:20:19,200 bénéficier des avantages des deux simultanément ! 411 00:20:19,570 --> 00:20:20,110 À bientôt !