Passando segredos para um contêiner do Docker

26

Eu tenho uma imagem de janela de encaixe base que é usada para executar o software de análise de imagem. Para cada contêiner criado a partir da imagem, há um conjunto de definições de configuração, algumas das quais são segredos (chaves de criptografia, informações do cliente etc.) usadas pelo software para analisar e distribuir as imagens processadas. Como posso transmitir esses segredos com segurança para um contêiner?

PrestonM
fonte
Cofre Hashicorp
030

Respostas:

23

Você tem três métodos para obter segredos para um aplicativo dentro de um contêiner de docker. Os dois primeiros envolvem a configuração do docker. O último é que seus aplicativos obtenham segredos diretamente de uma loja secreta.

1 - Variáveis ​​de ambiente

De acordo com o guia "The 12 Factor App" , os segredos são meramente configurações e sempre devem ser definidos no ambiente. Você pode definir seus segredos como variáveis ​​de ambiente durante a execução da janela de encaixe e o aplicativo os acessa a partir daí.

2 - Volumes montados

Você pode ter todos os seus segredos em um arquivo de configuração / segredos específico e montá-lo em sua instância como um volume montado .

3 - Buscar na loja secreta

Como @ 030 mencionado, você pode usar o Hashicorp Vault (ou "Amazon Secrets Manager" ou qualquer serviço desse tipo).
Seu aplicativo ou um side-car pode buscar diretamente os segredos de que precisa, sem precisar lidar com nenhuma configuração no contêiner do Docker. Esse método permite que você use segredos criados dinamicamente (um recurso muito atraente de tais sistemas) e sem ter que se preocupar com os segredos que podem ser visualizados no sistema de arquivos ou com a inspeção das variáveis ​​env do contêiner do docker.

Opinião pessoal

Eu acredito que as variáveis ​​env são o caminho a percorrer. É mais fácil de gerenciar, e você ainda pode obter de um armazenamento secreto como o Hashicorp Vault, se tiver o sistema de criação de CI, extrair os segredos durante a criação e defini-los quando você implantar. Você obtém o melhor dos dois mundos e o benefício adicional de seus desenvolvedores não precisarem escrever código de aplicativo para buscar segredos. Os desenvolvedores devem se concentrar em sua funcionalidade de código e não em tarefas administrativas, como a busca de senhas.

O código do seu aplicativo deve se concentrar na própria funcionalidade do aplicativo e não em tarefas de back-end, como buscar senhas. Assim como os 12 estados do App Fator.

Editar: última frase alterada para remover as implicações do silenciador Developer vs SysAdmin. As tarefas em si devem ser separadas da perspectiva do código, mas o DevOps é sobre as mesmas pessoas, mantendo em mente e não se limitando.

Opinião pessoal (atualização)

Pelo excelente comentário do Per @ Dirk ( Passando segredos para um contêiner do Docker ), há um argumento muito forte para priorizar um armazenamento secreto sobre os vars ENV, por não querer vazá-los.

BoomShadow
fonte
2
Isso promove silos. O DevOps está fazendo as coisas juntos, em vez de jogar coisas por cima do muro.
030
2
O código deve ser separado dos componentes da infraestrutura. As pessoas reais podem codificar a automação da infraestrutura e a base de códigos do aplicativo, mas as próprias tarefas devem ser separadas. Vejo que a última frase da minha resposta original foi silenciar os desenvolvedores, as pessoas. Isso é um erro. Vou editar isso para ficar mais claro.
BoomShadow
7
Colocar segredos em variáveis ​​de ambiente oferece várias possibilidades de vazamento. Alguns exemplos: todos com acesso ao daemon do Docker na máquina executando o contêiner podem vê-los usando os comandos inspectou exec. As variáveis ​​de ambiente geralmente são despejadas para stdoutou nos arquivos de log quando executadas em algum modo de depuração. Todos os processos filhos gerados podem ler e expô-los, o que pode estar fora de seu controle. Mais informações, por exemplo, aqui: diogomonica.com/2017/03/27/…
Dirk
1
Eu também estou lutando com esta questão. O que eu não entendo é que, mesmo se você usar um cofre de credenciais para proteger seus segredos, ainda precisará se autenticar para obter acesso a esse cofre e, presumivelmente, isso exige algum segredo. A mesma preocupação se aplica ao uso de um arquivo KeyStore protegido por senha. Estamos sempre presos a passar pelo menos a "meta credencial" no ambiente?
Wheezil 8/03
1
@Wheezil é mais fácil proteger uma meta credencial do que muitas credenciais específicas. você pode rotacionar frequentemente e automaticamente a meta credencial. a meta credencial pode ir para um cofre que está em um host seguro e pode ter coisas como a lista de permissões de IP, para que ele aceite apenas conexões das sub-redes de produção. você também pode garantir que o cofre use criptografia em repouso e criptografia em voo e tsl mútuo e fixação de certificados e todas as outras práticas recomendadas que tornam as coisas mais seguras.
simbo1905 9/03
1

Há outra opção apenas usando pipe:

docker run -d -i --name $n alpine sh -c 'read A; echo "[$A]"; exec some-server'
docker exec -i $n sh -c 'cat > /proc/1/fd/0' <<< _a_secret_

Primeiro, crie o daemon do docker com -io comando read Atravar aguardando a entrada de /proc/1/fd/0; Em seguida, execute o segundo comando do docker, lendo o segredo de stdin e redirecione para o último processo de interrupção.

James ZM Gao
fonte