Quais são as vantagens de colocar valores secretos de um website como variáveis de ambiente?

21

As diretrizes devops no link sugerem colocar os segredos do site (senhas de banco de dados, chaves de API, etc.) em variáveis de ambiente. Que vantagens isso tem em vez de usar arquivos de texto (JSON, XML, YAML, INI ou similar) ignorados do controle de versão?

Acho muito mais fácil copiar um arquivo de configuração com segredos do que manipular variáveis de ambiente em configuração .bash_profile e webserver. Eu sinto falta de algo?

    
por Aidas Bendoraitis 16.01.2018 / 17:30

6 respostas

21

O autor lista seu raciocínio, embora seja um pouco disjunto. Seu principal argumento é que é fácil fazer check-in acidentalmente em um arquivo de configuração, e que os arquivos de configuração têm formatos variados e podem estar espalhados pelo sistema (todos os três são argumentos medíocres para configurações relacionadas à segurança, como tokens de autenticação e credenciais).

Considerando minha própria experiência, você basicamente tem as três opções a seguir, com vantagens e desvantagens associadas:

Armazene os dados nos arquivos de configuração.

Ao adotar essa abordagem, você deve idealmente isolá-los do próprio repositório e certificar-se de que eles estejam fora da área em que o aplicativo armazena seu conteúdo.

Vantagens:

  • Muito fácil de isolar e controlar o acesso, especialmente se você estiver usando coisas como o SELinux ou o AppArmor para melhorar a segurança geral do sistema.
  • Geralmente fácil de alterar para usuários não técnicos (isso é uma vantagem para o software publicado, mas não necessariamente para software específico da sua organização).
  • Fácil de gerenciar em grandes grupos de servidores. Existem todos os tipos de ferramentas para implementação de configuração lá fora.
  • Razoavelmente fácil verificar qual é a configuração exata em uso.
  • Para um aplicativo bem escrito, normalmente você pode alterar a configuração sem interromper o serviço, atualizando o arquivo de configuração e, em seguida, enviando um sinal específico para o aplicativo (geralmente SIGHUP).

Desvantagens:

  • O planejamento adequado é necessário para manter os dados seguros.
  • Você pode ter que aprender diferentes formatos (embora atualmente só tenha muito o que se preocupar e eles geralmente tenham uma sintaxe semelhante).
  • Os locais de armazenamento exato podem ser codificados no aplicativo, o que torna a implantação potencialmente problemática.
  • A análise dos arquivos de configuração pode ser problemática.

Armazene os dados em variáveis de ambiente.

Geralmente isso é feito pelo fornecimento de uma lista de variáveis de ambiente e valores do script de inicialização, mas em alguns casos, pode ser apenas declará-los na linha de comando antes do nome do programa.

Vantagens:

  • Comparado à análise de um arquivo de configuração, extrair um valor de uma variável de ambiente é trivial em praticamente qualquer linguagem de programação.
  • Você não precisa se preocupar tanto com a publicação acidental da configuração.
  • Você ganha algum grau de segurança por obscuridade porque essa prática é incomum, e a maioria das pessoas que hackam seu aplicativo não pensa em analisar as variáveis de ambiente imediatamente.
  • O acesso pode ser controlado pelo próprio aplicativo (quando ele gera processos filho, ele pode facilmente limpar o ambiente para remover informações confidenciais).

Desvantagens

  • Na maioria dos sistemas UNIX, é razoavelmente fácil obter acesso às variáveis de ambiente de um processo. Alguns sistemas oferecem maneiras de atenuar isso (a opção hidepid mount para /proc no LInux, por exemplo), mas eles não são ativados por padrão e não protegem contra ataques do usuário que possui o processo.
  • Não é comum ver as configurações exatas que alguma coisa está usando se você lida corretamente com o problema de segurança mencionado acima.
  • Você precisa confiar no aplicativo para depurar o ambiente quando gerar processos filhos, caso contrário, vazará informações.
  • Você não pode alterar facilmente a configuração sem uma reinicialização completa do aplicativo.

Use argumentos de linha de comando para passar os dados.

Sério, evite isso a todo custo, não é seguro e é um saco para manter.

Vantagens:

  • Ainda mais simples de analisar que as variáveis de ambiente na maioria das linguagens.
  • Processos filhos não herdam automaticamente os dados.
  • Fornece uma maneira fácil de testar rapidamente configurações específicas ao desenvolver o aplicativo.

Desvantagens:

  • Assim como as variáveis de ambiente, é fácil ler a linha de comando de outro processo na maioria dos sistemas.
  • Extremamente tedioso para atualizar a configuração.
  • Coloca um limite rígido em quanto tempo a configuração pode ser (às vezes até 1024 caracteres).
por 16.01.2018 / 19:10
12

Variáveis de ambiente serão herdadas por cada processo filho do servidor web. Essa é toda sessão que se conecta ao servidor e a cada programa gerado por eles. Os segredos serão revelados automaticamente para todos esses processos.

Se você mantiver segredos em arquivos de texto, eles precisam ser legíveis pelo processo do servidor e, portanto, potencialmente também por cada processo filho. Mas pelo menos os programas precisam ir e encontrá-los; eles não são fornecidos automaticamente. Você também pode fazer com que alguns processos filhos sejam executados em contas diferentes e tornar os segredos legíveis somente por essas contas. Por exemplo, o suEXEC faz isso no Apache.

    
por 16.01.2018 / 17:44
1

Mesmo que haja algumas compensações relacionadas à segurança quando se trata de variáveis ou arquivos de ambiente, não acho que a segurança tenha sido a principal força motriz dessa recomendação. Lembre-se de que os autores do 12factor.net também são (ou eram também) desenvolvedores do Heroku PaaS. Fazer com que todos usem variáveis de ambiente provavelmente simplificou bastante o seu desenvolvimento. Há tanta variedade em diferentes formatos e locais de arquivos de configuração, e teria sido difícil para eles oferecer suporte a todos eles. Variáveis de ambiente são fáceis em comparação.

Não é preciso muita imaginação para adivinhar algumas das conversas que tiveram.

Developer A: "Ah this secret config file UI is too cluttered! Do we really need to have a drop down that switches between json, xml, and csv?"

Developer B: "Oh, life would be so grand if only everyone used environment variables for the app config."

Developer A: "Actually there are some plausible security-related reasons to do that. Environment variables probably won't get accidentally checked into source control."

Developer B: "Don't you set the environment variables with a script that launches the daemon, or a config file?"

Developer A: "Not in Heroku! We'll make them type them into the UI."

Developer B: "Oh look, my domain name alert for 12factor.net just went off."1

1 : source: composto.

    
por 17.01.2018 / 07:59
1

TL; DR

Existem vários motivos para usar variáveis de ambiente em vez de arquivos de configuração, mas dois dos mais comuns a ignorar são o valor do utilitário configuração fora da banda e aprimorado separação entre servidores, aplicativos ou funções organizacionais. Em vez de apresentar uma lista exaustiva de todas as razões possíveis, abordo apenas esses dois tópicos em minha resposta e toco levemente em suas implicações de segurança.

Configuração fora da banda: separando segredos do código-fonte

Se você armazenar todos os seus segredos em um arquivo de configuração, precisará distribuir esses segredos para cada servidor. Isso significa verificar os segredos no controle de revisão ao lado de seu código ou ter um repositório ou mecanismo de distribuição totalmente separado para os segredos.

Criptografar seus segredos realmente não ajuda a resolver isso. Tudo o que isso faz é empurrar o problema para uma remoção, porque agora você também precisa se preocupar com o gerenciamento e a distribuição de chaves!

Em suma, as variáveis de ambiente são uma abordagem para mover dados por servidor ou por aplicativo para fora do código-fonte quando você deseja separar o desenvolvimento das operações. Isso é especialmente importante se você publicou o código-fonte!

Melhorar a separação: servidores, aplicativos e funções

Embora você possa ter um arquivo de configuração para guardar seus segredos, se você armazenar os segredos no código fonte, você tem um problema de especificidade. Você tem uma filial ou repositório separado para cada conjunto de segredos? Como você garante que o conjunto certo de segredos chegue aos servidores certos? Ou você reduz a segurança tendo "segredos" que são os mesmos em todos os lugares (ou legíveis em todos os lugares, se você os tiver todos em um arquivo) e, portanto, constituem um risco maior se os controles de segurança de um sistema falharem?

Se você deseja ter segredos exclusivos em cada servidor ou para cada aplicativo, as variáveis de ambiente eliminam o problema de ter que gerenciar uma grande quantidade de arquivos. Se você adicionar um novo servidor, aplicativo ou função, não precisará criar novos arquivos ou atualizar os antigos: basta atualizar o ambiente do sistema em questão.

Reflexão sobre segurança

Embora uma exploração completa da segurança do kernel / memória / arquivo esteja fora do escopo desta resposta, vale a pena ressaltar que as variáveis de ambiente por sistema adequadamente implementadas não são menos seguras do que os segredos "criptografados". Em ambos os casos, o sistema de destino ainda tem que manter o segredo descriptografado na memória em algum ponto para usá-lo.

Também vale ressaltar que quando os valores são armazenados na memória volátil em um determinado nó, não há arquivos no disco que possam ser copiados e atacados offline. Isso geralmente é considerado uma vantagem para os segredos da memória, mas certamente não é conclusivo.

A questão das variáveis de ambiente versus outras técnicas de gerenciamento de segredos é realmente mais sobre segurança e usabilidade trade-offs do que sobre absolutos. Sua milhagem pode variar.

    
por 17.01.2018 / 17:43
1

Pessoalmente, eu não recomendaria a configuração de variáveis ambientais em .bashrc , pois elas se tornam visíveis para todos os processos iniciados pelo shell, mas para configurá-los no nível do daemon / supervisor (script init / rc , systemd config) para que seu escopo seja limitado a onde necessário.

Quando as equipes separadas gerenciam as operações, as variáveis de ambiente fornecem uma interface fácil para as operações definirem o ambiente para o aplicativo sem precisar saber sobre os arquivos / formatos de configuração e / ou recorrer ao processamento de seu conteúdo. Isso é especialmente verdadeiro em configurações de vários idiomas / várias estruturas, em que as equipes de operações podem escolher o sistema de implantação (SO, processos de supervisor) com base nas necessidades operacionais (facilidade de implantação, escalabilidade, segurança, etc.).

Outra consideração é pipelines de CI / CD - conforme o código passa por diferentes ambientes (isto é, dev, teste / qa, preparação, produção) os detalhes ambientais (zonas de implantação, dados de conexão do banco de dados, credenciais, IP endereços, nomes de domínio, etc, etc) são melhor definidos por ferramentas / estruturas de gerenciamento de configuração dedicadas e consumidos pelos processos de aplicativos do ambiente (em uma forma DRY, escrever uma vez, executar em qualquer lugar). Tradicionalmente, onde os desenvolvedores tendem a gerenciar essas preocupações operacionais, eles tendem a adicionar arquivos de configuração ou modelos além do código - e acabam adicionando soluções alternativas e outras complexidades quando os requisitos operacionais mudam (por exemplo, novos ambientes / implantação / sites, escalabilidade / segurança pesar, vários ramos de funcionalidades - e de repente existem scripts de implementação manual para gerir / manejar os muitos perfis de configuração) - esta complexidade é uma distração e uma sobrecarga melhor gerida fora do código por ferramentas dedicadas.

  • Env-vars simplifica a configuração / complexidade em escala.
  • O Env-vars coloca a configuração operacional diretamente na equipe responsável pelos aspectos relacionados ao não-código do aplicativo de maneira uniforme (se não padrão) sem vinculação.
  • O suporte a Env-vars troca os processos mestre / supervisor (por exemplo, deus, monit, supervisord, sysvinit, systemd etc.) que suportam o aplicativo - e certamente até mesmo o sistema de implantação (sistemas operacionais, imagens de contêiner etc.) conforme os requisitos operacionais evoluem / mudam. Embora todas as estruturas de linguagem tenham algum tipo de tempo de execução de processos, elas tendem a ser operacionalmente inferiores, mais adequadas para ambientes de desenvolvimento e / ou aumentam a complexidade em ambientes de produção multi-linguagem / multi-framework.

Para produção, eu prefiro definir o aplicativo env-vars em um EnvironmentFile como /etc/default/myapplication.conf que é implantado pelo gerenciamento de configuração e definido legível somente por root , de modo que systemd (ou qualquer outra coisa para esse assunto) possa gerar o aplicativo em um Usuário do sistema desprivilegiado em um Grupo privado . Apoiado com grupos de usuários dedicados para ops e sudo - esses arquivos são ilegíveis pelo mundo por padrão. Isso é compatível com 12factor, suportando todas as vantagens de Dev + Ops, além de ter todos os benefícios de uma segurança decente e, ao mesmo tempo, permitir que desenvolvedores / testadores instalem seus próprios EnvironmentFiles nos ambientes de desenvolvimento / teste / qa.

    
por 18.01.2018 / 00:38
0

Da perspectiva de um desenvolvedor, armazenar dados de configuração em variáveis de ambiente simplifica as implantações entre diferentes ambientes - desenvolvimento, controle de qualidade e produção - e libera os desenvolvedores de se preocuparem com a implantação do arquivo de configuração incorreto.

Os aplicativos da Web do Azure oferecem a opção de usar esse padrão e funciona muito bem.

Além disso, mantém dados potencialmente confidenciais fora do controle de origem. Ignorar esses arquivos do controle de origem não é realmente viável (pelo menos no .NET), porque muitas configurações de clichê também estão presentes nesses arquivos.

    
por 17.01.2018 / 03:16