¿Cuáles son las ventajas de poner valores secretos de un sitio web como variables de entorno?

24

Las pautas de devops en https://12factor.net/config sugieren poner los secretos del sitio web (contraseñas de bases de datos, claves de API, etc.) en variables de entorno. ¿Qué ventajas tiene eso en lugar de usar archivos de texto (JSON, XML, YAML, INI o similares) ignorados por el control de versiones?

Me resulta mucho más fácil copiar un archivo de configuración con secretos que manejar variables de entorno en .bash_profile y la configuración del servidor web. ¿Echo de menos algo?

Aidas Bendoraitis
fuente
1
En teoría, es más fácil leer un archivo que la memoria, por lo que podría considerar la superficie de ataque más grande y la complejidad más pequeña.
Florin Asăvoaie
La regla empírica de mi desarrollador es que almacenar configuraciones en variables de entorno es mejor hacerlo solo en entornos similares. Fuera de las máquinas virtuales de contenedores, aprueba / prefiere todos los demás puntos de 12factor.net y el uso de archivos de configuración. A ninguno de nosotros nos gustó la naturaleza insegura de las variables de entorno en las implementaciones de servidores regulares.
Corey Ogburn

Respuestas:

21

El autor enumera su razonamiento, aunque es un poco disjunto. Su argumento principal es que es fácil registrar accidentalmente un archivo de configuración, y que los archivos de configuración tienen diferentes formatos y pueden estar dispersos por el sistema (los tres son, en el mejor de los casos, argumentos mediocres para la configuración relacionada con la seguridad, como tokens de autenticación y credenciales).

Dada mi propia experiencia, esencialmente tiene las siguientes tres opciones, con las ventajas y desventajas asociadas:

Almacene los datos en archivos de configuración.

Al adoptar este enfoque, lo ideal es aislarlos del repositorio y asegurarse de que estén fuera del área en la que la aplicación almacena su contenido.

Ventajas:

  • Muy fácil de aislar y controlar el acceso, especialmente si está utilizando cosas como SELinux o AppArmor para mejorar la seguridad general del sistema.
  • Generalmente fácil de cambiar para usuarios no técnicos (esta es una ventaja para el software publicado, pero no necesariamente para el software específico de su organización).
  • Fácil de administrar en grandes grupos de servidores. Hay todo tipo de herramientas para la implementación de la configuración.
  • Razonablemente fácil de verificar cuál es la configuración exacta que se utiliza.
  • Para una aplicación bien escrita, generalmente puede cambiar la configuración sin interrumpir el servicio actualizando el archivo de configuración y luego enviando una señal particular a la aplicación (generalmente SIGHUP).

Desventajas

  • Se necesita una planificación adecuada para mantener seguros los datos.
  • Es posible que tenga que aprender diferentes formatos (aunque en estos días solo hay un puñado por el cual preocuparse, y generalmente tienen una sintaxis similar).
  • Las ubicaciones de almacenamiento exactas pueden estar codificadas en la aplicación, lo que hace que la implementación sea potencialmente problemática.
  • El análisis de los archivos de configuración puede ser problemático.

Almacene los datos en variables de entorno.

Por lo general, esto se realiza al obtener una lista de variables de entorno y valores del script de inicio, pero en algunos casos puede simplemente indicarlos en la línea de comandos antes del nombre del programa.

Ventajas:

  • En comparación con el análisis de un archivo de configuración, extraer un valor de una variable de entorno es trivial en casi cualquier lenguaje de programación.
  • No tiene que preocuparse tanto por publicar accidentalmente la configuración.
  • Obtendrá cierto grado de seguridad por la oscuridad porque esta práctica es poco común, y la mayoría de las personas que piratean su aplicación no van a pensar en mirar las variables de entorno de inmediato.
  • El acceso puede ser controlado por la aplicación misma (cuando genera procesos secundarios, puede eliminar fácilmente el entorno para eliminar información confidencial).

Desventajas

  • En la mayoría de los sistemas UNIX, es razonablemente fácil acceder a las variables de entorno de un proceso. Algunos sistemas proporcionan formas de mitigar esto (la hidepidopción de montaje /procen LInux, por ejemplo), pero no están habilitados de forma predeterminada y no protegen contra los ataques del usuario propietario del proceso.
  • No es trivial ver la configuración exacta que algo está usando si maneja el problema de seguridad mencionado anteriormente correctamente.
  • Debe confiar en la aplicación para eliminar el entorno cuando genera procesos secundarios, de lo contrario, se filtrará información.
  • No puede cambiar fácilmente la configuración sin un reinicio completo de la aplicación.

Use argumentos de línea de comandos para pasar los datos.

En serio, evite esto a toda costa, no es seguro y es muy difícil de mantener.

Ventajas:

  • Incluso más fácil de analizar que las variables de entorno en la mayoría de los idiomas.
  • Los procesos secundarios no heredan automáticamente los datos.
  • Proporciona una manera fácil de probar rápidamente configuraciones particulares al desarrollar la aplicación.

Desventajas

  • Al igual que las variables de entorno, es fácil leer la línea de comandos de otro proceso en la mayoría de los sistemas.
  • Extremadamente tedioso para actualizar la configuración.
  • Establece un límite estricto sobre la duración de la configuración (a veces tan baja como 1024 caracteres).
Austin Hemmelgarn
fuente
1
Un punto no importante es el (re) inicio desatendido de un servidor, sin tener que dar manualmente ninguna contraseña, al final están en algún lugar del disco para eso
PlasmaHH
77
En la mayoría de los sistemas UNIX, puede leer prácticamente cualquier variable de entorno de procesos sin necesidad de privilegios significativos. -- ¿Se puede ampliar al respecto? El archivo / proc / #### / environmental solo puede ser leído por el propietario, por lo que debe ser root o tener sudo.
rrauenza
Creo que parte de esta tendencia de configuración de env también surgió de cosas como Docker donde usas un contenedor estándar y lo configuras pasando variables env al contenedor.
rrauenza
@rrauenza La propiedad de un proceso no es un privilegio significativo a menos que haga un muy buen trabajo de segregación de cosas por cuenta, y en realidad solo necesita la capacidad CAP_SYS_ADMIN (que la raíz tiene implícitamente) si no es el propietario. Además, con respecto a la variable de entorno, probablemente tenga razón, pero es un diseño marginal incluso con Docker.
Austin Hemmelgarn
3
Estoy de acuerdo con el punto que hace @rrauenza. La respuesta es bastante buena en todos los aspectos, pero me gustaría aclarar cómo exactamente puede leer prácticamente cualquier variable de entorno de procesos sin necesidad de privilegios significativos . Con respecto a " y en realidad solo necesita la capacidad CAP_SYS_ADMIN (que la raíz tiene implícitamente) ..." bueno, si un agente malintencionado tiene privilegios de root, la discusión adicional es redundante, y CAP_SYS_ADMIN también podría ser un privilegio de root (ver man7.org/linux /man-pages/man7/capabilities.7.html , CAP_SYS_ADMIN y Notas para desarrolladores de kernel )
Nubarke
13

Las variables de entorno serán heredadas por cada proceso hijo del servidor web. Esa es cada sesión que se conecta al servidor, y cada programa generado por ellos. Los secretos se revelarán automáticamente a todos esos procesos.

Si mantiene secretos en los archivos de texto, deben ser legibles por el proceso del servidor, y potencialmente también por todos los procesos secundarios. Pero al menos los programas tienen que ir a buscarlos; No se proporcionan automáticamente. También puede hacer que algunos procesos secundarios se ejecuten en diferentes cuentas y hacer que los secretos sean legibles solo por esas cuentas. Por ejemplo, suEXEC hace esto en Apache.

Andrew Schulman
fuente
1
"Esa es cada sesión que se conecta al servidor" es una declaración engañosa. No puede abrir una sesión http en el servidor y obtener acceso a sus variables de entorno, ni puede iniciar sesión en un shell en ese servidor y obtenerlas a menos que tenga acceso de root o sea dueño del proceso del servidor web.
Segfault
Cada proceso generado por el servidor web hereda su entorno, a menos que tome medidas activas de lo contrario. Una página HTML no tiene la capacidad de usar esa información, pero un script sí.
Andrew Schulman
Si bien es correcta, esta respuesta podría funcionar con algunas correcciones / concesiones, especialmente con respecto a las sesiones de término . En la primera lectura, parece describir el uso de variables de entorno con poca luz casi para sugerir posibilidades de divulgación de información a un cliente externo. Además, se puede hacer una concesión comparable a suexec para la configuración limitada de env-vars, por ejemplo, la configuración de env-vars (a la MYVAR=foo /path/to/some/executable) por proceso limita la propagación a un proceso y es solo para niños, y donde sea necesario, los daemons maestros pueden eliminar / restablecer / modificar El entorno de los procesos secundarios.
shalomb
2

Incluso si hay algunas compensaciones relacionadas con la seguridad que se deben hacer cuando se trata de variables de entorno o archivos, no creo que la seguridad sea la principal fuerza impulsora de esta recomendación. Recuerde que los autores de 12factor.net también son (¿o también lo fueron?) Desarrolladores de Heroku PaaS. Hacer que todos usen variables de entorno probablemente simplificó bastante su desarrollo. Hay tanta variedad en diferentes formatos y ubicaciones de archivos de configuración y les habría resultado difícil admitirlos a todos. Las variables de entorno son fáciles en comparación.

No se necesita mucha imaginación para adivinar algunas de las conversaciones que se tuvieron.

Desarrollador A: "¡Ah, esta interfaz de usuario secreta del archivo de configuración está demasiado abarrotada! ¿Realmente necesitamos tener un menú desplegable que cambie entre json, xml y csv?"

Desarrollador B: "Oh, la vida sería tan grandiosa si solo todos usaran variables de entorno para la configuración de la aplicación".

Desarrollador A: "En realidad, hay algunas razones plausibles relacionadas con la seguridad para hacer eso. Las variables de entorno probablemente no se verifiquen accidentalmente en el control de origen".

Desarrollador B: "¿No configura las variables de entorno con un script que inicia el demonio o un archivo de configuración?"

Desarrollador A: "¡No en Heroku! Haremos que los escriban en la interfaz de usuario".

Desarrollador B: "Oh, mira, mi alerta de nombre de dominio para 12factor.net simplemente se activó". 1


1 : fuente: inventado.

Segfault
fuente
1

TL; DR

Existen varias razones para usar variables de entorno en lugar de archivos de configuración, pero dos de las más comunes que se deben pasar por alto es el valor de utilidad de la configuración fuera de banda y la separación mejorada entre servidores, aplicaciones o roles organizacionales. En lugar de presentar una lista exhaustiva de todas las razones posibles, solo abordo estos dos temas en mi respuesta, y toco ligeramente sus implicaciones de seguridad.

Configuración fuera de banda: separación de secretos del código fuente

Si almacena todos sus secretos en un archivo de configuración, debe distribuir esos secretos a cada servidor. Eso significa verificar los secretos en el control de revisión junto con su código, o tener un repositorio o mecanismo de distribución completamente separado para los secretos.

Cifrar tus secretos realmente no ayuda a resolver esto. ¡Todo lo que hace es empujar el problema a una eliminación, porque ahora también debe preocuparse por la administración y distribución de claves!

En resumen, las variables de entorno son un enfoque para mover los datos por servidor o por aplicación fuera del código fuente cuando desea separar el desarrollo de las operaciones. ¡Esto es especialmente importante si ha publicado el código fuente!

Mejorar la separación: servidores, aplicaciones y roles

Si bien ciertamente podría tener un archivo de configuración para guardar sus secretos, si almacena los secretos en el código fuente tiene un problema de especificidad. ¿Tiene una rama o repositorio separado para cada conjunto de secretos? ¿Cómo se asegura de que el conjunto correcto de secretos llegue a los servidores correctos? ¿O reduce la seguridad al tener "secretos" que son los mismos en todas partes (o legibles en todas partes, si los tiene todos en un archivo) y, por lo tanto, constituyen un riesgo mayor si fallan los controles de seguridad de cualquier sistema?

Si desea tener secretos únicos en cada servidor, o para cada aplicación, las variables de entorno eliminan el problema de tener que administrar una multitud de archivos. Si agrega un nuevo servidor, aplicación o rol, no tiene que crear archivos nuevos o actualizar los antiguos: simplemente actualiza el entorno del sistema en cuestión.

Pensamientos de despedida sobre seguridad

Si bien una exploración exhaustiva de la seguridad del núcleo / memoria / archivo está fuera del alcance de esta respuesta, vale la pena señalar que las variables de entorno implementadas adecuadamente por sistema no son menos seguras que los secretos "encriptados". En cualquier caso, el sistema de destino todavía tiene que mantener el secreto descifrado en la memoria en algún momento para poder usarlo.

También vale la pena señalar que cuando los valores se almacenan en la memoria volátil en un nodo determinado, no hay ningún archivo en el disco que se pueda copiar y atacar sin conexión. Esto generalmente se considera una ventaja para los secretos en memoria, pero ciertamente no es concluyente.

La cuestión de las variables de entorno frente a otras técnicas de gestión de secretos es realmente más sobre las compensaciones de seguridad y usabilidad que sobre los absolutos. Su experiencia puede ser diferente.

CodeGnome
fuente
2
Esto no es convincente, porque todas las desventajas que menciona para los archivos de configuración también se aplican a las variables de entorno. Las variables de entorno son datos de configuración. No se establecen mágicamente. Deben distribuirse a cada sistema y se debe utilizar algún tipo de mecanismo de configuración para configurarlos.
jpaugh
@jpaugh Estás discutiendo con un hombre de paja y atacas algo que nunca dije. Los problemas que abordo son la configuración fuera de banda y la separación de datos. Como se explica claramente, puede hacer estas cosas de la forma que desee. Si lo prefiere, puede publicar sus secretos junto con su código públicamente en GitHub, pero eso ciertamente parece poco acertado en el caso general. Sin embargo, solo usted puede determinar las compensaciones necesarias para que su sistema funcione correctamente dentro de un modelo de amenaza dado.
CodeGnome
2
Todos sus puntos son correctos, excepto que se aplica tanto a las variables de entorno como a cualquier otro dato de configuración. Si almacena variables de entorno en archivos, puede confirmarlas; y si los envía fuera de banda, es más fácil hacerlo en un archivo que escribiéndolos. Pero si prefiere escribirlos, ¿por qué no escribe un objeto JSON en su lugar y lo lee en stdin? Eso es realmente más seguro que la línea de comando.
jpaugh
1

Personalmente, no recomendaría establecer variables ambientales .bashrcya que estas se vuelven visibles para todos los procesos iniciados por el shell, sino establecerlas en el nivel de demonio / supervisor (script init / rc, configuración systemd) para que su alcance se limite a donde sea necesario .

Cuando los equipos separados administran las operaciones, las variables de entorno proporcionan una interfaz fácil para que las operaciones establezcan el entorno para la aplicación sin tener que conocer los archivos / formatos de configuración y / o recurrir a la manipulación de su contenido. Esto es especialmente cierto en configuraciones multi-idioma / multi-framework donde los equipos de operaciones pueden elegir el sistema de implementación (SO, procesos de supervisión) en función de las necesidades operativas (facilidad de implementación, escalabilidad, seguridad, etc.).

Otra consideración son las canalizaciones de CI / CD, ya que el código pasa por diferentes entornos(es decir, desarrollo, prueba / qa, puesta en escena, producción) los detalles ambientales (zonas de implementación, detalles de conexión de base de datos, credenciales, direcciones IP, nombres de dominio, etc.) se configuran mejor mediante herramientas / marcos de administración de configuración dedicados y consumidos por la aplicación procesos desde el entorno (en SECO, escribir una vez, ejecutar en cualquier lugar de manera) Tradicionalmente, cuando los desarrolladores tienden a gestionar estas preocupaciones operativas, tienden a registrar archivos de configuración o plantillas además del código, y luego terminan agregando soluciones y otra complejidad cuando cambian los requisitos operativos (por ejemplo, nuevos entornos / implementación / sitios, escalabilidad / seguridad) pesarse,

  • Env-vars simplifica la configuración / complejidad a escala.
  • Env-vars coloca la configuración operativa directamente con el equipo responsable de los aspectos no relacionados con el código de la aplicación de una manera uniforme (si no estándar) no vinculante.
  • Env-vars admite el intercambio de los procesos maestro / supervisor (por ejemplo, dios, monit, supervisor, sysvinit, systemd, etc.) que respaldan la aplicación, y ciertamente incluso el sistema de implementación (SO, imágenes de contenedor, etc.), etc., como requisitos operativos evolucionar / cambiar. Si bien cada marco de lenguaje hoy en día tiene algún tipo de tiempo de ejecución de proceso, estos tienden a ser operacionalmente inferiores, más adecuados para entornos de desarrollo y / o aumentan la complejidad en entornos de producción multi-lenguaje / multi-marco.

Para la producción, estoy a favor de configurar los entornos de la aplicación en un archivo de entorno como el /etc/default/myapplication.confque se implementa mediante la administración de la configuración y que solo sea legible de roottal manera que systemd(o cualquier otra cosa) pueda generar la aplicación bajo un usuario del sistema privilegiado dedicado en un privado grupo . Respaldado con grupos de usuarios dedicados para opsy sudo: estos archivos no se pueden leer de forma predeterminada en todo el mundo. Esto es compatible con 12factor y admite todas las bondades de Dev + Ops plus, tiene todos los beneficios de una seguridad decente y al mismo tiempo permite que los desarrolladores / evaluadores ingresen sus propios archivos Environment en los entornos dev / qa / test.

shalomb
fuente
0

Desde la perspectiva del desarrollador, el almacenamiento de datos de configuración en variables de entorno simplifica las implementaciones entre diferentes entornos (desarrollo, control de calidad y producción) y libera a los desarrolladores de tener que preocuparse por implementar el archivo de configuración incorrecto.

Las aplicaciones web de Azure ofrecen la opción de usar este patrón y funciona muy bien.

Además de eso, mantiene esos datos potencialmente confidenciales fuera del control de origen. Ignorar esos archivos del control de código fuente no es realmente factible (al menos en .NET) porque también hay una gran cantidad de configuraciones necesarias en esos archivos.

Derek Gusoff
fuente