Civil & Structural Engineering
Managing Docker Container Secrets with Hashicorp Vault
Table of Contents
Compreender a necessidade de uma gestão secreta segura no Docker
Os containers transformaram a implantação de aplicativos oferecendo ambientes leves e portáteis. No entanto, esta mudança ampliou o desafio de gerenciar dados sensíveis como chaves API, credenciais de banco de dados e certificados TLS. Segredos de codificação em imagens Docker, comprometendo-os ao controle de versões, ou passando-os como variáveis de ambiente simples introduz riscos de segurança significativos. Uma solução de gerenciamento secreto dedicado como HashiCorp Vault[] aborda esses riscos, fornecendo um sistema centralizado, auditável e dinâmico para armazenar e distribuir segredos para aplicativos containerizados.
O que é o Cofre HashiCorp?
HashiCorp Vault é uma ferramenta de código aberto projetada para armazenar e controlar com segurança o acesso a tokens, senhas, certificados e chaves de criptografia. Ele oferece uma interface unificada para gerenciamento de segredos, criptografia como serviço e acesso baseado em identidade. As características principais incluem:
- Segredos dinâmicos: Gerar credenciais de curta duração e com escopo a pedido (por exemplo, um usuário de banco de dados com contrato de locação 24 horas).
- Leasing and Renowal: Cada segredo tem uma duração de locação; aplicações devem renovar ou reautenticar, reduzindo o raio de explosão de um compromisso.
- Revogação: Invalide instantaneamente os segredos se uma aplicação ou usuário estiver comprometido.
- Auditar o registo: Registar todos os pedidos de acesso, proporcionando uma cadeia de custódia clara.
- Encriptação como um Serviço: Encriptar e descriptografar dados sem expor chaves a aplicações.
O Vault suporta vários secrets engines (valor chave, bases de dados, PKI, transit, etc.) e ] métodos de autenticação[ (tokens, AppRole, Kubernetes, LDAP, etc.), tornando-o adaptável a quase qualquer infra-estrutura.
Por que usar o Cofre com o Docker?
Integrar o Cofre com recipientes Docker traz várias vantagens sobre os métodos de injeção secretos tradicionais:
- Recuperação de tempo de execução: Os segredos são obtidos quando o recipiente começa ou sob demanda, nunca cozido na imagem. Isso elimina o risco de vazamento de segredos através de registros de imagem.
- Centralized Management: Um único cluster Vault gerencia segredos para todos os serviços de contêiner, reduzindo a deriva de configuração e simplificando a rotação.
- Créditas dinâmicas: Cada instância de container pode receber credenciais únicas e limitadas em tempo. Se um container for comprometido, a credencial expira rapidamente ou pode ser revogada centralmente.
- Audite Trails: Cada acesso secreto está registrado, ajudando a atender aos requisitos de conformidade (SOC 2, HIPAA, PCI DSS).
- Acesso baseado na política:ACLs de grãos finos garantem que cada recipiente só vê os segredos de que necessita (menos privilégio).
Arquitetura HashiCorp Vault para cargas de trabalho de container
Antes de mergulhar na integração, é útil entender a arquitetura de implantação do Vault. O Vault é executado como um servidor com uma infraestrutura de armazenamento ]key-value [ (Consul, etcd, armazenamento integrado de Raft ou armazenamento baseado em nuvem). Ele expõe uma API HTTP RESTful. Os clientes autenticam e recuperam segredos usando tokens, AppRole ou métodos baseados em identidade.
Para ambientes de contêineres, o Vault é frequentemente implantado de duas maneiras:
- Vault Server Cluster (produção): Um pedido de manuseio de cluster altamente disponível, selado/não selado de vários recipientes. Use o armazenamento integrado de Raft para simplicidade ou Cônsul para implantações maiores.
- Vault Dev Server (desenvolvimento): Uma instância de um único nó, em memória com auto-selo. Ideal para testes locais, mas nunca para produção.
Os containers interagem com o Vault através do oficial Vault CLI, a API HTTP, ou um agente sidecar (Agente de Vault) que lida com autenticação e busca secreta automaticamente.
Integrando o Cofre com o Docker: Padrões de Núcleo
Existem vários padrões comprovados para injetar segredos do Vault em recipientes Docker. A escolha depende da sua camada de orquestração e maturidade operacional.
1. Usando o CLI Vault em scripts de pontos de entrada
Este é o padrão mais simples. A imagem do recipiente inclui o CLI do Cofre, e um script de ponto de entrada autentica- se para o Cofre, obtém segredos e injecta- os na aplicação como variáveis de ambiente ou ficheiros.
# Dockerfile
FROM alpine:latest
RUN apk add --no-cache vault ca-certificates
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
# entrypoint.sh
#!/bin/sh
export VAULT_ADDR="http://vault.example.com:8200"
vault login -method=approle role_id="$ROLE_ID" secret_id="$SECRET_ID"
API_KEY=$(vault kv get -field=api_key secret/myapp)
export API_KEY
exec myapp
O recipiente recebe e como variáveis de ambiente (ou através de arquivos montados). Esta abordagem requer que o recipiente tenha acesso à rede ao Vault e ao binário Vault completo, o que aumenta o tamanho da imagem.
2. Agente de Vault Sidecar
[[FLT: 0]]O Vault Agent [[FLT: 1]] é um daemon que pode autenticar, obter segredos e transformá- los em arquivos ou modelos. Ele suporta um padrão de [[FLT: 2]]sidecar[[[FLT: 3]] onde o agente corre ao lado do recipiente primário no mesmo pod (Kubernetes) ou serviço Docker Compose. O agente renova automaticamente as locações e lida com a rotação secreta.
# config.hcl for Vault Agent
vault {
address = "http://vault.example.com:8200"
}
auto_auth {
method "approle" {
mount_path = "auth/approle"
config = {
role_id_file_path = "/tmp/role-id"
secret_id_file_path = "/tmp/secret-id"
}
}
}
template {
source = "/tmp/secrets.ctmpl"
destination = "/etc/secrets/app.env"
}
O agente observa o modelo para alterações e re- render a saída quando os segredos são renovados. Isto desacopla a recuperação secreta do código da aplicação.
O Docker Swarm tem um sistema secreto integrado, mas armazenar segredos em logs de Raft Swarm pode não atender às necessidades de conformidade. Um driver secreto de Vault de terceiros pode ser usado para encaminhar pedidos secretos de Swarm para Vault. Isso é menos comum, mas útil para organizações já investidas em Swarm.
4. Integração do Kubernetes com o Driver CSI
Para os utilizadores do Kubernetes, o Vault CSI Provider permite que os pods montem os segredos do Vault como volumes. Isto usa a Interface de Armazenamento de Contentores (CSI) para montar segredos sem quaisquer modificações de aplicações. Integra- se perfeitamente com o Driver CSI da Loja de Segredos do Kubernetes e suporta rotação automática.
Métodos de autenticação para contentores
Escolher o método de autenticação certo é fundamental para a segurança e automação. As opções comuns incluem:
- [[FLT: 0]]AppRole: Ideal para automação. O recipiente recebe um e um [[FLT: 6] (este último pode ser um símbolo embrulhado ou outro segredo). O recipiente troca-o por um símbolo de Vault.
- Kubernetes Auth: Ao correr em Kubernetes, Vault pode autenticar pods verificando tokens de contas de serviço. Nenhuma credencial explícita precisa ser distribuída.
- JWT/OIDC[: Adequado para ambientes nativos de nuvem onde os recipientes têm tokens JWT de um provedor de identidade confiável.
- Token: Mais simples, mas menos seguro. Os tokens podem ser pré-configurados em pipelines CI/CD ou injetados por orquestração.
Segredos dinâmicos: o poder real
Uma das características mais fortes do Vault para cargas de trabalho do Docker é ] segredos dinâmicos. Em vez de armazenar credenciais estáticas na loja de valor chave do Vault, Vault pode se conectar a um banco de dados (PostgreSQL, MySQL, MongoDB) e criar um usuário temporário em tempo real. O recipiente recebe esta credencial, usa-a, e quando o contrato expira (ou o recipiente morre), Vault apaga automaticamente o usuário.
# Example: Enable PostgreSQL secrets engine
vault secrets enable database
vault write database/config/my-postgres-database \
plugin_name=postgresql-database-plugin \
allowed_roles="my-role" \
connection_url="postgresql://{{username}}:{{password}}@postgres.example.com:5432/myapp" \
username="vault_admin" \
password="super_secret"
vault write database/roles/my-role \
db_name=my-postgres-database \
creation_statements="CREATE USER \"{{name}}\" WITH PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
default_ttl="1h" \
max_ttl="24h"
O recipiente então solicita uma credencial: . Isto retorna um nome de usuário/senha único válido por uma hora. Nenhuma credenciais estáticas são armazenadas em qualquer lugar.
Melhores Práticas para Acolhedor + Cofre
- Nunca segredes de código rígido em imagens. Use a injeção em tempo de execução exclusivamente.
- Use políticas de Vault menos privilégios. Cada recipiente ou serviço deve ser capaz de ler apenas seus próprios segredos e caminhos.
- Prefira o Vault Agent ou sidecars sobre a incorporação do Vault CLI em imagens. Ele simplifica o gerenciamento do ciclo de vida e reduz o tamanho da imagem.
- Rotate AppRole SecretIDs frequentemente. Use ou fichas periódicas para minimizar a exposição.
- Permite o registo de auditorias em Vault e em Ship logs para um SIEM central.
- Secure Vault self:] Use TLS para toda a comunicação, não sele via auto-unseal (KMS, nuvem HSM), e restringir o acesso de rede ao Vault apenas para orquestradores e containers.
- Renovação secreta manual graciosamente. As aplicações devem ser capazes de atualizar credenciais sem reiniciar. Os modelos do Vault Agent ou mecanismos de monitoramento de ambiente ajudam.
- Teste para cenários de falha: Simule tempo de inatividade do Vault, partições de rede e expiração do token para garantir que as aplicações se degradam graciosamente.
- Use TTLs curtos para segredos dinâmicos e tokens para limitar a exposição se um recipiente estiver comprometido.
- Considere uma camada de cache secreta (por exemplo, cache do Vault Agent) para reduzir a carga no Vault e melhorar o desempenho para ambientes de alta qualidade.
Comparação com Alternativas
Embora Vault seja uma solução líder, vale a pena entender como se compara a outras abordagens:
- Docker Native Secrets (Swarm): Simples, mas limitado a segredos estáticos, sem geração dinâmica, trilha de auditoria ou políticas de grãos finos. Armazenado em logs de raft, que podem não satisfazer o cumprimento rigoroso.
- Kubernetes Secrets: Base de segredos estáticos básicos64 codificados em etcd. Sem criptografia em repouso (que requer configuração extra) eles podem ser inseguros. Nenhum gerenciamento central entre clusters.
- Provider Secret Managers (AWS Secrets Manager, Azure Key Vault, GCP Secret Manager): Boa integração com os seus ecossistemas, mas bloqueio. Normalmente, não existem segredos dinâmicos para bases de dados ou PKI tão flexíveis como Vault.
- CyberArk Conjur: Concentrado em empresas, forte na gestão de acesso privilegiada, mas mais complexo e caro do que o Vault para casos de uso de contentores.
O Vault consegue um equilíbrio entre flexibilidade de código aberto, riqueza de recursos e suporte de plataforma ampla, tornando-o uma escolha popular para implantações de Docker multinuvem e híbridas.
Configurar um Vault de Grade de Produção para Docker
- Implantar um cluster de vault altamente disponível : Use o gráfico oficial do Vault Helm em Kubernetes, ou execute Vault em modo HA manual com armazenamento de raft. Certifique-se de pelo menos três nós.
- Configure Auto-Unseal: Use uma nuvem KMS (AWS KMS, Azure Key Vault, GCP Cloud KMS) ou HSM. Nunca guarde chaves por selar no mesmo cluster que Vault.
- Ativar dispositivos de auditoria: Envie registros de auditoria para o stdout e uma loja externa segura.
- Set Up Policys and Roles: Criar políticas para cada serviço (por exemplo, ]). Ligar estas funções às funções do AppRole ou às contas de serviço do Kubernetes.
- Integrar-se com a Orquestração: Em Kubernetes, instale o Fornecedor de CSI ou Injector de Vault (mutando o webhook). Para o Docker em bruto, use os recipientes de sidecar do Vault Agent via Docker Compose.
- Test Dynamic Secrets: Habilite o mecanismo de segredos de banco de dados e crie funções. Verifique se os recipientes podem solicitar e usar credenciais temporárias.
- Implementar a Integração CI/CD: No seu gasoduto, use a API do Vault para fornecer tokens temporários para cada etapa de construção, evitando credenciais estáticas.
Considerações de segurança além do armazenamento secreto
Usando Vault reduz o risco de exposição secreta, mas não elimina todos os vetores de ataque:
- Segurança de rede: Certifique-se de que o Vault não está exposto à internet pública. Use DNS e TLS interna autenticação mútua, se possível.
- Procedência de imagem[: Verifique se as imagens de base e os pacotes extraídos são de registos de confiança. Uma imagem comprometida pode exfiltrar segredos antes da injecção do Vault.
- Monitorização de tempo de execução: Use ferramentas de segurança de container (Falco, Tracee, AppArmor) para detectar execuções inesperadas de processos ou acessos de arquivos.
- Secret sprawl: Mesmo com o Vault, os desenvolvedores ainda podem codificar segredos em arquivos de ambiente para testes locais. Aplique políticas e use os proxies Vault dev.
- Gestão de locação : Aplicações que não renovam locações podem perder acesso em momentos críticos. Implementar verificações de saúde e mecanismos de recuo.
Caso de uso do mundo real: Microservices com Credenciais de Banco de Dados
Considere uma plataforma de comércio eletrônico com 20 microservices, cada um conectando-se a um banco de dados PostgreSQL específico. Sem Vault, cada serviço tem um usuário/senha de banco de dados codificados em seu manifesto de implantação ou imagem. Senhas rotativas requerem reimplantar todos os serviços. Com Vault:
- Cada serviço autentica-se através do AppRole ou do Kubernetes auth.
- Todos os serviços solicitam credenciais dinâmicas de banco de dados na inicialização.
- As credenciais são válidas por 1 hora e renovadas automaticamente pelo Vault Agent.
- Se um serviço for comprometido, o operador revoga todas as suas locações ativas em um comando.
- Os registros de auditoria de banco de dados mostram usuários temporários criados, reduzindo o raio de explosão de qualquer credencial roubado.
Este padrão reduz a sobrecarga operacional e melhora significativamente a postura de segurança.
Pistas comuns e como evitá - las
- Esquecer de selar/desselar Vault: Na produção, Vault começa selado. Automatizado desencarregamento (via auto-seal) é essencial.
- Exposição de fichas de Vault em logs: Use resposta-embrulho ou Vault Agent para evitar fichas que aparecem em logs de containers.
- Mistura de segredos estáticos e dinâmicos: Evite guardar segredos estáticos de longa duração na loja KV do Vault para cargas de trabalho de contentores. Use segredos dinâmicos sempre que possível.
- Não está planejando o tempo de inatividade do Vault: Segredos de cache com caches conscientes de TTL, ou usar sidecars que podem servir segredos obsoletos temporariamente.
- Políticas permissivas: Uma política que concede a um container de frontend poderia expor senhas de banco de dados de backend. Aplicar o menor privilégio estritamente.
Conclusão
Integrar o HashiCorp Vault com recipientes Docker é uma boa prática para qualquer organização séria sobre segurança, conformidade e eficiência operacional. Ao passar de segredos estáticos e codificados para um ciclo de vida secreto dinâmico e gerenciado centralmente, você reduz o risco, simplifica rotações e ganha total auditabilidade. Se você usa sidecars de agente, CSI Kubernetes ou scripts personalizados de ponto de entrada, o Vault fornece uma base robusta para gerenciamento secreto em ambientes containerizados. Comece com um único serviço, e depois expanda em toda sua frota – seu futuro eu (e sua equipe de segurança) irá agradecer.
Para mais informações, consultar a documentação oficial do Vault , a panorâmica do Docker Secrets , e o guia de provedores de Vault CSI.