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

24

As diretrizes do devops em https://12factor.net/config sugerem colocar segredos de sites (senhas de bancos de dados, chaves API, etc.) em variáveis ​​de ambiente. Que vantagens isso tem em vez de usar arquivos de texto (JSON, XML, YAML, INI ou similares) ignorados no controle de versão?

Acho muito mais fácil copiar um arquivo de configuração com segredos do que manipular variáveis ​​de ambiente nas configurações .bash_profile e webserver. Perco alguma coisa?

Aidas Bendoraitis
fonte
1
Em teoria, é mais fácil ler um arquivo do que memória, para que você possa considerar a superfície de ataque maior e a complexidade menor.
Florin Asăvoaie
A regra geral do meu desenvolvedor é que o armazenamento de configurações em variáveis ​​de ambiente é melhor apenas para ser feito em ambientes do tipo docker. Fora das VMs de contêiner, ele aprova / prefere todos os outros pontos do 12factor.net e o uso de arquivos de configuração. Nenhum de nós gostou da natureza insegura das variáveis ​​de ambiente em implantações regulares de servidores.
Corey Ogburn

Respostas:

21

O autor lista o seu raciocínio, embora seja um pouco desinteressado. O argumento principal é 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 na melhor das hipóteses argumentos medíocres para configurações relacionadas à segurança, como tokens de autenticação e credenciais).

Dada 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 isolá-las do próprio repositório e garantir que elas 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 SELinux ou AppArmor para melhorar a segurança geral do sistema.
  • Geralmente é fácil alterar para usuários não técnicos (essa é uma vantagem para o software publicado, mas não necessariamente para o software específico da sua organização).
  • Fácil de gerenciar em grandes grupos de servidores. Existem todos os tipos de ferramentas para implantação de configuração por aí.
  • É razoavelmente fácil verificar qual é a configuração exata que está sendo usada.
  • Para um aplicativo bem escrito, geralmente você pode alterar a configuração sem interromper o serviço atualizando o arquivo de configuração e enviando um sinal específico para o aplicativo (geralmente SIGHUP).

Desvantagens:

  • É necessário um planejamento adequado para manter os dados seguros.
  • Você pode ter que aprender formatos diferentes (embora hoje em dia haja apenas um punhado de preocupações e eles geralmente tenham sintaxe semelhante).
  • Os locais de armazenamento exatos podem ser codificados no aplicativo, tornando 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 fornecendo uma lista de variáveis ​​e valores do ambiente a partir do script de inicialização, mas em alguns casos, pode ser indicado 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ê obtém um certo grau de segurança pela obscuridade, porque essa prática é incomum, e a maioria das pessoas que invade seu aplicativo não pensa em examinar as variáveis ​​de ambiente imediatamente.
  • O acesso pode ser controlado pelo próprio aplicativo (quando gera processos filho, pode facilmente esfregar 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 fornecem maneiras de atenuar isso (a hidepidopção de montagem 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 é trivial ver as configurações exatas que algo está usando se você lidar com o problema de segurança mencionado acima corretamente.
  • Você precisa confiar no aplicativo para limpar o ambiente quando ele gerar processos filhos, caso contrário ele vazará informações.
  • Você não pode alterar facilmente a configuração sem reiniciar completamente o aplicativo.

Use argumentos da linha de comando para transmitir os dados.

Sério, evite isso a todo custo, não é seguro e é muito difícil de manter.

Vantagens:

  • Ainda mais simples de analisar do que as variáveis ​​de ambiente na maioria dos idiomas.
  • Os processos filhos não herdam os dados automaticamente.
  • 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.
  • Estabelece um limite rígido de quanto tempo a configuração pode demorar (às vezes, com 1024 caracteres).
Austin Hemmelgarn
fonte
1
Um ponto não sem importância é autônoma boot (re) de um servidor, sem ter manualmente para dar todas as senhas, no final, eles estão em algum lugar no disco para que
PlasmaHH
7
Na maioria dos sistemas UNIX, você pode ler praticamente qualquer variável de ambiente de processos sem precisar de privilégios significativos. - Você pode expandir isso? O arquivo / proc / #### / environ é legível apenas pelo proprietário, portanto você precisa ser root ou ter sudo.
Rruenza
Eu acho que algumas dessas tendências de configuração de env também surgiram de coisas como o docker, onde você usa um contêiner padrão e o configura passando variáveis ​​env para o contêiner.
Rruenza
@rrauenza A propriedade de um processo não é um privilégio significativo, a menos que você faça um bom trabalho de segregar as coisas por conta, e na verdade você só precisa do recurso CAP_SYS_ADMIN (que a raiz tem implicitamente) se você não for o proprietário. Além disso, com relação à variável de ambiente, você provavelmente está certo, mas é um design marginal, mesmo com o Docker.
precisa saber é o seguinte
3
Eu concordo com o argumento que @rrauenza faz. A resposta é ótima, mas gostaria de esclarecer como exatamente você pode ler praticamente qualquer variável de ambiente de processos sem precisar de privilégios significativos . Em relação a " e você realmente só precisa do recurso CAP_SYS_ADMIN (que a raiz tem implicitamente) ..." bem, se um agente mal-intencionado tiver privilégios de root, uma discussão adicional será redundante e o CAP_SYS_ADMIN também poderá ser um privilégio de root (consulte man7.org/linux /man-pages/man7/capabilities.7.html , CAP_SYS_ADMIN e notas para desenvolvedores de kernel )
Nubarke
13

As variáveis ​​de ambiente serão herdadas por todos os processos filhos do servidor web. É toda sessão que se conecta ao servidor e todo programa gerado por eles. Os segredos serão automaticamente revelados a todos esses processos.

Se você mantiver segredos em arquivos de texto, eles devem ser legíveis pelo processo do servidor e, potencialmente, por todos os processos filhos também. 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 apenas por essas contas. Por exemplo, suEXEC faz isso no Apache.

Andrew Schulman
fonte
1
"Essa é a sessão que se conecta ao servidor" é uma declaração enganosa. Você não pode abrir uma sessão http no servidor e obter acesso a suas variáveis ​​de ambiente, nem pode fazer login em um shell nesse servidor e obtê-las, a menos que tenha acesso root ou seja o proprietário do processo do servidor web.
Segfault
Todo processo gerado pelo servidor da Web herda seu ambiente, a menos que você execute etapas ativas em contrário. Uma página HTML não tem a capacidade de usar essas informações, mas um script possui.
precisa
Embora correta, essa resposta pode ter algumas correções / concessões, especialmente no que diz respeito ao termo sessões . Na primeira leitura, parece mostrar mal o uso de variáveis ​​de ambiente, quase sugerindo possibilidades de divulgação de informações para um cliente externo. Além disso, uma concessão comparável ao suexec pode ser feita para a configuração limitada de env-vars, por exemplo, a definição de env-vars por processo (a MYVAR=foo /path/to/some/executable) limita a propagação a um processo e é apenas para crianças - e onde os daemons mestres necessários podem limpar / redefinir / modificar o ambiente dos processos filho.
Shalomb
2

Mesmo que haja algumas compensações relacionadas à segurança a serem feitas quando se trata de arquivos ou variáveis ​​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 foram?) Desenvolvedores do Heroku PaaS. Fazer com que todos usem variáveis ​​de ambiente provavelmente simplificou bastante seu desenvolvimento. Há muita variedade em diferentes formatos e locais de arquivos de configuração e teria sido difícil para eles oferecer suporte a todos. As variáveis ​​de ambiente são fáceis de comparar.

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

Desenvolvedor A: "Ah, essa interface de usuário secreta do arquivo de configuração está muito confusa! Precisamos mesmo de uma lista suspensa que alterne entre json, xml e csv?"

Desenvolvedor B: "Ah, a vida seria tão grande se todos usassem variáveis ​​de ambiente para a configuração do aplicativo".

Desenvolvedor A: "Na verdade, existem alguns motivos plausíveis relacionados à segurança para fazer isso. As variáveis ​​de ambiente provavelmente não serão acidentalmente verificadas no controle de origem".

Desenvolvedor B: "Você não define as variáveis ​​de ambiente com um script que inicia o daemon ou um arquivo de configuração?"

Desenvolvedor A: "Não está no Heroku! Vamos fazê-los digitar na interface do usuário".

Desenvolvedor B: "Olha, meu alerta de nome de domínio para 12factor.net acabou de disparar." 1


1 : fonte: composta.

Segfault
fonte
1

TL; DR

Existem várias razões para usar variáveis ​​de ambiente em vez de arquivos de configuração, mas duas das mais comuns a serem ignoradas é o valor de utilidade da configuração fora de banda e separação aprimorada 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 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á distribuí-los para cada servidor. Isso significa verificar os segredos no controle de revisão ao lado do 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 faz é levar o problema a um ponto, porque agora você também precisa se preocupar com o gerenciamento e distribuição de chaves!

Em resumo, as variáveis ​​de ambiente são uma abordagem para mover os 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!

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

Embora você certamente possa ter um arquivo de configuração para guardar seus segredos, se você armazenar os segredos no código-fonte, terá 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 iguais em todos os lugares (ou legíveis em todos os lugares, se você os tiver 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 infinidade 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.

Pensamentos sobre segurança

Embora uma exploração completa da segurança do kernel / memória / arquivo esteja fora do escopo desta resposta, vale ressaltar que as variáveis ​​de ambiente por sistema implementadas corretamente são menos seguras que os segredos "criptografados". Nos dois casos, o sistema de destino ainda precisa manter o segredo descriptografado na memória em algum momento 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á arquivo no disco que possa ser copiado e atacado 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 gestão de segredos é realmente mais sobre segurança e usabilidade trade-offs que se trata de absolutos. Sua milhagem pode variar.

CodeGnome
fonte
2
Isso não é convincente, porque todas as desvantagens mencionadas nos arquivos de configuração também se aplicam a variáveis ​​de ambiente. Variáveis ​​de ambiente são dados de configuração. Eles não se colocam magicamente. Eles precisam ser distribuídos para cada sistema, e algum tipo de mecanismo de configuração deve ser usado para defini-los.
jpaugh
@jpaugh Você está discutindo e atacando algo que eu nunca disse. Os problemas que abordo são a configuração fora de banda e a separação de dados. Como explicado claramente, você pode fazer essas coisas da maneira que quiser. Se preferir, você pode postar seus segredos publicamente no GitHub publicamente, mas isso certamente parece imprudente no caso geral. No entanto, somente você pode determinar as compensações necessárias para o seu sistema operar adequadamente dentro de um determinado modelo de ameaça.
CodeGnome 17/01
2
Todos os seus pontos estão corretos, exceto que se aplicam a variáveis ​​de ambiente e a quaisquer outros dados de configuração. Se você armazenar variáveis ​​de ambiente em arquivos, poderá confirmá-las; e se você enviá-los fora da banda, é mais fácil fazer isso em um arquivo do que digitando-os. Mas se você preferir digitá-los, por que não digitar um objeto JSON e lê-lo no stdin? Isso é realmente mais seguro que a linha de comando.
jpaugh
1

Pessoalmente, eu não recomendaria definir variáveis ​​ambientais, .bashrcpois elas se tornam visíveis para todos os processos iniciados pelo shell, mas defini-las no nível daemon / supervisor (script init / rc, systemd config) para que seu escopo seja limitado ao necessário .

Onde equipes separadas gerenciam operações, as variáveis ​​de ambiente fornecem uma interface fácil para as operações definirem o ambiente para o aplicativo sem precisar conhecer os arquivos / formatos de configuração e / ou recorrer à manipulação de seu conteúdo. Isso é especialmente verdadeiro nas configurações de vários idiomas / 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 são os pipelines de CI / CD - já que o código passa por diferentes ambientes(isto é, dev, test / qa, preparo, produção) os detalhes ambientais (zonas de implantação, detalhes de conexão com o banco de dados, credenciais, endereços IP, nomes de domínio etc.) são melhor definidos por ferramentas / estruturas de gerenciamento de configuração dedicados e consumidos pelo aplicativo processos do ambiente (em um DRY, escreva uma vez, execute em qualquer lugar da moda). Tradicionalmente, quando os desenvolvedores tendem a gerenciar essas preocupações operacionais, eles fazem check-in de arquivos ou modelos de configuração 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,

  • Env-vars simplificam a configuração / complexidade em escala.
  • Os envários colocam a configuração operacional diretamente com a equipe responsável pelos aspectos não relacionados ao código do aplicativo, de maneira uniforme (se não padrão) não vinculativa.
  • Os Env-vars suportam a troca dos processos de mestre / supervisor (por exemplo, deus, monit, supervisord, sysvinit, systemd, etc) que apoiam o aplicativo - e certamente até o sistema de implantação (sistemas operacionais, imagens de contêineres etc.) ou outros como requisitos operacionais evoluir / mudar. Embora atualmente toda estrutura de linguagem possua algum tipo de tempo de execução do processo, elas tendem a ser operacionalmente inferiores, mais adequadas para ambientes de desenvolvimento e / ou aumentam a complexidade em ambientes de produção em vários idiomas / várias estruturas.

Para produção, sou a favor da configuração dos envios de aplicativos em um EnvironmentFile , como /etc/default/myapplication.confo implantado pelo gerenciamento de configuração, e a legibilidade somente por rootque systemd(ou qualquer outra coisa) possa gerar o aplicativo sob um usuário de sistema Desprivilegiado dedicado em um Private grupo . Apoiado com grupos de usuários dedicados para opse sudo- esses arquivos são ilegíveis por mundo por padrão. Isso é compatível com 12 fatores, oferecendo suporte a todos os benefícios do Dev + Ops plus e todos os benefícios de uma segurança decente, enquanto permite que os desenvolvedores / testadores acessem seus próprios EnvironmentFiles nos ambientes dev / qa / test.

shalomb
fonte
0

Do ponto de vista do desenvolvedor, o armazenamento de 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 terem que se preocupar em implantar o arquivo de configuração errado.

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

Além disso, mantém esses dados potencialmente sensíveis 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 necessárias também estão presentes nesses arquivos.

Derek Gusoff
fonte