web-dev-qa-db-fra.com

Quels sont les avantages de mettre les valeurs secrètes d'un site Web en tant que variables d'environnement?

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?

24
Aidas Bendoraitis

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:

Stockez les données dans des fichiers de configuration.

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.

Avantages:

  • Très facile à isoler et à contrôler l'accès, surtout si vous utilisez des choses comme SELinux ou AppArmor pour améliorer la sécurité globale du système.
  • Généralement facile à changer pour les utilisateurs non techniques (c'est un avantage pour les logiciels publiés, mais pas nécessairement pour les logiciels spécifiques à votre organisation).
  • Facile à gérer sur de grands groupes de serveurs. Il existe toutes sortes d'outils pour le déploiement de la configuration.
  • Raisonnablement facile de vérifier quelle est la configuration exacte utilisée.
  • Pour une application bien écrite, vous pouvez généralement modifier la configuration sans interrompre le service en mettant à jour le fichier de configuration, puis en envoyant un signal particulier à l'application (généralement SIGHUP).

Désavantages:

  • Une bonne planification est nécessaire pour sécuriser les données.
  • Vous devrez peut-être apprendre différents formats (bien que de nos jours il n'y ait qu'une poignée de soucis et qu'ils aient généralement une syntaxe similaire).
  • Les emplacements de stockage exacts peuvent être codés en dur dans l'application, ce qui rend le déploiement potentiellement problématique.
  • L'analyse des fichiers de configuration peut être problématique.

Stockez les données dans des variables d'environnement.

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.

Avantages:

  • Comparé à l'analyse d'un fichier de configuration, extraire une valeur d'une variable d'environnement est trivial dans à peu près n'importe quel langage de programmation.
  • Vous n'avez pas à vous soucier autant de la publication accidentelle de la configuration.
  • Vous obtenez un certain degré de sécurité par l'obscurité, car cette pratique est rare, et la plupart des gens qui piratent votre application ne vont pas penser à regarder les variables d'environnement tout de suite.
  • L'accès peut être contrôlé par l'application elle-même (lorsqu'elle génère des processus enfants, elle peut facilement nettoyer l'environnement pour supprimer les informations sensibles).

Désavantages

  • Sur la plupart des systèmes UNIX, il est relativement facile d'accéder aux variables d'environnement d'un processus. Certains systèmes offrent des moyens d'atténuer ce problème (l'option de montage 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.
  • Il n'est pas trivial de voir les paramètres exacts que quelque chose utilise si vous gérez correctement le problème de sécurité mentionné ci-dessus.
  • Vous devez faire confiance à l'application pour nettoyer l'environnement lorsqu'il génère des processus enfants, sinon cela entraînera une fuite d'informations.
  • Vous ne pouvez pas facilement modifier la configuration sans redémarrer complètement l'application.

Utilisez des arguments de ligne de commande pour transmettre les données.

Sérieusement, évitez cela à tout prix, ce n'est pas sûr et c'est une douleur dans le cul à maintenir.

Avantages:

  • Encore plus simple à analyser que les variables d'environnement dans la plupart des langues.
  • Les processus enfants n'héritent pas automatiquement des données.
  • Fournit un moyen simple de tester rapidement des configurations particulières lors du développement de l'application.

Désavantages:

  • Tout comme les variables d'environnement, il est facile de lire la ligne de commande d'un autre processus sur la plupart des systèmes.
  • Extrêmement fastidieux pour mettre à jour la configuration.
  • Fixe une limite stricte sur la durée de la configuration (parfois aussi faible que 1024 caractères).
21
Austin Hemmelgarn

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.

13
Andrew Schulman

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.

2
Segfault

TL; DR

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é.

Configuration hors bande: séparation des secrets du code source

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!

Améliorez la séparation: serveurs, applications et rôles

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.

Réflexions sur la sécurité

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.

1
CodeGnome

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.

  • Env-vars simplifie la configuration/complexité à grande échelle.
  • Env-vars place la configuration opérationnelle en face à face avec l'équipe responsable des aspects liés à l'application non-code dans un uniforme (sinon standard) non contraignant façon.
  • Env-vars prend en charge l'échange des processus maître/superviseur (par exemple, god, monit, supervisord, sysvinit, systemd, etc.) qui soutiennent l'application - et certainement même le système de déploiement (OS, images de conteneur, etc.) ou ainsi de suite en tant qu'exigences opérationnelles évoluer/changer. Bien que chaque framework de langage ait de nos jours une sorte d'exécution de processus, ceux-ci ont tendance à être inférieurs sur le plan opérationnel, mieux adaptés aux environnements de développement et/ou à augmenter la complexité dans les environnements de production multilingues/multi-framework.

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.

1
shalomb

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.

0
Derek Gusoff