Eu mantenho configurações importantes como os nomes de host e as portas dos servidores de desenvolvimento e produção no meu sistema de controle de versão. Mas eu sei que é uma má prática manter segredos (como chaves privadas e senhas de banco de dados) em um repositório VCS.
Mas as senhas - como qualquer outra configuração - parecem que devem ser versionadas. Então, qual é a maneira correta de manter a versão das senhas controlada?
Eu imagino que isso envolveria manter os segredos em seu próprio arquivo "configurações de segredos" e ter esse arquivo criptografado e controlado por versão. Mas quais tecnologias? E como fazer isso corretamente? Existe uma maneira melhor de fazer isso?
Eu faço a pergunta geralmente, mas no meu exemplo específico eu gostaria de armazenar chaves e senhas secretas para um site Django / Python usando git e github .
Além disso, uma solução ideal faria algo mágico quando eu empurra / puxa com o git - por exemplo, se o arquivo de senhas criptografadas muda, um script é executado, solicitando uma senha e descriptografando-a no lugar.
EDIT: Para maior clareza, estou perguntando sobre onde armazenar segredos de produção .
fonte
Respostas:
Você está certo em criptografar seu arquivo de configurações confidenciais enquanto ainda mantém o arquivo no controle de versão. Como você mencionou, a melhor solução seria aquela em que o Git criptografaria transparentemente certos arquivos confidenciais quando você os enviar para que localmente (ou seja, em qualquer máquina que possua seu certificado) você possa usar o arquivo de configurações, mas Git ou Dropbox ou quem quer que seja armazenar seus arquivos no VC não tem a capacidade de ler as informações em texto sem formatação.
Tutorial sobre criptografia / descriptografia transparente durante push / pull
Esta lista https://gist.github.com/873637 mostra um tutorial sobre como usar o driver de filtro de manchas / limpeza do Git com o openssl para criptografar transparentemente os arquivos enviados. Você só precisa fazer algumas configurações iniciais.
Resumo de como funciona
Basicamente, você criará uma
.gitencrypt
pasta contendo 3 scripts bash,que são usados pelo Git para descriptografia, criptografia e suporte ao Git diff. Uma senha mestre e salt (fixos!) São definidos dentro desses scripts e você DEVE garantir que o .gitencrypt nunca seja realmente enviado.
clean_filter_openssl
Script de exemplo :Semelhante para
smudge_filter_open_ssl
ediff_filter_oepnssl
. Veja Gist.Seu repositório com informações confidenciais deve ter um arquivo .gitattribute (não criptografado e incluído no repositório) que faça referência ao diretório .gitencrypt (que contém tudo o que o Git precisa para criptografar / descriptografar o projeto de forma transparente) e que esteja presente na sua máquina local.
.gitattribute
conteúdo:Por fim, você também precisará adicionar o seguinte conteúdo ao seu
.git/config
arquivoAgora, quando você envia o repositório que contém suas informações confidenciais para um repositório remoto, os arquivos serão criptografados de forma transparente. Quando você puxa de uma máquina local que possui o diretório .gitencrypt (que contém sua senha), os arquivos são descriptografados de forma transparente.
Notas
Devo observar que este tutorial não descreve uma maneira de criptografar apenas seu arquivo de configurações confidenciais. Isso criptografa de forma transparente todo o repositório enviado ao host remoto do VC e descriptografa o repositório inteiro para que seja totalmente descriptografado localmente. Para alcançar o comportamento desejado, você pode colocar arquivos confidenciais para um ou vários projetos em um sensitive_settings_repo. Você pode investigar como essa técnica de criptografia transparente funciona com os submódulos Git http://git-scm.com/book/en/Git-Tools-Submodules se você realmente precisa que os arquivos confidenciais estejam no mesmo repositório.
O uso de uma senha fixa pode teoricamente levar a vulnerabilidades de força bruta se os invasores tiverem acesso a muitos repositórios / arquivos criptografados. IMO, a probabilidade disso é muito baixa. Como menciona uma observação na parte inferior deste tutorial, o não uso de uma senha fixa resultará em versões locais de um repositório em máquinas diferentes, sempre mostrando que ocorreram alterações com o 'status git'.
fonte
O Heroku aprimora o uso de variáveis de ambiente para configurações e chaves secretas:
Com o Foreman e os
.env
arquivos, o Heroku fornece uma cadeia de ferramentas invejável para exportar, importar e sincronizar variáveis de ambiente.Pessoalmente, acredito que é errado salvar chaves secretas ao lado do código. É fundamentalmente inconsistente com o controle de origem, porque as chaves são para serviços extrínsecos ao código . O único benefício seria que um desenvolvedor pode clonar HEAD e executar o aplicativo sem nenhuma configuração. No entanto, suponha que um desenvolvedor verifique uma revisão histórica do código. A cópia deles incluirá a senha do banco de dados do ano passado, para que o aplicativo falhe no banco de dados atual.
Com o método Heroku acima, um desenvolvedor pode fazer check-out do aplicativo do ano passado, configurá-lo com as chaves de hoje e executá-lo com sucesso no banco de dados de hoje.
fonte
A maneira mais limpa, na minha opinião, é usar variáveis de ambiente. Você não precisará lidar com arquivos .dist, por exemplo, e o estado do projeto no ambiente de produção seria o mesmo que o da sua máquina local.
Eu recomendo ler o capítulo de configuração do Twelve-Factor App , os outros também, se você estiver interessado.
fonte
export MY_ENV_VAR=
e, quando implantar, basta preenchê-lo com os valores certossource
. Se por manter você significa a versão das configurações, você não deveria fazer isso em primeiro lugar.Uma opção seria colocar credenciais vinculadas ao projeto em um contêiner criptografado (TrueCrypt ou Keepass) e enviá-lo por push.
Atualize como resposta do meu comentário abaixo:
Pergunta interessante btw. Acabei de encontrar o seguinte: github.com/shadowhand/git-encrypt que parece muito promissor para criptografia automática
fonte
git-encrypt
sons exatamente como o que estou procurando "Ao trabalhar com um repositório git remoto hospedado em um servidor de armazenamento de terceiros, a confidencialidade dos dados às vezes se torna uma preocupação. Este artigo orienta você nos procedimentos de configuração de repositórios git para os quais seus diretórios de trabalho locais são normais (não criptografados), mas o conteúdo confirmado é criptografado ". (Claro, eu só quero um subconjunto do meu conteúdo criptografado ...)Sugiro usar arquivos de configuração para isso e não os versão.
No entanto, você pode exemplos de versão dos arquivos.
Não vejo problema em compartilhar configurações de desenvolvimento. Por definição, ele não deve conter dados valiosos.
fonte
O BlackBox foi lançado recentemente pelo StackExchange e, embora eu ainda precise usá-lo, parece abordar exatamente os problemas e dar suporte aos recursos solicitados nesta pergunta.
Na descrição em https://github.com/StackExchange/blackbox :
fonte
Desde que fiz essa pergunta, decidi por uma solução, que uso no desenvolvimento de aplicativos pequenos com uma pequena equipe de pessoas.
git-cripta
O git-crypt usa GPG para criptografar arquivos de forma transparente quando seus nomes correspondem a determinados padrões. Por exemplo, se você adicionar ao seu
.gitattributes
arquivo ...... então um arquivo como
config.secret.json
sempre será enviado para repositórios remotos com criptografia, mas permanecerá sem criptografia no sistema de arquivos local.Se eu quiser adicionar uma nova chave GPG (uma pessoa) ao seu repositório, que pode descriptografar os arquivos protegidos, execute
git-crypt add-gpg-user <gpg_user_key>
. Isso cria um novo commit. O novo usuário poderá descriptografar confirmações subsequentes.fonte
Não, apenas não, mesmo que seja seu repositório particular e você nunca pretenda compartilhá-lo, não faça.
Você deve criar um local_settings.py colocá-lo em VCS ignore e em seu settings.py fazer algo como
Se suas configurações de segredos são tão versáteis, estou ansioso para dizer que você está fazendo algo errado
fonte
EDIT: Suponho que você deseja acompanhar as versões anteriores de suas senhas - por exemplo, para um script que evite a reutilização de senhas etc.
Eu acho que o GnuPG é o melhor caminho a percorrer - ele já é usado em um projeto relacionado ao git (git-anexo) para criptografar o conteúdo do repositório armazenado nos serviços em nuvem. O GnuPG (gnu pgp) fornece uma criptografia baseada em chave muito forte.
Agora, se o arquivo 'minha senha' não foi alterado, a criptografia resultará no mesmo texto cifrado e não será adicionado ao índice (sem redundância). A modificação mais leve do mypassword resulta em texto cifrado radicalmente diferente e mypassword.gpg na área de teste diferem muito da do repositório, portanto serão adicionados ao commit. Mesmo que o invasor segure sua chave gpg, ele ainda precisará aplicar força à senha. Se o invasor obtiver acesso ao repositório remoto com texto cifrado, ele poderá comparar um monte de textos cifrados, mas o número deles não será suficiente para lhe proporcionar uma vantagem não negligenciável.
Posteriormente, você pode usar .gitattributes para fornecer uma descriptografia imediata para sair do git diff da sua senha.
Além disso, você pode ter chaves separadas para diferentes tipos de senhas, etc.
fonte
Normalmente, separo a senha como um arquivo de configuração. e distingui-los.
E quando eu corro
main.py
, coloque a senha real nadefault.cfg
cópia.ps. quando você trabalha com git ou hg. você pode ignorar
*.cfg
arquivos para criar.gitignore
ou.hgignore
fonte
Forneça uma maneira de substituir a configuração
Essa é a melhor maneira de gerenciar um conjunto de padrões sãos para a configuração que você fez check-in sem exigir que a configuração seja concluída ou conter itens como nomes de host e credenciais. Existem algumas maneiras de substituir as configurações padrão.
Variáveis de ambiente (como outros já mencionaram) são uma maneira de fazê-lo.
A melhor maneira é procurar um arquivo de configuração externo que substitua os valores de configuração padrão. Isso permite gerenciar as configurações externas por meio de um sistema de gerenciamento de configurações como Chef, Puppet ou Cfengine. O gerenciamento de configuração é a resposta padrão para o gerenciamento de configurações, separado da base de código, para que você não precise fazer uma liberação para atualizar a configuração em um único host ou grupo de hosts.
FYI: Criptografar creds nem sempre é uma prática recomendada, especialmente em um local com recursos limitados. Pode ser que as criptografadas creds não ofereçam mais mitigação de riscos e simplesmente adicionem uma camada desnecessária de complexidade. Certifique-se de fazer a análise adequada antes de tomar uma decisão.
fonte
Criptografe o arquivo de senhas, usando, por exemplo, GPG. Adicione as chaves na sua máquina local e no seu servidor. Descriptografe o arquivo e coloque-o fora de suas pastas de recompra.
Eu uso um passwords.conf, localizado na minha pasta inicial. Em cada implantação, esse arquivo é atualizado.
fonte
Não, chaves privadas e senhas não se enquadram no controle de revisão. Não há razão para sobrecarregar todos os que têm acesso de leitura ao seu repositório ao conhecerem as credenciais de serviço confidenciais usadas na produção, quando é provável que nem todas elas tenham acesso a esses serviços.
A partir do Django 1.4, seus projetos do Django agora são enviados com um
project.wsgi
módulo que define oapplication
objeto e é um local perfeito para começar a impor o uso de umproject.local
módulo de configurações que contém configurações específicas do site.Esse módulo de configurações é ignorado do controle de revisão, mas é necessária presença ao executar a instância do projeto como um aplicativo WSGI, típico para ambientes de produção. É assim que deve ser:
Agora você pode ter um
local.py
módulo cujo proprietário e grupo podem ser configurados para que somente pessoal autorizado e os processos do Django possam ler o conteúdo do arquivo.fonte
Se você precisar de VCS para seus segredos, pelo menos mantenha-os em um segundo repositório separado do seu código real. Assim, você pode dar aos membros da sua equipe acesso ao repositório de código-fonte e eles não verão suas credenciais. Além disso, hospede este repositório em outro lugar (por exemplo, no seu próprio servidor com um sistema de arquivos criptografado, não no github) e, para fazer o check-out no sistema de produção, você pode usar algo como o git-submódulo .
fonte
Outra abordagem seria evitar completamente salvar segredos nos sistemas de controle de versão e usar uma ferramenta como o vault da hashicorp , um armazenamento secreto com rolagem e auditoria de chaves, com uma API e criptografia incorporada.
fonte
Isto é o que eu faço:
Os arquivos de modelo contêm um espaço reservado para o segredo, como:
my.password = ## MY_PASSWORD ##
Na implantação do aplicativo, é executado um script que transforma o arquivo de modelo no arquivo de destino, substituindo espaços reservados por valores de variáveis de ambiente, como alterar ## MY_PASSWORD ## pelo valor de $ MY_PASSWORD.
fonte
Você poderia usar o EncFS se o seu sistema fornecer isso. Assim, você pode manter seus dados criptografados como uma subpasta do seu repositório, fornecendo ao seu aplicativo uma visualização descriptografada para os dados montados de lado. Como a criptografia é transparente, nenhuma operação especial é necessária em pull ou push.
No entanto, seria necessário montar as pastas EncFS, o que poderia ser feito pelo seu aplicativo com base em uma senha armazenada em outro local fora das pastas com versão (por exemplo, variáveis de ambiente).
fonte