Problema: "Posso gerenciar todas as configurações do meu K8s no git, exceto segredos."
Solução: criptografe seu segredo em um SealedSecret, que pode ser armazenado com segurança - mesmo dentro de um repositório público. O SealedSecret pode ser descriptografado apenas pelo controlador em execução no cluster de destino e ninguém mais (nem mesmo o autor original) é capaz de obter o segredo original do SealedSecret.
Visão geral
SealedSecrets como modelos para segredos
Chave pública/Certificado
Escopos
Instalação
Cerveja caseira
MacPorts
Linux
Instalação da fonte
Personalizar
Gráfico do Helm
Controlador
Kubeseal
Atualizar
Uso
Gerenciando segredos existentes
Corrigindo segredos existentes
Atualizar segredos existentes
Modo bruto (experimental)
Valide um segredo selado
Rotação Secreta
Selagem de renovação de chave
Rotação secreta do usuário
Renovação antecipada da chave
Equívocos comuns sobre renovação de chaves
Gerenciamento manual de chaves (avançado)
Recriptografia (avançado)
Detalhes (avançado)
Criptografia
Em desenvolvimento
Perguntas frequentes
Você ainda poderá descriptografar se não tiver mais acesso ao seu cluster?
Como posso fazer um backup dos meus SealedSecrets?
Posso descriptografar meus segredos offline com uma chave de backup?
Quais bandeiras estão disponíveis para o kubeseal?
Como atualizo partes do arquivo JSON/YAML/TOML/.. criptografado com segredos selados?
Posso trazer meus próprios certificados (pré-gerados)?
Como usar o kubeseal se o controlador não estiver sendo executado no namespace kube-system
?
Como verificar as imagens?
Como usar um controlador para um subconjunto de namespaces
Posso configurar as novas tentativas de desbloqueio do controlador
Comunidade
Projetos relacionados
Segredos Selados é composto de duas partes:
Um controlador/operador do lado do cluster
Um utilitário do lado do cliente: kubeseal
O utilitário kubeseal
usa criptografia assimétrica para criptografar segredos que somente o controlador pode descriptografar.
Esses segredos criptografados são codificados em um recurso SealedSecret
, que você pode ver como uma receita para criar um segredo. Aqui está como parece:
apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata: nome: mysecret namespace: mynamespacespec: criptografadoData: foo: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....
Uma vez aberto, isso produzirá um segredo equivalente a este:
apiVersion: v1kind: Secretmetadata: name: mysecret namespace: mynamespacedata: foo: YmFy # <- "bar" codificado em base64
Este segredo normal do Kubernetes aparecerá no cluster após alguns segundos. Você pode usá-lo como usaria qualquer segredo que teria criado diretamente (por exemplo, referenciá-lo a partir de um Pod
).
Vá para a seção Instalação para começar a trabalhar.
A seção Uso explora com mais detalhes como você cria recursos SealedSecret
.
O exemplo anterior se concentrou apenas nos próprios itens secretos criptografados, mas o relacionamento entre um recurso personalizado SealedSecret
e o Secret
no qual ele é aberto é semelhante em muitos aspectos (mas não em todos eles) ao familiar Deployment
vs Pod
.
Em particular, as anotações e rótulos de um recurso SealedSecret
não são iguais às anotações do Secret
gerado a partir dele.
Para capturar essa distinção, o objeto SealedSecret
possui uma seção template
que codifica todos os campos que você deseja que o controlador coloque no Secret
não selado.
A biblioteca de funções Sprig está disponível além das funções padrão do Go Text Template.
O bloco metadata
é copiado como está (o campo ownerReference
será atualizado, a menos que seja desabilitado).
Outros campos secretos são tratados individualmente. Os campos type
e immutable
são copiados, e o campo data
pode ser usado para modelar valores complexos no Secret
. Todos os outros campos são atualmente ignorados.
apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata: nome: mysecret namespace: mynamespace anotações: "kubectl.kubernetes.io/last-applied-configuration": ....spec:cryptedData: .dockerconfigjson: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.... .modelo: digite: kubernetes.io/dockerconfigjson immutable: true # este é um exemplo de rótulos e anotações que serão adicionados aos metadados secretos de saída: rótulos: "jenkins.io/credentials-type": usernamePassword annotations: "jenkins.io/credentials-description ": credenciais do Kubernetes
O controlador iria revelar isso em algo como:
apiVersion: v1kind: Secretmetadata: nome: mysecret namespace: mynamespace rótulos: "jenkins.io/credentials-type": nome de usuárioAnotações de senha: "jenkins.io/credentials-description": credenciais do proprietário do KubernetesReferências: - apiVersion: bitnami.com/v1alpha1 controlador: true kind: SealedSecret nome: mysecret uid: 5caff6a0-c9ac-11e9-881e-42010aac003etype: kubernetes.io/dockerconfigjsonimmutable: truedata: .dockerconfigjson: ewogICJjcmVk...
Como você pode ver, o recurso Secret
gerado é um "objeto dependente" do SealedSecret
e, como tal, será atualizado e excluído sempre que o objeto SealedSecret
for atualizado ou excluído.
O certificado de chave (parte da chave pública) é usado para selar segredos e precisa estar disponível onde quer que kubeseal
seja usado. O certificado não é uma informação secreta, embora você precise garantir que está usando o certificado correto.
kubeseal
buscará o certificado do controlador em tempo de execução (requer acesso seguro ao servidor da API Kubernetes), o que é conveniente para uso interativo, mas é conhecido por ser frágil quando os usuários têm clusters com configurações especiais, como clusters privados do GKE que possuem firewalls entre plano de controle e nós.
Um fluxo de trabalho alternativo é armazenar o certificado em algum lugar (por exemplo, disco local) com kubeseal --fetch-cert >mycert.pem
e usá-lo offline com kubeseal --cert mycert.pem
. O certificado também é impresso no log do controlador na inicialização.
Desde a v0.9.x, os certificados são renovados automaticamente a cada 30 dias. É uma boa prática que você e sua equipe atualizem seu certificado offline periodicamente. Para ajudá-lo com isso, desde a v0.9.2 kubeseal
também aceita URLs. Você pode configurar sua automação interna para publicar certificados em algum lugar de sua confiança.
kubeseal --cert https://your.intranet.company.com/sealed-secrets/your-cluster.cert
Ele também reconhece o env var SEALED_SECRETS_CERT
. (dica profissional: veja também direnv).
NOTA : estamos trabalhando para fornecer mecanismos de gerenciamento de chaves que transferem a criptografia para módulos baseados em HSM ou soluções de criptografia em nuvem gerenciadas, como KMS.
SealedSecrets são do ponto de vista de um usuário final, um dispositivo "somente gravação".
A ideia é que o SealedSecret possa ser descriptografado apenas pelo controlador em execução no cluster de destino e ninguém mais (nem mesmo o autor original) seja capaz de obter o segredo original do SealedSecret.
O usuário pode ou não ter acesso direto ao cluster de destino. Mais especificamente, o usuário pode ou não ter acesso ao segredo não lacrado pelo controlador.
Há muitas maneiras de configurar o RBAC em k8s, mas é bastante comum proibir usuários de baixo privilégio de ler segredos. Também é comum conceder aos usuários um ou mais namespaces onde eles tenham privilégios mais altos, o que lhes permitiria criar e ler segredos (e/ou criar implantações que possam fazer referência a esses segredos).
Os recursos criptografados SealedSecret
são projetados para serem vistos com segurança, sem obter qualquer conhecimento sobre os segredos que escondem. Isso implica que não podemos permitir que os usuários leiam um SealedSecret destinado a um namespace ao qual eles não teriam acesso e apenas enviem uma cópia dele em um namespace de onde possam ler segredos.
Sealed-secrets, portanto, se comporta como se cada namespace tivesse sua própria chave de criptografia independente e, assim, depois que você selar um segredo para um namespace, ele não poderá ser movido para outro namespace e descriptografado lá.
Tecnicamente, não usamos uma chave privada independente para cada namespace, mas incluímos o nome do namespace durante o processo de criptografia, obtendo efetivamente o mesmo resultado.
Além disso, os namespaces não são o único nível no qual as configurações do RBAC podem decidir quem pode ver qual segredo. Na verdade, é possível que os usuários possam acessar um segredo chamado foo
em um determinado namespace, mas não qualquer outro segredo no mesmo namespace. Portanto, não podemos, por padrão, permitir que os usuários renomeiem livremente os recursos SealedSecret
caso contrário, um usuário mal-intencionado seria capaz de descriptografar qualquer SealedSecret para esse namespace apenas renomeando-o para substituir o único segredo ao qual o usuário tem acesso. Usamos o mesmo mecanismo usado para incluir o namespace na chave de criptografia para incluir também o nome secreto.
Dito isto, existem muitos cenários em que você pode não se importar com esse nível de proteção. Por exemplo, as únicas pessoas que têm acesso aos seus clusters são administradores ou não podem ler nenhum recurso Secret
. Você pode ter um caso de uso para mover um segredo selado para outros namespaces (por exemplo, você pode não saber o nome do namespace antecipadamente) ou pode não saber o nome do segredo (por exemplo, ele pode conter um sufixo exclusivo baseado no hash do conteúdos, etc.).
Estes são os escopos possíveis:
strict
(padrão): o segredo deve ser selado exatamente com o mesmo nome e namespace . Esses atributos tornam-se parte dos dados criptografados e, portanto, alterar o nome e/ou o namespace levaria a um "erro de descriptografia".
namespace-wide
: você pode renomear livremente o segredo selado dentro de um determinado namespace.
cluster-wide
: o segredo pode ser aberto em qualquer namespace e pode receber qualquer nome.
Em contraste com as restrições de name e namespace , itens secretos (ou seja, chaves de objeto JSON como spec.encryptedData.my-key
) podem ser renomeados à vontade sem perder a capacidade de descriptografar o segredo selado.
O escopo é selecionado com o sinalizador --scope
:
kubeseal --scope em todo o clustersealed-secret.json
Também é possível solicitar um escopo por meio de anotações no segredo de entrada que você passa para kubeseal
:
sealedsecrets.bitnami.com/namespace-wide: "true"
-> para namespace-wide
sealedsecrets.bitnami.com/cluster-wide: "true"
-> para cluster-wide
A falta de qualquer uma dessas anotações significa modo strict
. Se ambos estiverem definidos, cluster-wide
terá precedência.
NOTA: A próxima versão consolidará isso em uma única anotação
sealedsecrets.bitnami.com/scope
.
Consulte https://github.com/bitnami-labs/sealed-secrets/releases para obter a versão mais recente e instruções detalhadas de instalação.
Notas e instruções específicas da plataforma Cloud:
GKE
Depois de implantar o manifesto, ele criará o recurso SealedSecret
e instalará o controlador no namespace kube-system
, criará uma conta de serviço e as funções RBAC necessárias.
Após alguns instantes, o controlador será iniciado, gerará um par de chaves e estará pronto para operação. Caso contrário, verifique os logs do controlador.
O mecanismo oficial de instalação do manifesto do controlador é apenas um arquivo YAML.
Em alguns casos, pode ser necessário aplicar suas próprias personalizações, como definir um namespace personalizado ou definir algumas variáveis de ambiente.
kubectl
tem suporte nativo para isso, consulte kustomize.
O gráfico do leme Sealed Secrets agora é oficialmente suportado e hospedado neste repositório GitHub.
helm repo adicionar segredos selados https://bitnami-labs.github.io/sealed-secrets
NOTA: O esquema de versão do gráfico do leme difere do esquema de versão do próprio projeto de segredos selados.
Originalmente, o gráfico de leme era mantido pela comunidade e a primeira versão adotou uma versão principal de 1, enquanto o projeto de segredos selados em si ainda está em 0. Isso é aceitável porque a versão do gráfico de leme em si não se destina a ser necessariamente a versão do próprio aplicativo. No entanto, isso é confuso, então nossa regra atual de controle de versão é:
O esquema de versão do controlador SealedSecret
: 0.XY
O esquema da versão do gráfico do leme: 1.XY-rZ
Portanto, pode haver diversas revisões do gráfico do leme, com correções que se aplicam apenas ao gráfico do leme, sem afetar os manifestos YAML estáticos ou a própria imagem do controlador.
NOTA: O leia-me do gráfico do helm ainda contém um aviso de descontinuação, mas não reflete mais a realidade e será removido na próxima versão.
NOTA: O gráfico do helm, por padrão, instala o controlador com o nome
sealed-secrets
, enquanto a interface de linha de comando (CLI)kubeseal
tenta acessar o controlador com o nomesealed-secrets-controller
. Você pode passar--controller-name
explicitamente para a CLI:
kubeseal --controller-name segredos selados
Como alternativa, você pode definir fullnameOverride
ao instalar o gráfico para substituir o nome. Observe também que kubeseal
assume que o controlador está instalado no namespace kube-system
por padrão. Portanto, se você quiser usar a CLI kubeseal
sem precisar passar o nome e o namespace esperados do controlador, você deve instalar o Helm Chart assim:
helm install sealed-secrets -n kube-system --set-string fullnameOverride=sealed-secrets-controller sealed-secrets/sealed-secrets
Em algumas empresas, você pode ter acesso apenas a um único namespace, e não a um cluster completo.
Um dos ambientes mais restritivos que você pode encontrar é:
Um namespace
foi alocado para você com alguma service account
.
Você não tem acesso ao restante do cluster, nem mesmo aos CRDs do cluster.
Talvez você nem consiga criar outras contas de serviço ou funções em seu namespace.
É necessário incluir limites de recursos em todas as suas implantações.
Mesmo com essas restrições você ainda pode instalar os segredos selados do Helm Chart, há apenas um pré-requisito:
O cluster já deve ter os CRDs de segredos selados instalados .
Depois que seus administradores instalarem os CRDs, se eles ainda não estiverem lá, você poderá instalar o gráfico preparando um arquivo de configuração YAML como este:
conta de serviço: criar: falso nome: {conta de serviço alocada} rbac: criar: falso clusterRole: recursos falsos: limites: CPU: 150m memória: 256Mi
Observe que:
Nenhuma conta de serviço é criada; em vez disso, será usada aquela alocada a você.
{allocated-service-account}
é o nome da service account
que você recebeu no cluster.
Nenhuma função RBAC é criada no namespace nem no cluster.
Os limites de recursos devem ser especificados.
Os limites são exemplos que devem funcionar, mas você pode querer revisá-los em sua configuração específica.
Assim que o arquivo estiver pronto, se você o nomeou config.yaml
agora você pode instalar os segredos selados do Helm Chart assim:
helm instalar segredos selados -n {espaço de nome alocado} segredos selados/segredos selados --skip-crds -f config.yaml
Onde {allocated-namespace}
é o nome do namespace
que você foi alocado no cluster.
O cliente kubeseal
também está disponível no homebrew:
preparar instalar kubeseal
O cliente kubeseal
também está disponível em MacPorts:
porta instalar kubeseal
O cliente kubeseal
também está disponível no Nixpkgs: ( AVISO LEGAL : Não mantido por bitnami-labs)
nix-env -iA nixpkgs.kubeseal
O cliente kubeseal
pode ser instalado no Linux, usando os comandos abaixo:
KUBESEAL_VERSION='' # Defina como, por exemplo, KUBESEAL_VERSION='0.23.0'curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION:?} /kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz"tar -xvzf kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz kubeseal sudo install -m 755 kubeseal /usr/local/bin/kubeseal
Se você tiver curl
e jq
instalados em sua máquina, poderá obter a versão dinamicamente desta forma. Isso pode ser útil para ambientes usados em automação e similares.
# Fetch the latest sealed-secrets version using GitHub API KUBESEAL_VERSION=$(curl -s https://api.github.com/repos/bitnami-labs/sealed-secrets/tags | jq -r '.[0].name' | cut -c 2-) # Check if the version was fetched successfully if [ -z "$KUBESEAL_VERSION" ]; then echo "Failed to fetch the latest KUBESEAL_VERSION" exit 1 fi curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz" tar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz kubeseal sudo install -m 755 kubeseal /usr/local/bin/kubeseal
onde KUBESEAL_VERSION
é a tag de versão da versão do kubeseal que você deseja usar. Por exemplo: v0.18.0
.
Se você deseja apenas a ferramenta cliente mais recente, ela pode ser instalada em $GOPATH/bin
com:
vá instalar github.com/bitnami-labs/sealed-secrets/cmd/kubeseal@main
Você pode especificar uma tag de lançamento ou um SHA de commit em vez de main
.
O comando go install
colocará o binário kubeseal
em $GOPATH/bin
:
$(go env GOPATH)/bin/kubeseal
Não se esqueça de verificar as notas de lançamento para obter orientação sobre possíveis alterações importantes ao atualizar a ferramenta cliente e/ou o controlador.
Atualmente, apenas a versão mais recente do Sealed Secrets é compatível com ambientes de produção.
O controlador Sealed Secrets garante compatibilidade com diferentes versões do Kubernetes, contando com uma API Kubernetes estável. Normalmente, as versões do Kubernetes acima de 1.16 são consideradas compatíveis. No entanto, oferecemos suporte oficial às versões atualmente recomendadas do Kubernetes. Além disso, as versões acima de 1.24 passam por verificação completa através do nosso processo de CI a cada lançamento.
# Crie um segredo codificado em json/yaml de alguma forma:# (observe o uso de `--dry-run` - este é apenas um arquivo local!)echo -n bar | kubectl criar segredo genérico mysecret --dry-run=client --from-file=foo=/dev/stdin -o json >mysecret.json# Esta é a parte importante:kubeseal -f mysecret.json -w mysealedsecret.json# Neste ponto, mysealedsecret.json é seguro para carregar no Github,# postar no Twitter, etc.# Eventualmente:kubectl create -f mysealedsecret.json# Lucro!kubectl obter segredo mysecret
Observe que SealedSecret
e Secret
devem ter o mesmo namespace e name . Este é um recurso para evitar que outros usuários no mesmo cluster reutilizem seus segredos lacrados. Consulte a seção Escopos para obter mais informações.
kubeseal
lê o namespace do segredo de entrada, aceita um argumento --namespace
explícito e usa o namespace padrão kubectl
(nessa ordem). Quaisquer rótulos, anotações, etc. no Secret
original são preservados, mas não são refletidos automaticamente no SealedSecret
.
Por design, esse esquema não autentica o usuário . Em outras palavras, qualquer pessoa pode criar um SealedSecret
contendo qualquer Secret
que desejar (desde que o namespace/nome corresponda). Depende do seu fluxo de trabalho de gerenciamento de configuração existente, regras RBAC do cluster, etc., garantir que apenas o SealedSecret
pretendido seja carregado no cluster. A única mudança em relação ao Kubernetes existente é que o conteúdo do Secret
agora fica oculto fora do cluster.
Se quiser que o controlador Sealed Secrets gerencie um Secret
existente, você pode anotar seu Secret
com a anotação sealedsecrets.bitnami.com/managed: "true"
. O Secret
existente será substituído ao abrir um SealedSecret
com o mesmo nome e namespace, e o SealedSecret
assumirá a propriedade do Secret
(de modo que quando o SealedSecret
for excluído, o Secret
também será excluído).
Novo na v0.23.0
Existem alguns casos de uso em que você não deseja substituir todo o Secret
, mas apenas adicionar ou modificar algumas chaves do Secret
existente. Para isso, você pode anotar seu Secret
com sealedsecrets.bitnami.com/patch: "true"
. Usar esta anotação garantirá que as chaves secretas, rótulos e anotações no Secret
que não estão presentes no SealedSecret
não serão excluídas, e aqueles presentes no SealedSecret
serão adicionados ao Secret
(chaves secretas, rótulos e anotações que existem tanto no Secret
quanto no SealedSecret
serão modificados pelo SealedSecret
).
Esta anotação não faz com que SealedSecret
se aproprie do Secret
. Você pode adicionar o patch
e as anotações managed
para obter o comportamento do patch e, ao mesmo tempo, assumir a propriedade do Secret
.
Se você deseja que SealedSecret
e o Secret
sejam independentes, o que significa que quando você exclui o SealedSecret
o Secret
não desaparecerá com ele, então você deve anotar esse segredo com a anotação sealedsecrets.bitnami.com/skip-set-owner-references: "true"
antes de aplicar as etapas de uso. Você ainda pode adicionar sealedsecrets.bitnami.com/managed: "true"
ao seu Secret
para que seu segredo seja atualizado quando SealedSecret
for atualizado.
Se você quiser adicionar ou atualizar segredos selados existentes sem ter o texto não criptografado para os outros itens, basta copiar e colar os novos itens de dados criptografados e mesclá-los em um segredo selado existente.
Você deve selar os itens atualizados com um nome e namespace compatíveis (veja nota sobre escopos acima).
Você pode usar o comando --merge-into
para atualizar segredos selados existentes se não quiser copiar e colar:
eco -n barra | kubectl cria segredo genérico mysecret --dry-run=client --from-file=foo=/dev/stdin -o json | kubeseal > mysealedsecret.jsonecho -n baz | kubectl cria segredo genérico mysecret --dry-run=client --from-file=bar=/dev/stdin -o json | kubeseal --merge-into mysealedsecret.json
Criar um segredo temporário com o comando kubectl
, apenas para jogá-lo fora depois de canalizado para kubeseal
pode ser uma experiência de usuário bastante hostil. Estamos trabalhando em uma reformulação da experiência CLI. Enquanto isso, oferecemos um modo alternativo em que o kubeseal se preocupa apenas em criptografar um valor para stdout, e é sua responsabilidade colocá-lo dentro de um recurso SealedSecret
(não diferente de qualquer outro recurso k8s).
Também pode ser útil como um bloco de construção para integrações editor/IDE.
A desvantagem é que você precisa ter cuidado para ser consistente com o escopo de vedação, o namespace e o nome.
Ver escopos
escopo strict
(padrão):
$ echo -n foo | kubeseal --raw --namespace bar --name meusecretAgBChHUWLMx...
escopo namespace-wide
:
$ echo -n foo | kubeseal --raw --namespace bar --scope namespace-wideAgAbbFNkM54...
Inclua a anotação sealedsecrets.bitnami.com/namespace-wide
no SealedSecret
metadados: anotações: sealedsecrets.bitnami.com/namespace-wide: "true"
escopo cluster-wide
:
$ echo -n foo | kubeseal --raw --scope cluster-wideAgAjLKpIYV+...
Inclua a anotação sealedsecrets.bitnami.com/cluster-wide
no SealedSecret
metadados: anotações: sealedsecrets.bitnami.com/cluster-wide: "true"
Se você deseja validar um segredo selado existente, kubeseal
possui o sinalizador --validate
para ajudá-lo.
Fornecendo um arquivo chamado sealed-secrets.yaml
contendo o seguinte segredo selado:
apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata: nome: mysecret namespace: mynamespacespec: criptografadoData: foo: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....
Você pode validar se o segredo lacrado foi criado corretamente ou não:
$ gato selado-secrets.yaml | kubeseal --validar
No caso de um segredo selado inválido, kubeseal
mostrará:
$ gato selado-secrets.yaml | kubeseal --validateerror: incapaz de descriptografar o segredo selado
Você deve sempre alternar seus segredos. Mas como seus segredos são criptografados com outro segredo, você precisa entender como essas duas camadas se relacionam para tomar as decisões corretas.
DR:
Se uma chave privada de vedação for comprometida, você precisará seguir as instruções abaixo na seção "Renovação antecipada da chave" antes de rotacionar qualquer um dos seus valores secretos reais.
Os recursos de renovação e nova criptografia da chave SealedSecret não substituem a rotação periódica de seus valores secretos reais.
As chaves de selamento são renovadas automaticamente a cada 30 dias. O que significa que uma nova chave de vedação é criada e anexada ao conjunto de chaves de vedação ativas que o controlador pode usar para liberar recursos SealedSecret
.
A chave de vedação criada mais recentemente é aquela usada para selar novos segredos quando você usa kubeseal
e é aquela cujo certificado é baixado quando você usa kubeseal --fetch-cert
.
O tempo de renovação de 30 dias é um padrão razoável, mas pode ser ajustado conforme necessário com o sinalizador --key-renew-period=
para o comando no modelo de pod do controlador SealedSecret
. O campo value
pode ser fornecido como sinalizador de duração golang (por exemplo: 720h30m
). Supondo que você instalou Sealed Secrets no namespace kube-system
, use o comando a seguir para editar o controlador de implantação e adicione o parâmetro --key-renew-period
. Depois de fechar o editor de texto e o controlador de implantação ter sido modificado, um novo pod será criado automaticamente para substituir o pod antigo.
kubectl edit deployment/sealed-secrets-controller --namespace=kube-system
Um valor 0
desativará a renovação automática da chave. É claro que você pode ter um caso de uso válido para desativar a renovação automática de chaves seladas, mas a experiência mostra que novos usuários muitas vezes tendem a tirar conclusões precipitadas de que desejam ter controle sobre a renovação de chaves, antes de compreenderem completamente como funcionam os segredos selados. Leia mais sobre isso na seção de equívocos comuns abaixo.
Infelizmente, você não pode usar, por exemplo, "d" como unidade por dias porque isso não é suportado pelo Go stdlib. Em vez de bater no rosto com a palma da mão, aproveite esta oportunidade para meditar sobre as falsidades que os programadores acreditam sobre o tempo.
Um mal-entendido comum é que a renovação de chaves é muitas vezes vista como uma forma de rotação de chaves, onde a chave antiga não é apenas obsoleta, mas na verdade ruim e, portanto, você deseja se livrar dela. Não ajuda o fato de esse recurso ter sido historicamente chamado de “rotação de teclas”, o que pode aumentar a confusão.
Os segredos selados não são alternados automaticamente e as chaves antigas não são excluídas quando novas chaves são geradas. Os recursos antigos SealedSecret
ainda podem ser descriptografados (isso ocorre porque as chaves de vedação antigas não são excluídas).
A renovação da chave de selamento e a rotação do SealedSecret não substituem a rotação de seus segredos reais.
Uma proposta de valor central desta ferramenta é:
Criptografe seu segredo em um SealedSecret, que pode ser armazenado com segurança - mesmo dentro de um repositório público.
Se você armazenar algo em um armazenamento de controle de versão, e em um armazenamento público em particular, você deve assumir que nunca poderá excluir essas informações.
Se uma chave de vedação de alguma forma vazar do cluster, você deverá considerar todos os seus recursos SealedSecret
criptografados com essa chave como comprometidos. Nenhuma quantidade de rotação de chaves de vedação no cluster ou mesmo a nova criptografia de arquivos SealedSecrets existentes pode mudar isso.
A melhor prática é alternar periodicamente todos os seus segredos reais (por exemplo, alterar a senha) e criar novos recursos SealedSecret
com esses novos segredos.
Mas se o controlador SealedSecret
não estivesse renovando a chave de selamento , essa rotação seria discutível, já que o invasor também poderia descriptografar os novos segredos. Assim, você precisa fazer as duas coisas: renovar periodicamente a chave de selamento e rodar seus segredos reais!
Se você sabe ou suspeita que uma chave de selamento foi comprometida, renove a chave o mais rápido possível antes de começar a selar seus novos segredos rotacionados, caso contrário, você também estará dando aos invasores acesso aos seus novos segredos.
Uma chave pode ser gerada antecipadamente, passando o carimbo de data/hora atual para o controlador em um sinalizador chamado --key-cutoff-time
ou um env var chamado SEALED_SECRETS_KEY_CUTOFF_TIME
. O formato esperado é RFC1123, você pode gerá-lo com o comando date -R
unix.
As chaves seladas de segredos não são chaves de controle de acesso (por exemplo, uma senha). Eles são mais parecidos com a chave GPG que você pode usar para ler mensagens criptografadas enviadas a você. Vamos continuar um pouco com a analogia do e-mail:
Imagine que você tem motivos para acreditar que sua chave GPG privada pode ter sido comprometida. Você teria mais a perder do que a ganhar se a primeira coisa a fazer fosse simplesmente excluir sua chave privada. Todos os e-mails anteriores enviados com essa chave não estarão mais acessíveis para você (a menos que você tenha uma cópia descriptografada desses e-mails), nem novos e-mails serão enviados por seus amigos a quem você ainda não conseguiu dizer para usar a nova chave.
Claro, o conteúdo desses e-mails criptografados não é seguro, pois um invasor pode agora ser capaz de descriptografá-los, mas o que está feito está feito. Sua perda repentina da capacidade de ler esses e-mails certamente não desfaz o dano. Na verdade, é pior porque você não sabe mais ao certo qual segredo o invasor descobriu. O que você realmente quer fazer é garantir que seu amigo pare de usar sua chave antiga e que, de agora em diante, todas as comunicações futuras sejam criptografadas com um novo par de chaves (ou seja, seu amigo deve saber sobre essa nova chave).
A mesma lógica se aplica a SealedSecrets. O objetivo final é proteger seus segredos reais de “usuário”. Os segredos de “selagem” são apenas um mecanismo, um “envelope”. Se um segredo vazar não há como voltar atrás, o que está feito está feito.
Primeiro você precisa garantir que novos segredos não sejam criptografados com a antiga chave comprometida (na analogia do e-mail acima: crie um novo par de chaves e dê a todos os seus amigos sua nova chave pública).
O segundo passo lógico é neutralizar o dano, que depende da natureza do segredo. Um exemplo simples é uma senha de banco de dados: se você acidentalmente vazar sua senha de banco de dados, o que você deve fazer é simplesmente alterar sua senha de banco de dados (no banco de dados; e revogar a antiga!) e atualizar o recurso SealedSecret
com o nova senha (ou seja, executando kubeseal
novamente).
Ambas as etapas são descritas nas seções anteriores, embora de forma menos detalhada. Não há vergonha em lê-los novamente, agora que você tem uma compreensão mais profunda da lógica subjacente.
O controlador SealedSecret
e o fluxo de trabalho associado são projetados para manter chaves de vedação antigas e adicionar novas periodicamente. Você não deve excluir chaves antigas, a menos que saiba o que está fazendo.
Dito isto, se desejar, você pode gerenciar manualmente (criar, mover, excluir) chaves de vedação . Eles são apenas segredos normais do k8s que vivem no mesmo namespace onde reside o controlador SealedSecret
(geralmente kube-system
, mas é configurável).
Existem casos de uso avançados que você pode resolver por meio do gerenciamento criativo das chaves de vedação. Por exemplo, você pode compartilhar a mesma chave de selagem entre alguns clusters para poder aplicar exatamente o mesmo segredo selado em vários clusters. Como as chaves de selamento são apenas segredos k8s normais, você pode até usar os próprios segredos selados e usar um fluxo de trabalho GitOps para gerenciar suas chaves de selamento (útil quando você deseja compartilhar a mesma chave entre diferentes clusters)!
Rotular um segredo de chave de selamento com algo diferente de active
exclui efetivamente a chave do controlador SealedSecret
, mas ainda está disponível em k8s para criptografia/descriptografia manual, se necessário.
NOTA: O controlador SealedSecret
atualmente não coleta automaticamente chaves de vedação criadas manualmente, excluídas ou renomeadas. Um administrador deve reiniciar o controlador antes que o efeito seja aplicado.
Antes de se livrar de algumas chaves de selamento antigas, você precisa criptografar novamente seus SealedSecrets com a chave privada mais recente.
kubeseal --re-encrypttmp.json && mv tmp.json my_sealed_secret.json
A invocação acima produzirá um novo arquivo secreto selado, recém-criptografado com a chave mais recente, sem fazer com que os segredos deixem o cluster para o cliente. Você pode então salvar esse arquivo em seu sistema de controle de versão ( kubeseal --re-encrypt
não atualiza o objeto no cluster).
Atualmente, as chaves antigas não são coletadas como lixo automaticamente.
É uma boa ideia recriptografar periodicamente seus SealedSecrets. Mas, como mencionado acima, não se deixe levar por uma falsa sensação de segurança: você deve assumir que a versão antiga do recurso SealedSecret
(aquele criptografado com uma chave que você considera morta) ainda está potencialmente disponível e acessível aos invasores. Ou seja, a recriptografia não substitui a rotação periódica de seus segredos reais.
Este controlador adiciona um novo recurso personalizado SealedSecret
. A parte interessante de um SealedSecret
é um Secret
criptografado assimetricamente codificado em base64.
O controlador mantém um conjunto de pares de chaves privadas/públicas como segredos do Kubernetes. As chaves são rotuladas com sealedsecrets.bitnami.com/sealed-secrets-key
e identificadas no rótulo como active
ou compromised
. Na inicialização, o controlador de segredos selados irá...
Procure essas chaves e adicione-as ao armazenamento local se estiverem rotuladas como ativas.
Crie uma nova chave
Inicie o ciclo de rotação da chave
Mais detalhes sobre criptografia podem ser encontrados aqui.
As diretrizes de desenvolvimento podem ser encontradas no Guia do desenvolvedor.
Sim, você pode! Coloque quantos segredos quiser em um arquivo. Certifique-se de separá-los via ---
para YAML e como objetos únicos extras em JSON.
Não, as chaves privadas são armazenadas apenas no Secret gerenciado pelo controlador (a menos que você tenha algum outro backup dos seus objetos k8s). Não há backdoors - sem a chave privada usada para criptografar um determinado SealedSecrets, você não pode descriptografá-lo. Se você não conseguir acessar os segredos com as chaves de criptografia e também não conseguir acessar as versões descriptografadas de seus segredos no cluster, será necessário gerar novamente novas senhas para tudo, selá-las novamente com um novo chave de vedação, etc.
Se você quiser fazer um backup das chaves privadas de criptografia, é fácil fazer isso a partir de uma conta com acesso adequado:
kubectl obter segredo -n kube-system -l seladosecrets.bitnami.com/sealed-secrets-key -o yaml >main.keyecho "---" >> main.key kubectl obtém segredo -n kube-system selado-secrets-key -o yaml >>main.key
NOTA: Você precisará da segunda instrução somente se tiver instalado segredos selados anteriores à versão 0.9.x em seu cluster.
NOTA: Este arquivo conterá as chaves públicas + privadas do controlador e deve ser mantido em segurança!
NOTA: Após selar a renovação da chave, você deverá recriar seu backup. Caso contrário, seu backup não será capaz de descriptografar novos segredos lacrados.
Para restaurar a partir de um backup após algum desastre, basta colocar os segredos de volta antes de iniciar o controlador - ou se o controlador já tiver sido iniciado, substitua os segredos recém-criados e reinicie o controlador:
Para implantação do Helm:
kubectl aplicar -f main.key kubectl excluir pod -n kube-system -l app.kubernetes.io/name=sealed-secrets
Para implantação via manifesto controller.yaml
kubectl aplicar -f main.key kubectl excluir pod -n kube-system -l nome = controlador de segredos selados
Embora tratar segredos selados como um sistema de armazenamento de longo prazo para segredos não seja o caso de uso recomendado, algumas pessoas têm um requisito legítimo para poder recuperar segredos quando o cluster k8s está inativo e restaurar um backup em uma nova implantação do controlador SealedSecret
não é prático.
Se você fez backup de uma ou mais de suas chaves privadas (veja a pergunta anterior), você pode usar o comando kubeseal --recovery-unseal --recovery-private-key file1.key,file2.key,...
para descriptografar um arquivo de segredos selados.
Você pode verificar os sinalizadores disponíveis usando kubeseal --help
.
Um recurso Secret
do Kubernetes contém vários itens, basicamente um mapa plano de pares chave/valor. SealedSecrets opera nesse nível e não se importa com o que você coloca nos valores. Em outras palavras, ele não consegue entender nenhum arquivo de configuração estruturado que você possa ter colocado em um segredo e, portanto, não pode ajudá-lo a atualizar campos individuais nele.
Como este é um problema comum, especialmente quando se trata de aplicativos legados, oferecemos um exemplo de uma possível solução alternativa.
Sim, você pode fornecer ao controlador seus próprios certificados e ele os consumirá. Verifique aqui uma solução alternativa.
kube-system
? Se você instalou o controlador em um namespace diferente do padrão kube-system
, será necessário fornecer esse namespace para a ferramenta de linha de comando kubeseal
. Existem duas opções:
Você pode especificar o namespace por meio da opção de linha de comando --controller-namespace
:
kubeseal --controller-namespace selado-segredosmysealedsecret.json
Através da variável de ambiente SEALED_SECRETS_CONTROLLER_NAMESPACE
:
exportar SEALED_SECRETS_CONTROLLER_NAMESPACE=segredos selados kubesealmeusegredosecreto.json
Nossas imagens estão sendo assinadas com fiança. As assinaturas foram salvas em nosso GitHub Container Registry.
Imagens até v0.20.2 inclusive foram assinadas usando Cosign v1. As imagens mais recentes são assinadas com Cosign v2.
É muito simples verificar as imagens:
# exporte o COSIGN_VARIABLE configurando os sinais de registro do contêiner GitHub pathexport COSIGN_REPOSITORY=ghcr.io/bitnami-labs/sealed-secrets-controller/signs# verifique a imagem carregada em GHCRcosign verify --key .github/workflows/cosign.pub ghcr. io/bitnami-labs/sealed-secrets-controller:latest# verifique a imagem carregada no Dockerhubcosign verify --key .github/workflows/cosign.pub docker.io/bitnami/sealed-secrets-controller:mais recente
Se quiser usar um controlador para mais de um namespace, mas não para todos os namespaces, você poderá fornecer namespaces adicionais usando o sinalizador de linha de comando --additional-namespaces=
. Certifique-se de fornecer funções e associações de funções apropriadas nos namespaces de destino, para que o controlador possa gerenciar os segredos neles contidos.
A resposta é sim, você pode configurar o número de tentativas em seu controlador usando o sinalizador --max-unseal-retries
. Este sinalizador permite que você configure o número máximo de tentativas para revelar seus Segredos Selados.
#segredos selados no Kubernetes Slack
Clique aqui para se inscrever na organização Kubernetes Slack.
kubeseal-convert
: https://github.com/EladLeev/kubeseal-convert
Extensão do Visual Studio Code: https://marketplace.visualstudio.com/items?itemName=codecontemplator.kubeseal
WebSeal: gera segredos no navegador: https://socialgouv.github.io/webseal
Implementação HybridEncrypt TypeScript: https://github.com/SocialGouv/aes-gcm-rsa-oaep
[DEPRACADO] Operador Sealed Secrets: https://github.com/disposab1e/sealed-secrets-operator-helm