Mantengo configuraciones importantes como los nombres de host y los puertos de servidores de desarrollo y producción en mi sistema de control de versiones. Pero sé que es una mala práctica guardar secretos (como claves privadas y contraseñas de bases de datos) en un repositorio de VCS.
Pero las contraseñas, como cualquier otra configuración, parecen ser versionadas. Entonces, ¿cuál es la forma correcta de mantener controlada la versión de las contraseñas?
Me imagino que implicaría mantener los secretos en su propio archivo de "configuración de secretos" y tener ese archivo encriptado y controlado por la versión. ¿Pero qué tecnologías? ¿Y cómo hacer esto correctamente? ¿Hay una mejor manera de hacerlo?
En general, hago la pregunta, pero en mi caso específico me gustaría almacenar claves secretas y contraseñas para un sitio Django / Python usando git y github .
Además, una solución ideal haría algo mágico cuando empuje / tire con git; por ejemplo, si el archivo de contraseñas cifradas cambia, se ejecuta un script que solicita una contraseña y la descifra en su lugar.
EDITAR: para mayor claridad, estoy preguntando dónde almacenar los secretos de producción .
fuente
Respuestas:
Tiene toda la razón al querer cifrar su archivo de configuración confidencial mientras mantiene el archivo en control de versiones. Como mencionó, la mejor solución sería una en la que Git cifre de forma transparente ciertos archivos confidenciales cuando los presione para que localmente (es decir, en cualquier máquina que tenga su certificado) pueda usar el archivo de configuración, pero Git o Dropbox o quien sea almacenar sus archivos en VC no tiene la capacidad de leer la información en texto sin formato.
Tutorial sobre cifrado / descifrado transparente durante Push / Pull
Esta esencia https://gist.github.com/873637 muestra un tutorial sobre cómo usar el controlador de filtro de manchas / limpieza de Git con openssl para encriptar archivos empujados de forma transparente. Solo necesita hacer una configuración inicial.
Resumen de cómo funciona
Básicamente crearás una
.gitencrypt
carpeta que contiene 3 scripts de bash,que Git usa para descifrar, cifrar y admitir Git diff. Una frase de contraseña maestra y una sal (¡arreglado!) Se definen dentro de estos scripts y DEBE asegurarse de que .gitencrypt nunca se envíe.
clean_filter_openssl
Script de ejemplo :Similar para
smudge_filter_open_ssl
ydiff_filter_oepnssl
. Ver Gist.Su repositorio con información confidencial debe tener un archivo .gitattribute (sin cifrar e incluido en el repositorio) que hace referencia al directorio .gitencrypt (que contiene todo lo que Git necesita para cifrar / descifrar el proyecto de manera transparente) y que está presente en su máquina local.
.gitattribute
contenido:Finalmente, también deberá agregar el siguiente contenido a su
.git/config
archivoAhora, cuando inserta el repositorio que contiene su información confidencial en un repositorio remoto, los archivos se cifrarán de forma transparente. Cuando extrae de una máquina local que tiene el directorio .gitencrypt (que contiene su frase de contraseña), los archivos se descifrarán de forma transparente.
Notas
Debo señalar que este tutorial no describe una forma de cifrar solo su archivo de configuración confidencial. Esto cifrará de forma transparente todo el repositorio que se envía al host VC remoto y descifrará todo el repositorio para que se descifre por completo a nivel local. Para lograr el comportamiento que desea, puede colocar archivos confidenciales para uno o varios proyectos en una sensible_configuración_repo. Podría investigar cómo funciona esta técnica de cifrado transparente con los submódulos Git http://git-scm.com/book/en/Git-Tools-Submodules si realmente necesita que los archivos confidenciales estén en el mismo repositorio.
El uso de una frase de contraseña fija podría conducir teóricamente a vulnerabilidades de fuerza bruta si los atacantes tuvieran acceso a muchos repositorios / archivos cifrados. OMI, la probabilidad de esto es muy baja. Como se menciona en una nota al final de este tutorial, no usar una frase de contraseña fija dará como resultado versiones locales de un repositorio en diferentes máquinas que siempre muestran que se han producido cambios con el 'estado de git'.
fuente
Heroku impulsa el uso de variables de entorno para configuraciones y claves secretas:
Con Foreman y los
.env
archivos, Heroku proporciona una cadena de herramientas envidiable para exportar, importar y sincronizar variables de entorno.Personalmente, creo que está mal guardar claves secretas junto con el código. Es fundamentalmente inconsistente con el control de código fuente, porque las claves son para servicios extrínsecos al código . El único beneficio sería que un desarrollador pueda clonar HEAD y ejecutar la aplicación sin ninguna configuración. Sin embargo, suponga que un desarrollador revisa una revisión histórica del código. Su copia incluirá la contraseña de la base de datos del año pasado, por lo que la aplicación fallará en la base de datos de hoy.
Con el método Heroku anterior, un desarrollador puede verificar la aplicación del año pasado, configurarla con las claves de hoy y ejecutarla con éxito en la base de datos de hoy.
fuente
La forma más limpia en mi opinión es usar variables de entorno. No tendrá que lidiar con archivos .dist , por ejemplo, y el estado del proyecto en el entorno de producción sería el mismo que el de su máquina local.
Recomiendo leer el capítulo de configuración de la aplicación The Twelve-Factor , los otros también si está interesado.
fuente
export MY_ENV_VAR=
, y cuando lo implemente, simplemente complételo con los valores correctossource
. Si por mantener quiere decir la versión de la configuración, no debería estar haciendo esto en primer lugar.Una opción sería colocar las credenciales vinculadas al proyecto en un contenedor cifrado (TrueCrypt o Keepass) y enviarlo.
Actualización como respuesta de mi comentario a continuación:
Pregunta interesante por cierto. Acabo de encontrar esto: github.com/shadowhand/git-encrypt que parece muy prometedor para el cifrado automático
fuente
git-encrypt
sonidos suena exactamente como la que estoy buscando "Al trabajar con un repositorio git remoto que está alojado en un servidor de almacenamiento de terceros, la confidencialidad de los datos a veces se convierte en una preocupación. Este artículo lo guía a través de los procedimientos para configurar repositorios git para el cual sus directorios de trabajo locales son normales (sin cifrar) pero el contenido comprometido está cifrado ". (Por supuesto, solo quiero un subconjunto de mi contenido encriptado ...)Sugiero usar archivos de configuración para eso y no versionarlos.
Sin embargo, puede ver ejemplos de versiones de los archivos.
No veo ningún problema para compartir la configuración de desarrollo. Por definición, no debe contener datos valiosos.
fuente
BlackBox fue lanzado recientemente por StackExchange y aunque todavía tengo que usarlo, parece abordar exactamente los problemas y respaldar las funciones solicitadas en esta pregunta.
De la descripción en https://github.com/StackExchange/blackbox :
fuente
Desde que hice esta pregunta, me decidí por una solución, que uso cuando desarrollo pequeñas aplicaciones con un pequeño equipo de personas.
cripta git
git-crypt usa GPG para cifrar archivos de forma transparente cuando sus nombres coinciden con ciertos patrones. Por ejemplo, si agrega a su
.gitattributes
archivo ...... entonces un archivo como
config.secret.json
siempre se enviará a repositorios remotos con cifrado, pero permanecerá sin cifrar en su sistema de archivos local.Si quiero agregar una nueva clave GPG (una persona) a su repositorio, que puede descifrar los archivos protegidos y luego ejecutarlos
git-crypt add-gpg-user <gpg_user_key>
. Esto crea una nueva confirmación. El nuevo usuario podrá descifrar las confirmaciones posteriores.fuente
No, simplemente no lo hagas, incluso si es tu repositorio privado y nunca tienes la intención de compartirlo, no lo hagas.
Debe crear un local_settings.py, ponerlo en VCS ignorar y en su settings.py hacer algo como
Si la configuración de tus secretos es tan versátil, estoy ansioso por decirte que estás haciendo algo mal
fuente
EDITAR: supongo que desea realizar un seguimiento de sus versiones de contraseñas anteriores, por ejemplo, para un script que evitaría la reutilización de contraseñas, etc.
Creo que GnuPG es la mejor manera de hacerlo: ya se usa en un proyecto relacionado con git (git-annex) para cifrar el contenido del repositorio almacenado en los servicios en la nube. GnuPG (gnu pgp) proporciona un cifrado basado en claves muy fuerte.
Ahora, si su archivo 'mypassword' no cambió, el cifrado tendrá el mismo texto cifrado y no se agregará al índice (sin redundancia). La más mínima modificación de mypassword resulta en texto cifrado radicalmente diferente y mypassword.gpg en el área de preparación difiere mucho del que está en el repositorio, por lo que se agregará a la confirmación. Incluso si el atacante obtiene su clave gpg, todavía necesita forzar la contraseña. Si el atacante obtiene acceso al repositorio remoto con texto cifrado, puede comparar un montón de textos cifrados, pero su número no será suficiente para darle una ventaja no despreciable.
Más adelante puede usar .gitattributes para proporcionar un descifrado sobre la marcha para salir de su contraseña.
También puede tener claves separadas para diferentes tipos de contraseñas, etc.
fuente
Por lo general, separo la contraseña como un archivo de configuración. y hacerlos dist.
Y cuando corro
main.py
, pon la contraseña real endefault.cfg
la copiada.PD. cuando trabajas con git o hg. puede ignorar
*.cfg
archivos para hacer.gitignore
o.hgignore
fuente
Proporcionar una forma de anular la configuración
Esta es la mejor manera de administrar un conjunto de valores predeterminados razonables para la configuración que registra sin requerir que la configuración esté completa o que contenga cosas como nombres de host y credenciales. Hay algunas formas de anular las configuraciones predeterminadas.
Las variables de entorno (como ya han mencionado otros) son una forma de hacerlo.
La mejor manera es buscar un archivo de configuración externo que anule los valores de configuración predeterminados. Esto le permite administrar las configuraciones externas a través de un sistema de administración de configuración como Chef, Puppet o Cfengine. La gestión de la configuración es la respuesta estándar para la gestión de configuraciones separadas de la base de código, por lo que no tiene que hacer una versión para actualizar la configuración en un solo host o grupo de hosts.
FYI: Cifrar créditos no siempre es una buena práctica, especialmente en un lugar con recursos limitados. Puede ser que el cifrado de créditos no le permita mitigar riesgos adicionales y simplemente agregará una capa innecesaria de complejidad. Asegúrese de hacer el análisis adecuado antes de tomar una decisión.
fuente
Cifre el archivo de contraseñas, utilizando, por ejemplo, GPG. Agregue las claves en su máquina local y en su servidor. Descifre el archivo y colóquelo fuera de sus carpetas de repositorio.
Yo uso passwords.conf, ubicado en mi carpeta de inicio. En cada implementación, este archivo se actualiza.
fuente
No, las claves privadas y las contraseñas no están bajo control de revisión. No hay ninguna razón para abrumar a todos con acceso de lectura a su repositorio con el conocimiento de las credenciales de servicio confidenciales utilizadas en la producción, cuando lo más probable es que no todas tengan acceso a esos servicios.
Comenzando con Django 1.4, sus proyectos de Django ahora se envían con un
project.wsgi
módulo que define elapplication
objeto y es un lugar perfecto para comenzar a aplicar el uso de unproject.local
módulo de configuración que contiene configuraciones específicas del sitio.Este módulo de configuración se ignora desde el control de revisión, pero se requiere presencia cuando se ejecuta la instancia de su proyecto como una aplicación WSGI, típica de los entornos de producción. Así es como debería verse:
Ahora puede tener un
local.py
módulo cuyo propietario y grupo se pueden configurar para que solo el personal autorizado y los procesos de Django puedan leer el contenido del archivo.fuente
Si necesita VCS para sus secretos, al menos debe mantenerlos en un segundo repositorio separado de su código real. Por lo tanto, puede dar acceso a los miembros de su equipo al repositorio de código fuente y no verán sus credenciales. Además, aloje este repositorio en otro lugar (por ejemplo, en su propio servidor con un sistema de archivos encriptado, no en github) y para verificarlo en el sistema de producción podría usar algo como git-submodule .
fuente
Otro enfoque podría ser evitar por completo guardar secretos en los sistemas de control de versiones y, en su lugar, utilizar una herramienta como la bóveda de hashicorp , un almacenamiento secreto con rodadura de claves y auditoría, con una API y cifrado integrado.
fuente
Esto es lo que hago:
Los archivos de plantilla contienen un marcador de posición para el secreto, como:
my.password = ## MY_PASSWORD ##
En la implementación de la aplicación, se ejecuta un script que transforma el archivo de plantilla en el archivo de destino, reemplazando los marcadores de posición con valores de variables de entorno, como cambiar ## MY_PASSWORD ## al valor de $ MY_PASSWORD.
fuente
Puede usar EncFS si su sistema lo proporciona. Por lo tanto, podría mantener sus datos cifrados como una subcarpeta de su repositorio, mientras proporciona a su aplicación una vista descifrada de los datos montados a un lado. Como el cifrado es transparente, no se necesitan operaciones especiales en pull o push.
Sin embargo, necesitaría montar las carpetas EncFS, lo que podría hacer su aplicación en función de una contraseña almacenada en otro lugar fuera de las carpetas versionadas (por ejemplo, variables de entorno).
fuente