Les directives devops à https://12factor.net/config suggèrent de mettre les secrets du site Web (mots de passe de la base de données, clés api, etc.) dans des variables d'environnement. Quels avantages cela a-t-il au lieu d'utiliser des fichiers texte (JSON, XML, YAML, INI ou similaire) ignorés du contrôle de version?
Je trouve qu'il est beaucoup plus facile de copier un fichier de configuration avec des secrets que de gérer les variables d'environnement dans la configuration .bash_profile et le serveur Web. Dois-je manquer quelque chose?
L'auteur énumère leur raisonnement, bien que ce soit un peu décousu. Leur principal argument est qu'il est facile de vérifier accidentellement un fichier de configuration, et que les fichiers de configuration ont des formats différents et peuvent être dispersés dans le système (tous les trois sont au mieux des arguments médiocres pour une configuration liée à la sécurité comme les jetons d'authentification et les informations d'identification).
Compte tenu de ma propre expérience, vous avez essentiellement les trois options suivantes, avec les avantages et inconvénients associés:
Lorsque vous adoptez cette approche, vous devez idéalement les isoler du référentiel lui-même et vous assurer qu'ils se trouvent en dehors de la zone dans laquelle l'application stocke son contenu.
Habituellement, cela se fait en obtenant une liste de variables et de valeurs d'environnement à partir du script de démarrage, mais dans certains cas, il peut simplement les indiquer sur la ligne de commande avant le nom du programme.
hidepid
pour /proc
sur LInux par exemple), mais ils ne sont pas activés par défaut et ne protègent pas contre les attaques de l'utilisateur propriétaire du processus.Sérieusement, évitez cela à tout prix, ce n'est pas sûr et c'est une douleur dans le cul à maintenir.
Les variables d'environnement seront héritées par chaque processus enfant du serveur Web. C'est chaque session qui se connecte au serveur et chaque programme généré par eux. Les secrets seront automatiquement révélés à tous ces processus.
Si vous conservez des secrets dans des fichiers texte, ils doivent être lisibles par le processus serveur, et donc potentiellement aussi par chaque processus enfant. Mais au moins, les programmes doivent aller les trouver; ils ne sont pas fournis automatiquement. Vous pouvez également être en mesure d'exécuter certains processus enfants sous différents comptes et de rendre les secrets lisibles uniquement par ces comptes. Par exemple, suEXEC fait cela dans Apache.
Même s'il y a des compromis à faire en matière de sécurité en ce qui concerne les variables d'environnement ou les fichiers, je ne pense pas que la sécurité ait été le principal moteur de cette recommandation. N'oubliez pas que les auteurs de 12factor.net sont également (ou étaient également?) Des développeurs de Heroku PaaS. Amener tout le monde à utiliser les variables d'environnement a probablement simplifié un peu leur développement. Il y a tellement de variété dans les différents formats et emplacements des fichiers de configuration et il aurait été difficile pour eux de les prendre en charge tous. Les variables d'environnement sont faciles à comparer.
Il ne faut pas beaucoup d'imagination pour deviner certaines des conversations qui ont eu lieu.
Développeur A: "Ah, cette interface secrète de fichier de configuration est trop encombrée! Avons-nous vraiment besoin d'une liste déroulante qui permute entre json, xml et csv?"
Développeur B: "Oh, la vie serait si belle si tout le monde utilisait des variables d'environnement pour la configuration de l'application."
Développeur A: "En fait, il existe des raisons plausibles liées à la sécurité. Les variables d'environnement ne seront probablement pas accidentellement vérifiées dans le contrôle de code source."
Développeur B: "Ne définissez-vous pas les variables d'environnement avec un script qui lance le démon ou un fichier de configuration?"
Développeur A: "Pas dans Heroku! Nous allons les faire taper dans l'interface utilisateur."
Développeur B: "Oh regardez, mon alerte de nom de domaine pour 12factor.net vient de se déclencher."1
1: source: composée.
Il existe un certain nombre de raisons pour utiliser des variables d'environnement au lieu de fichiers de configuration, mais deux des plus courantes à ignorer sont la valeur d'utilité de configuration hors bande et séparation améliorée entre les serveurs, les applications ou les rôles organisationnels. Plutôt que de présenter une liste exhaustive de toutes les raisons possibles, j'aborde uniquement ces deux sujets dans ma réponse, et j'aborde légèrement leurs implications en matière de sécurité.
Si vous stockez tous vos secrets dans un fichier de configuration, vous devez distribuer ces secrets à chaque serveur. Cela signifie soit vérifier les secrets dans le contrôle de révision avec votre code, soit disposer d'un référentiel ou d'un mécanisme de distribution entièrement séparé pour les secrets.
Crypter vos secrets n'aide pas vraiment à résoudre ce problème. Tout ce que cela fait est de pousser le problème à une seule suppression, car vous devez maintenant vous soucier de la gestion et de la distribution des clés!
En bref, les variables d'environnement sont une approche pour déplacer des données par serveur ou par application hors du code source lorsque vous souhaitez séparer le développement des opérations. Ceci est particulièrement important si vous avez publié du code source!
Bien que vous puissiez certainement avoir un fichier de configuration pour conserver vos secrets, si vous stockez les secrets dans le code source, vous avez un problème de spécificité. Avez-vous une branche ou un référentiel distinct pour chaque ensemble de secrets? Comment vous assurez-vous que le bon ensemble de secrets parvient aux bons serveurs? Ou réduisez-vous la sécurité en ayant des "secrets" qui sont les mêmes partout (ou lisibles partout, si vous les avez tous dans un seul fichier), et constituent donc un plus grand risque si les contrôles de sécurité d'un système échouent?
Si vous voulez avoir des secrets uniques sur chaque serveur, ou pour chaque application, les variables d'environnement éliminent le problème d'avoir à gérer une multitude de fichiers. Si vous ajoutez un nouveau serveur, une nouvelle application ou un nouveau rôle, vous n'avez pas besoin de créer de nouveaux fichiers ou de mettre à jour les anciens: vous mettez simplement à jour l'environnement du système en question.
Bien qu'une exploration approfondie de la sécurité du noyau/de la mémoire/des fichiers soit hors de portée pour cette réponse, il convient de souligner que les variables d'environnement par système correctement implémentées ne sont pas moins sécurisées que les secrets "chiffrés". Dans les deux cas, le système cible doit toujours conserver le secret déchiffré en mémoire à un certain point pour l'utiliser.
Il convient également de souligner que lorsque des valeurs sont stockées dans une mémoire volatile sur un nœud donné, aucun fichier sur disque ne peut être copié et attaqué hors ligne. Ceci est généralement considéré comme un avantage pour les secrets en mémoire, mais ce n'est certainement pas concluant.
Le problème des variables d'environnement par rapport aux autres techniques de gestion des secrets concerne davantage les compromis de sécurité et d'utilisation que les absolus. Votre kilométrage peut varier.
Personnellement, je ne recommanderais pas de définir des variables d'environnement dans .bashrc
lorsque ceux-ci deviennent visibles pour tous les processus démarrés par le shell mais pour les définir au niveau du démon/superviseur (script init/rc, configuration systemd) de sorte que leur portée est limitée à l'endroit où cela est nécessaire.
Lorsque des équipes distinctes gèrent les opérations, les variables d'environnement fournissent une interface facile pour les opérations afin de définir l'environnement de l'application sans avoir à connaître les fichiers/formats de configuration et/ou à recourir à la manipulation de leur contenu. Cela est particulièrement vrai dans les paramètres multilingues/multi-frameworks où les équipes opérationnelles peuvent choisir le système de déploiement (OS, processus superviseur) en fonction des besoins opérationnels (facilité de déploiement, évolutivité, sécurité, etc.).
Une autre considération est les pipelines CI/CD - comme le code passe par différents environnements (ie dev, test/qa, staging, production) les détails environnementaux (zones de déploiement , les détails de connexion à la base de données, les informations d'identification, les adresses IP, les noms de domaine, etc.) sont mieux définis par des outils/cadres de gestion de configuration dédiés et consommés par les processus d'application de l'environnement (dans un SEC, écrire une fois, exécuter n'importe où). Traditionnellement, lorsque les développeurs ont tendance à gérer ces problèmes opérationnels, ils ont tendance à archiver les fichiers de configuration ou les modèles en plus du code - et finissent par ajouter des solutions de contournement et d'autres complexités lorsque les exigences opérationnelles changent (par exemple, de nouveaux environnements/déploiement/sites se présentent, l'évolutivité/la sécurité peser, plusieurs branches de fonctionnalités - et soudain, il y a des scripts de déploiement roulés à la main pour gérer/modifier les nombreux profils de configuration) - cette complexité est une distraction et une surcharge mieux gérée en dehors du code par des outils dédiés.
Pour la production, je préfère définir l'application env-vars dans un EnvironmentFile tel que/etc/default/myapplication.conf
qui est déployé par la gestion de la configuration et défini en lecture seule par root
de telle sorte que systemd
(ou toute autre chose d'ailleurs) peut engendrer l'application sous un dédié tilisateur système défavorisé dans un groupe privé . Soutenu avec des groupes d'utilisateurs dédiés pour ops
et Sudo
- ces fichiers sont illisibles par défaut par le monde. Ceci est compatible avec 12factor et prend en charge toutes les qualités de Dev + Ops plus a tous les avantages d'une sécurité décente tout en permettant aux développeurs/testeurs de déposer leurs propres fichiers d'environnement dans les environnements dev/qa/test.
Du point de vue d'un développeur, le stockage des données de configuration dans des variables d'environnement simplifie les déploiements entre différents environnements - développement, assurance qualité et production - et évite aux développeurs d'avoir à se soucier de déployer le mauvais fichier de configuration.
Les applications Web Azure offrent la possibilité d'utiliser ce modèle et cela fonctionne très bien.
En plus de cela, il garde ces données potentiellement sensibles hors du contrôle des sources. Ignorer ces fichiers à partir du contrôle de code source n'est pas vraiment faisable (au moins dans .NET) car une grande partie de la configuration passe-partout nécessaire est également présente dans ces fichiers.