Problema: "Puedo administrar todas las configuraciones de mi K8 en git, excepto los Secretos".
Solución: Cifre su secreto en un SealedSecret, que es seguro de almacenar, incluso dentro de un repositorio público. El SealedSecret solo puede ser descifrado por el controlador que se ejecuta en el clúster de destino y nadie más (ni siquiera el autor original) puede obtener el Secreto original del SealedSecret.
Descripción general
SealedSecrets como plantillas para secretos
Clave pública/Certificado
Alcances
Instalación
cerveza casera
Puertos Mac
linux
Instalación desde fuente
Personalizar
Carta de timón
Controlador
sello kubeseal
Mejora
Uso
Gestionar secretos existentes
Parchear secretos existentes
Actualizar secretos existentes
Modo crudo (experimental)
Validar un secreto sellado
Rotación secreta
Renovación de llave de sellado
Rotación de secretos de usuario
Renovación anticipada de claves
Conceptos erróneos comunes sobre la renovación de claves
Gestión manual de claves (avanzada)
Volver a cifrar (avanzado)
Detalles (avanzado)
Cripto
Desarrollo
Preguntas frecuentes
¿Aún podrás descifrar si ya no tienes acceso a tu clúster?
¿Cómo puedo hacer una copia de seguridad de mis SealedSecrets?
¿Puedo descifrar mis secretos sin conexión con una clave de respaldo?
¿Qué banderas están disponibles para kubeseal?
¿Cómo actualizo partes de un archivo JSON/YAML/TOML/.. cifrado con secretos sellados?
¿Puedo traer mis propios certificados (pregenerados)?
¿Cómo usar kubeseal si el controlador no se ejecuta dentro del espacio de nombres kube-system
?
¿Cómo verificar las imágenes?
Cómo utilizar un controlador para un subconjunto de espacios de nombres
¿Puedo configurar los reintentos de desbloqueo del controlador?
Comunidad
Proyectos relacionados
Secretos Sellados se compone de dos partes:
Un controlador/operador del lado del clúster
Una utilidad del lado del cliente: kubeseal
La utilidad kubeseal
utiliza criptografía asimétrica para cifrar secretos que sólo el controlador puede descifrar.
Estos secretos cifrados están codificados en un recurso SealedSecret
, que puede ver como una receta para crear un secreto. Así es como se ve:
apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata: nombre: mysecret espacio de nombres: mynamespacespec: encryptedData: foo: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....
Una vez abierto, esto producirá un secreto equivalente a este:
apiVersion: v1kind: Secretmetadata: nombre: mysecret espacio de nombres: mynamespacedata: foo: YmFy # <- "barra" codificada en base64
Este secreto normal de Kubernetes aparecerá en el clúster después de unos segundos. Puede usarlo como usaría cualquier secreto que hubiera creado directamente (por ejemplo, referenciarlo desde un Pod
).
Vaya a la sección Instalación para comenzar a funcionar.
La sección Uso explora con más detalle cómo se crean los recursos SealedSecret
.
El ejemplo anterior solo se centró en los elementos secretos cifrados en sí, pero la relación entre un recurso personalizado SealedSecret
y el Secret
que se abre es similar en muchos aspectos (pero no en todos) al conocido Deployment
vs Pod
.
En particular, las anotaciones y etiquetas de un recurso SealedSecret
no son las mismas que las anotaciones del Secret
que se genera a partir de él.
Para capturar esta distinción, el objeto SealedSecret
tiene una sección template
que codifica todos los campos que desea que el controlador coloque en el Secret
abierto.
La biblioteca de funciones Sprig está disponible además de las funciones predeterminadas de Go Text Template.
El bloque metadata
se copia tal cual (el ownerReference
se actualizará a menos que esté deshabilitado).
Otros campos secretos se manejan individualmente. Los campos type
e immutable
se copian, y el campo data
se puede utilizar para crear plantillas de valores complejos en Secret
. Todos los demás campos se ignoran actualmente.
apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata: nombre: mysecret namespace: mynamespace anotaciones: "kubectl.kubernetes.io/last-applied-configuration": ....spec: encryptedData: .dockerconfigjson: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.... .plantilla: tipo: kubernetes.io/dockerconfigjson inmutable: true # este es un ejemplo de etiquetas y anotaciones que se agregarán a los metadatos secretos de salida: etiquetas: "jenkins.io/credentials-type": nombre de usuario Anotaciones de contraseña: "jenkins.io/credentials-description ": credenciales de Kubernetes
El controlador abriría eso en algo como:
apiVersion: v1kind: Secretmetadata: nombre: mysecret namespace: mynamespace etiquetas: "jenkins.io/credentials-type": nombre de usuario Anotaciones de contraseña: "jenkins.io/credentials-description": credenciales del propietario de KubernetesReferencias: - apiVersion: bitnami.com/v1alpha1 controlador: true tipo: SealedSecret nombre: mysecret uid: 5caff6a0-c9ac-11e9-881e-42010aac003etype: kubernetes.io/dockerconfigjsonimmutable: truedata: .dockerconfigjson: ewogICJjcmVk...
Como puede ver, el recurso Secret
generado es un "objeto dependiente" de SealedSecret
y, como tal, se actualizará y eliminará cada vez que el objeto SealedSecret
se actualice o elimine.
El certificado de clave (parte de la clave pública) se utiliza para sellar secretos y debe estar disponible dondequiera que se vaya a utilizar kubeseal
. El certificado no es información secreta, aunque debes asegurarte de que estás utilizando el correcto.
kubeseal
obtendrá el certificado del controlador en tiempo de ejecución (requiere acceso seguro al servidor API de Kubernetes), lo cual es conveniente para el uso interactivo, pero se sabe que es frágil cuando los usuarios tienen clústeres con configuraciones especiales, como clústeres privados de GKE que tienen firewalls entre ellos. plano de control y nodos.
Un flujo de trabajo alternativo es almacenar el certificado en algún lugar (por ejemplo, disco local) con kubeseal --fetch-cert >mycert.pem
y usarlo sin conexión con kubeseal --cert mycert.pem
. El certificado también se imprime en el registro del controlador al iniciar.
Desde la versión 0.9.x, los certificados se renuevan automáticamente cada 30 días. Es una buena práctica que usted y su equipo actualicen periódicamente su certificado fuera de línea. Para ayudarle con eso, desde la versión 0.9.2, kubeseal
también acepta URL. Puede configurar su automatización interna para publicar certificados en algún lugar de confianza.
kubeseal --cert https://your.intranet.company.com/sealed-secrets/your-cluster.cert
También reconoce la var de entorno SEALED_SECRETS_CERT
. (consejo profesional: ver también direnv).
NOTA : estamos trabajando para proporcionar mecanismos de administración de claves que descarguen el cifrado en módulos basados en HSM o soluciones criptográficas administradas en la nube, como KMS.
SealedSecrets son, desde el punto de vista de un usuario final, un dispositivo de "solo escritura".
La idea es que SealedSecret solo puede ser descifrado por el controlador que se ejecuta en el clúster de destino y nadie más (ni siquiera el autor original) puede obtener el secreto original de SealedSecret.
El usuario puede tener o no acceso directo al clúster de destino. Más específicamente, el usuario puede o no tener acceso al Secreto abierto por el controlador.
Hay muchas formas de configurar RBAC en k8, pero es bastante común prohibir a los usuarios con pocos privilegios leer Secretos. También es común dar a los usuarios uno o más espacios de nombres donde tienen privilegios más altos, lo que les permitiría crear y leer secretos (y/o crear implementaciones que puedan hacer referencia a esos secretos).
Los recursos cifrados SealedSecret
están diseñados para que sean seguros y puedan consultarse sin obtener ningún conocimiento sobre los secretos que oculta. Esto implica que no podemos permitir que los usuarios lean un SealedSecret destinado a un espacio de nombres al que no tendrían acceso y simplemente envíen una copia del mismo en un espacio de nombres desde donde puedan leer secretos.
Por lo tanto, los secretos sellados se comportan como si cada espacio de nombres tuviera su propia clave de cifrado independiente y, por lo tanto, una vez que sella un secreto para un espacio de nombres, no se puede mover a otro espacio de nombres ni descifrarlo allí.
Técnicamente, no utilizamos una clave privada independiente para cada espacio de nombres, sino que incluimos el nombre del espacio de nombres durante el proceso de cifrado, logrando efectivamente el mismo resultado.
Además, los espacios de nombres no son el único nivel en el que las configuraciones de RBAC pueden decidir quién puede ver qué secreto. De hecho, es posible que los usuarios puedan acceder a un secreto llamado foo
en un espacio de nombres determinado pero no a ningún otro secreto en el mismo espacio de nombres. Por lo tanto, de forma predeterminada, no podemos permitir que los usuarios cambien libremente el nombre de los recursos SealedSecret
, de lo contrario, un usuario malintencionado podría descifrar cualquier SealedSecret para ese espacio de nombres simplemente cambiándole el nombre para sobrescribir el único usuario secreto al que tiene acceso. Usamos el mismo mecanismo usado para incluir el espacio de nombres en la clave de cifrado para incluir también el nombre secreto.
Dicho esto, hay muchos escenarios en los que es posible que no le importe este nivel de protección. Por ejemplo, las únicas personas que tienen acceso a sus clústeres son los administradores o no pueden leer ningún recurso Secret
. Es posible que tenga un caso de uso para mover un secreto sellado a otros espacios de nombres (por ejemplo, es posible que no conozca el nombre del espacio de nombres de antemano), o puede que no sepa el nombre del secreto (por ejemplo, podría contener un sufijo único basado en el hash del contenidos, etc.).
Estos son los alcances posibles:
strict
(predeterminado): el secreto debe sellarse con exactamente el mismo nombre y espacio de nombres . Estos atributos pasan a formar parte de los datos cifrados y, por lo tanto, cambiar el nombre y/o el espacio de nombres provocaría un "error de descifrado".
namespace-wide
: puede cambiar libremente el nombre del secreto sellado dentro de un espacio de nombres determinado.
cluster-wide
: el secreto se puede abrir en cualquier espacio de nombres y se le puede dar cualquier nombre.
A diferencia de las restricciones de nombre y espacio de nombres , los elementos secretos (es decir, claves de objetos JSON como spec.encryptedData.my-key
) pueden cambiarse de nombre a voluntad sin perder la capacidad de descifrar el secreto sellado.
El alcance se selecciona con el indicador --scope
:
kubeseal --scope en todo el clústersealed-secret.json
También es posible solicitar un alcance mediante anotaciones en el secreto de entrada que pasa a kubeseal
:
sealedsecrets.bitnami.com/namespace-wide: "true"
-> para namespace-wide
sealedsecrets.bitnami.com/cluster-wide: "true"
-> para cluster-wide
La falta de cualquiera de estas anotaciones significa modo strict
. Si ambos están configurados, cluster-wide
tiene prioridad.
NOTA: La próxima versión consolidará esto en una única anotación
sealedsecrets.bitnami.com/scope
.
Consulte https://github.com/bitnami-labs/sealed-secrets/releases para obtener la última versión e instrucciones detalladas de instalación.
Notas e instrucciones específicas de la plataforma en la nube:
GKE
Una vez que implemente el manifiesto, creará el recurso SealedSecret
e instalará el controlador en el espacio de nombres kube-system
, creará una cuenta de servicio y las funciones RBAC necesarias.
Después de unos momentos, el controlador se iniciará, generará un par de claves y estará listo para funcionar. Si no es así, verifique los registros del controlador.
El mecanismo de instalación oficial del manifiesto del controlador es solo un archivo YAML.
En algunos casos, es posible que necesites aplicar tus propias personalizaciones, como establecer un espacio de nombres personalizado o establecer algunas variables de entorno.
kubectl
tiene soporte nativo para eso, consulte kustomize.
El gráfico de timón de Sealed Secrets ahora cuenta con soporte oficial y está alojado en este repositorio de GitHub.
repositorio de timón agregar secretos sellados https://bitnami-labs.github.io/sealed-secrets
NOTA: El esquema de versiones del gráfico de timón difiere del esquema de versiones del propio proyecto de secretos sellados.
Originalmente, la comunidad mantenía el gráfico de timón y la primera versión adoptó una versión principal de 1, mientras que el proyecto de secretos sellados todavía está en 0. Esto está bien porque la versión del gráfico de timón en sí no debe ser necesariamente la versión de la propia aplicación. Sin embargo, esto resulta confuso, por lo que nuestra regla de versiones actual es:
El esquema de versión del controlador SealedSecret
: 0.XY
Esquema de versión del gráfico de timón: 1.XY-rZ
Por lo tanto, puede haber múltiples revisiones del gráfico de timón, con correcciones que se aplican solo al gráfico de timón sin afectar los manifiestos YAML estáticos o la imagen del controlador en sí.
NOTA: El archivo Léame del gráfico de timón aún contiene un aviso de obsolescencia, pero ya no refleja la realidad y se eliminará en la próxima versión.
NOTA: El gráfico de timón instala de forma predeterminada el controlador con el nombre
sealed-secrets
, mientras que la interfaz de línea de comandos (CLI)kubeseal
intenta acceder al controlador con el nombresealed-secrets-controller
. Puede pasar explícitamente--controller-name
a la CLI:
kubeseal --nombre-controlador secretos-sellados
Alternativamente, puede configurar fullnameOverride
al instalar el gráfico para anular el nombre. Tenga en cuenta también que kubeseal
supone que el controlador está instalado dentro del espacio de nombres kube-system
de forma predeterminada. Entonces, si desea utilizar la CLI kubeseal
sin tener que pasar el nombre del controlador y el espacio de nombres esperado, debe instalar Helm Chart de esta manera:
helm install secretos-sellados -n kube-system --set-string nombre completoOverride=controlador-de-secretos-sellados secretos-sellados/secretos-sellados
En algunas empresas, es posible que solo se le brinde acceso a un único espacio de nombres, no a un clúster completo.
Uno de los entornos más restrictivos que puede encontrar es:
Se le asignó un namespace
con alguna service account
.
No tiene acceso al resto del clúster, ni siquiera a los CRD del clúster.
Es posible que ni siquiera puedas crear más cuentas de servicio o roles en tu espacio de nombres.
Debe incluir límites de recursos en todas sus implementaciones.
Incluso con estas restricciones, aún puedes instalar el Helm Chart de secretos sellados, solo hay un requisito previo:
El clúster ya debe tener instalados los CRD de secretos sellados .
Una vez que sus administradores instalaron los CRD, si aún no estaban allí, puede instalar el gráfico preparando un archivo de configuración YAML como este:
cuenta de servicio: crear: falso nombre: {cuenta-de-servicio-asignada} rbac: crear: falso rol del clúster: recursos falsos: límites: procesador: 150m memoria: 256Mi
Tenga en cuenta que:
No se crean cuentas de servicio, sino que se utilizará la que se le haya asignado.
{allocated-service-account}
es el nombre de la service account
que se le asignó en el clúster.
No se crean roles RBAC ni en el espacio de nombres ni en el clúster.
Se deben especificar los límites de recursos.
Los límites son ejemplos que deberían funcionar, pero es posible que desee revisarlos en su configuración particular.
Una vez que el archivo esté listo, si lo nombró config.yaml
ahora puede instalar el Helm Chart de secretos sellados de esta manera:
helm install secretos-sellados -n {espacio-de-nombres-asignado} secretos-sellados/secretos-sellados --skip-crds -f config.yaml
Donde {allocated-namespace}
es el nombre del espacio de namespace
que se le asignó en el clúster.
El cliente kubeseal
también está disponible en homebrew:
instalar kubeseal
El cliente kubeseal
también está disponible en MacPorts:
instalación de puerto kubeseal
El cliente kubeseal
también está disponible en Nixpkgs: ( DESCARGO DE RESPONSABILIDAD : No mantenido por bitnami-labs)
nix-env -iA nixpkgs.kubeseal
El cliente kubeseal
se puede instalar en Linux utilizando los siguientes comandos:
KUBESEAL_VERSION='' # Establezca esto en, por ejemplo, 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 instalar -m 755 kubeseal /usr/local/bin/kubeseal
Si tiene curl
y jq
instalados en su máquina, puede obtener la versión dinámicamente de esta manera. Esto puede resultar útil para entornos utilizados en automatización y demás.
# 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
donde KUBESEAL_VERSION
es la etiqueta de versión de la versión de kubeseal que desea utilizar. Por ejemplo: v0.18.0
.
Si solo desea la última herramienta de cliente, puede instalarla en $GOPATH/bin
con:
vaya a instalar github.com/bitnami-labs/sealed-secrets/cmd/kubeseal@main
Puede especificar una etiqueta de lanzamiento o un SHA de confirmación en lugar de main
.
El comando go install
colocará el binario kubeseal
en $GOPATH/bin
:
$(ir env GOPATH)/bin/kubeseal
No olvide consultar las notas de la versión para obtener orientación sobre posibles cambios importantes cuando actualice la herramienta cliente y/o el controlador.
Actualmente, solo se admite la última versión de Sealed Secrets para entornos de producción.
El controlador Sealed Secrets garantiza la compatibilidad con diferentes versiones de Kubernetes al confiar en una API de Kubernetes estable. Normalmente, las versiones de Kubernetes superiores a 1.16 se consideran compatibles. Sin embargo, admitimos oficialmente las versiones de Kubernetes recomendadas actualmente. Además, las versiones superiores a 1.24 se someten a una verificación exhaustiva a través de nuestro proceso de CI con cada lanzamiento.
# Cree un secreto codificado en json/yaml de alguna manera:# (tenga en cuenta el uso de `--dry-run`: ¡esto es solo un archivo local!)echo -n bar | kubectl create secret generic mysecret --dry-run=client --from-file=foo=/dev/stdin -o json >mysecret.json# Este es el bit importante:kubeseal -f mysecret.json -w mysealedsecret.json# En este punto, mysealedsecret.json es seguro para cargar en Github,# publicar en Twitter, etc.# Eventualmente:kubectl create -f mysealedsecret.json# Beneficio!kubectl obtener secreto mysecret
Tenga en cuenta que SealedSecret
y Secret
deben tener el mismo espacio de nombres y nombre . Esta es una función para evitar que otros usuarios del mismo clúster reutilicen sus secretos sellados. Consulte la sección Alcances para obtener más información.
kubeseal
lee el espacio de nombres del secreto de entrada, acepta un argumento --namespace
explícito y utiliza el espacio de nombres predeterminado kubectl
(en ese orden). Todas las etiquetas, anotaciones, etc. del Secret
original se conservan, pero no se reflejan automáticamente en SealedSecret
.
Por diseño, este esquema no autentica al usuario . En otras palabras, cualquiera puede crear un SealedSecret
que contenga cualquier Secret
que desee (siempre que el espacio de nombres/nombre coincida). Depende de su flujo de trabajo de administración de configuración existente, reglas RBAC del clúster, etc., garantizar que solo se cargue en el clúster el SealedSecret
deseado. El único cambio con respecto a los Kubernetes existentes es que el contenido del Secret
ahora está oculto mientras está fuera del clúster.
Si desea que el controlador de Sealed Secrets administre un Secret
existente, puede anotar su Secret
con la anotación sealedsecrets.bitnami.com/managed: "true"
. El Secret
existente se sobrescribirá al abrir un SealedSecret
con el mismo nombre y espacio de nombres, y SealedSecret
tomará posesión del Secret
(de modo que cuando se elimine el SealedSecret
, el Secret
también se eliminará).
Nuevo en v0.23.0
Hay algunos casos de uso en los que no desea reemplazar todo el Secret
, sino simplemente agregar o modificar algunas claves del Secret
existente. Para ello, puede anotar su Secret
con sealedsecrets.bitnami.com/patch: "true"
. El uso de esta anotación asegurará que las claves secretas, etiquetas y anotaciones en el Secret
que no están presentes en SealedSecret
no se eliminen, y aquellas presentes en SealedSecret
se agregarán al Secret
(claves secretas, etiquetas y anotaciones que existen tanto en el Secret
como en el SealedSecret
serán modificados por el SealedSecret
).
Esta anotación no hace que SealedSecret
tome posesión del Secret
. Puede agregar tanto el patch
como las anotaciones managed
para obtener el comportamiento de parcheo y al mismo tiempo tomar posesión del Secret
.
Si desea que SealedSecret
y el Secret
sean independientes, lo que significa que cuando elimine el SealedSecret
el Secret
no desaparecerá con él, entonces debe anotar ese Secreto con la anotación sealedsecrets.bitnami.com/skip-set-owner-references: "true"
antes de aplicar los pasos de uso. También puede agregar sealedsecrets.bitnami.com/managed: "true"
a su Secret
para que su secreto se actualice cuando se actualice SealedSecret
.
Si desea agregar o actualizar secretos sellados existentes sin tener el texto sin cifrar de los otros elementos, puede simplemente copiar y pegar los nuevos elementos de datos cifrados y fusionarlos en un secreto sellado existente.
Debe encargarse de sellar los elementos actualizados con un nombre y espacio de nombres compatibles (consulte la nota sobre los alcances más arriba).
Puede utilizar el comando --merge-into
para actualizar secretos sellados existentes si no desea copiar y pegar:
barra de eco -n | kubectl crear secreto genérico mysecret --dry-run=client --from-file=foo=/dev/stdin -o json | kubeseal > mysealedsecret.jsonecho -n baz | kubectl crea secreto genérico mysecret --dry-run=client --from-file=bar=/dev/stdin -o json | kubeseal --merge-into mysealedsecret.json
Crear un secreto temporal con el comando kubectl
, solo para tirarlo una vez conectado a kubeseal
puede ser una experiencia de usuario bastante desagradable. Estamos trabajando en una revisión de la experiencia CLI. Mientras tanto, ofrecemos un modo alternativo en el que kubeseal solo se preocupa por cifrar un valor en stdout, y es su responsabilidad colocarlo dentro de un recurso SealedSecret
(no muy diferente a cualquiera de los otros recursos de k8s).
También puede ser útil como bloque de construcción para integraciones de editor/IDE.
La desventaja es que hay que tener cuidado de ser coherente con el alcance del sellado, el espacio de nombres y el nombre.
Ver Alcances
alcance strict
(predeterminado):
$ eco -n foo | kubeseal --raw --namespace bar --name mysecretAgBChHUWLMx...
alcance namespace-wide
:
$ eco -n foo | kubeseal --raw --namespace bar --scope namespace-wideAgAbbFNkM54...
Incluya la anotación sealedsecrets.bitnami.com/namespace-wide
en SealedSecret
metadatos: anotaciones: sealsecrets.bitnami.com/namespace-wide: "verdadero"
alcance cluster-wide
:
$ eco -n foo | kubeseal --raw --scope todo el clústerAgAjLKpIYV+...
Incluya la anotación sealedsecrets.bitnami.com/cluster-wide
en SealedSecret
metadatos: anotaciones: sealsecrets.bitnami.com/cluster-wide: "true"
Si desea validar un secreto sellado existente, kubeseal
tiene la bandera --validate
para ayudarlo.
Proporcionando un archivo llamado sealed-secrets.yaml
que contiene el siguiente secreto sellado:
apiVersion: bitnami.com/v1alpha1kind: SealedSecretmetadata: nombre: mysecret espacio de nombres: mynamespacespec: encryptedData: foo: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....
Puedes validar si el secreto sellado fue creado correctamente o no:
$ gato sellado-secretos.yaml | kubeseal --validar
En caso de un secreto sellado no válido, kubeseal
mostrará:
$ gato sellado-secretos.yaml | kubeseal --validateerror: no se puede descifrar el secreto sellado
Siempre debes rotar tus secretos. Pero dado que sus secretos están cifrados con otro secreto, necesita comprender cómo se relacionan estas dos capas para tomar las decisiones correctas.
TL;DR:
Si una clave privada de sellado se ve comprometida, debe seguir las instrucciones que aparecen a continuación en la sección "Renovación anticipada de clave" antes de rotar cualquiera de sus valores secretos reales.
Las funciones de renovación y reencriptación de claves SealedSecret no sustituyen la rotación periódica de sus valores secretos reales.
Las claves de sellado se renuevan automáticamente cada 30 días. Lo que significa que se crea una nueva clave de sellado y se agrega al conjunto de claves de sellado activas que el controlador puede usar para desbloquear los recursos SealedSecret
.
La clave de sellado creada más recientemente es la que se usa para sellar nuevos secretos cuando usa kubeseal
y es aquella cuyo certificado se descarga cuando usa kubeseal --fetch-cert
.
El tiempo de renovación de 30 días es un valor predeterminado razonable, pero se puede modificar según sea necesario con el indicador --key-renew-period=
para el comando en la plantilla de pod del controlador SealedSecret
. El campo value
se puede proporcionar como indicador de duración de golang (por ejemplo: 720h30m
). Suponiendo que haya instalado Sealed Secrets en el espacio de nombres kube-system
, use el siguiente comando para editar el controlador de implementación y agregue el parámetro --key-renew-period
. Una vez que cierre su editor de texto y se haya modificado el controlador de implementación, se creará automáticamente un nuevo Pod para reemplazar el Pod anterior.
kubectl edit deployment/sealed-secrets-controller --namespace=kube-system
Un valor de 0
desactivará la renovación automática de claves. Por supuesto, es posible que tenga un caso de uso válido para desactivar la renovación automática de la clave de sellado, pero la experiencia ha demostrado que los nuevos usuarios a menudo tienden a sacar conclusiones precipitadas de que quieren tener control sobre la renovación de la clave, antes de comprender completamente cómo funcionan los secretos sellados. Lea más sobre esto en la sección de conceptos erróneos comunes a continuación.
Desafortunadamente, no puede usar, por ejemplo, "d" como unidad durante días porque no es compatible con Go stdlib. En lugar de golpearte la cara con la palma, aprovecha esto como una oportunidad para meditar sobre las falsedades que los programadores creen sobre el tiempo.
Un malentendido común es que la renovación de claves a menudo se considera una forma de rotación de claves, donde la clave anterior no sólo está obsoleta sino que en realidad es mala y, por lo tanto, desea deshacerse de ella. No ayuda que esta característica haya sido históricamente llamada "rotación de claves", lo que puede aumentar la confusión.
Los secretos sellados no se rotan automáticamente y las claves antiguas no se eliminan cuando se generan claves nuevas. Los recursos antiguos SealedSecret
aún se pueden descifrar (esto se debe a que las claves de sellado antiguas no se eliminan).
La renovación de la clave de sellado y la rotación de SealedSecret no sustituyen la rotación de sus secretos reales.
Una propuesta de valor central de esta herramienta es:
Cifre su secreto en un SealedSecret, que es seguro de almacenar, incluso dentro de un repositorio público.
Si almacena algo en un almacenamiento de control de versiones, y en uno público en particular, debe asumir que nunca podrá eliminar esa información.
Si de alguna manera se filtra una clave de sellado del clúster, debe considerar todos sus recursos SealedSecret
cifrados con esa clave como comprometidos. Ninguna cantidad de rotación de claves de sellado en el clúster o incluso volver a cifrar los archivos SealedSecrets existentes puede cambiar eso.
La mejor práctica es rotar periódicamente todos sus secretos reales (por ejemplo, cambiar la contraseña) y crear nuevos recursos SealedSecret
con esos nuevos secretos.
Pero si el controlador SealedSecret
no renovaba la clave de sellado, esa rotación sería discutible, ya que el atacante también podría descifrar los nuevos secretos. Por lo tanto, debes hacer ambas cosas: ¡renovar periódicamente la llave de sellado y rotar tus secretos reales!
Si sabe o sospecha que una clave de sellado se ha visto comprometida, debe renovar la clave lo antes posible antes de comenzar a sellar sus nuevos secretos rotados; de lo contrario, también les dará a los atacantes acceso a sus nuevos secretos.
Se puede generar una clave anticipadamente pasando la marca de tiempo actual al controlador en un indicador llamado --key-cutoff-time
o una var de entorno llamada SEALED_SECRETS_KEY_CUTOFF_TIME
. El formato esperado es RFC1123, puede generarlo con el comando date -R
Unix.
Las claves de sellado de secretos sellados no son claves de control de acceso (por ejemplo, una contraseña). Se parecen más a la clave GPG que puede utilizar para leer el correo cifrado que le envían. Sigamos un poco con la analogía del correo electrónico:
Imagine que tiene motivos para creer que su clave GPG privada podría haber sido comprometida. Tendría más que perder que ganar si lo primero que hace es simplemente eliminar su clave privada. Ya no podrá acceder a todos los correos electrónicos anteriores enviados con esa clave (a menos que tenga una copia descifrada de esos correos electrónicos), ni a los nuevos correos electrónicos enviados por sus amigos a quienes aún no ha logrado decirles que usen la nueva clave.
Claro, el contenido de esos correos electrónicos cifrados no es seguro, ya que un atacante ahora podría descifrarlos, pero lo hecho, hecho está. Su repentina pérdida de la capacidad de leer esos correos electrónicos seguramente no deshace el daño. En todo caso, es peor porque ya no se sabe con certeza qué secreto llegó a conocer el atacante. Lo que realmente desea hacer es asegurarse de que su amigo deje de usar su clave anterior y que de ahora en adelante todas las comunicaciones posteriores estén cifradas con un nuevo par de claves (es decir, su amigo debe conocer esa nueva clave).
La misma lógica se aplica a SealedSecrets. El objetivo final es proteger sus secretos reales de "usuario". Los secretos de "sellado" son sólo un mecanismo, un "sobre". Si se filtra un secreto no hay vuelta atrás, hecho, hecho está.
Primero debe asegurarse de que los nuevos secretos no se cifren con esa antigua clave comprometida (en la analogía del correo electrónico anterior: cree un nuevo par de claves y proporcione a todos sus amigos su nueva clave pública).
El segundo paso lógico es neutralizar el daño, lo que depende de la naturaleza del secreto. Un ejemplo simple es la contraseña de una base de datos: si accidentalmente filtra la contraseña de su base de datos, lo que se supone que debe hacer es simplemente cambiar la contraseña de su base de datos (en la base de datos; ¡y revocar la anterior!) y actualizar el recurso SealedSecret
con la nueva contraseña (es decir, ejecutar kubeseal
nuevamente).
Ambos pasos se describen en las secciones anteriores, aunque de forma menos detallada. No es ninguna vergüenza volver a leerlos ahora que comprendemos más profundamente el fundamento subyacente.
El controlador SealedSecret
y el flujo de trabajo asociado están diseñados para mantener las claves de sellado antiguas y agregar periódicamente otras nuevas. No debes eliminar claves antiguas a menos que sepas lo que estás haciendo.
Dicho esto, si lo deseas, puedes administrar (crear, mover, eliminar) manualmente las claves de sellado . Son simplemente secretos normales de k8 que viven en el mismo espacio de nombres donde vive el controlador SealedSecret
(generalmente kube-system
, pero es configurable).
Existen casos de uso avanzados que puede abordar mediante la gestión creativa de las claves de sellado. Por ejemplo, puede compartir la misma clave de sellado entre algunos grupos para poder aplicar exactamente el mismo secreto sellado en varios grupos. Dado que las claves de sellado son solo secretos normales de k8, incluso puede usar secretos sellados y usar un flujo de trabajo de GitOps para administrar sus claves de sellado (útil cuando desea compartir la misma clave entre diferentes grupos).
Etiquetar un secreto de clave de sellado con algo que no sea active
elimina efectivamente la clave del controlador SealedSecret
, pero aún está disponible en k8s para cifrado/descifrado manual si es necesario.
NOTA El controlador SealedSecret
actualmente no recoge automáticamente las claves de sellado creadas, eliminadas o reetiquetadas manualmente. Un administrador debe reiniciar el controlador antes de que se aplique el efecto.
Antes de poder deshacerse de algunas claves de sellado antiguas, debe volver a cifrar sus SealedSecrets con la última clave privada.
kubeseal --re-encrypttmp.json && mv tmp.json my_sealed_secret.json
La invocación anterior producirá un nuevo archivo secreto sellado recién cifrado con la clave más reciente, sin que los secretos abandonen el clúster al cliente. Luego puede guardar ese archivo en su sistema de control de versiones ( kubeseal --re-encrypt
no actualiza el objeto del clúster).
Actualmente, las claves antiguas no se recolectan como basura automáticamente.
Es una buena idea volver a cifrar periódicamente sus SealedSecrets. Pero como se mencionó anteriormente, no se deje llevar por una falsa sensación de seguridad: debe asumir que la versión antigua del recurso SealedSecret
(la que está cifrada con una clave que considera muerta) todavía está potencialmente disponible y es accesible para los atacantes. Es decir, volver a cifrar no sustituye la rotación periódica de sus secretos reales.
Este controlador agrega un nuevo recurso personalizado SealedSecret
. La parte interesante de un SealedSecret
es un Secret
cifrado asimétricamente codificado en base64.
El controlador mantiene un conjunto de pares de claves pública y privada como secretos de Kubernetes. Las claves están etiquetadas con sealedsecrets.bitnami.com/sealed-secrets-key
y se identifican en la etiqueta como active
o compromised
. Al iniciarse, el controlador de secretos sellados...
Busque estas claves y agréguelas a su tienda local si están etiquetadas como activas.
Crear una nueva clave
Iniciar el ciclo de rotación de llaves
Se pueden encontrar más detalles sobre las criptomonedas aquí.
Las pautas de desarrollo se pueden encontrar en la Guía para desarrolladores.
¡Sí, puedes! Coloca tantos secretos como quieras en un solo archivo. Asegúrese de separarlos mediante ---
para YAML y como objetos individuales adicionales en JSON.
No, las claves privadas sólo se almacenan en el Secreto administrado por el controlador (a menos que tengas alguna otra copia de seguridad de tus objetos k8s). No hay puertas traseras: sin esa clave privada utilizada para cifrar un SealedSecrets determinado, no puedes descifrarlo. Si no puede acceder a los Secretos con las claves de cifrado y tampoco puede acceder a las versiones descifradas de sus Secretos que se encuentran en el clúster, entonces deberá volver a generar nuevas contraseñas para todo y sellarlas nuevamente con una nueva. llave de sellado, etc.
Si desea hacer una copia de seguridad de las claves privadas de cifrado, es fácil hacerlo desde una cuenta con acceso adecuado:
kubectl get secret -n kube-system -l sealsecrets.bitnami.com/sealed-secrets-key -o yaml >main.keyecho "---" >> main.key kubectl get secret -n kube-system clave-secretos-sellados -o yaml >>main.key
NOTA: Necesita la segunda declaración solo si alguna vez instaló secretos sellados anteriores a la versión 0.9.x en su clúster.
NOTA: ¡Este archivo contendrá las claves públicas y privadas del controlador y debe mantenerse a salvo!
NOTA: Después de sellar la renovación de la clave, debe volver a crear su copia de seguridad. De lo contrario, su copia de seguridad no podrá descifrar nuevos secretos sellados.
Para restaurar desde una copia de seguridad después de algún desastre, simplemente vuelva a colocar esos secretos antes de iniciar el controlador, o si el controlador ya se inició, reemplace los secretos recién creados y reinicie el controlador:
Para la implementación de Helm:
kubectl aplicar -f clave principal kubectl eliminar pod -n kube-system -l app.kubernetes.io/name=sealed-secrets
Para implementación a través del manifiesto controller.yaml
kubectl aplicar -f clave principal kubectl eliminar pod -n kube-system -l nombre=controlador-de-secretos-sellados
Si bien tratar los secretos sellados como un sistema de almacenamiento a largo plazo para secretos no es el caso de uso recomendado, algunas personas tienen un requisito legítimo para poder recuperar secretos cuando el clúster k8s no funciona y restaurar una copia de seguridad en una nueva implementación del controlador SealedSecret
no lo es. práctico.
Si ha realizado una copia de seguridad de una o más de sus claves privadas (consulte la pregunta anterior), puede usar el comando kubeseal --recovery-unseal --recovery-private-key file1.key,file2.key,...
para descifrar una Archivo de secretos sellado.
Puede consultar las banderas disponibles usando kubeseal --help
.
Un recurso Secret
de Kubernetes contiene varios elementos, básicamente un mapa plano de pares clave/valor. SealedSecrets opera a ese nivel y no le importa lo que pongas en los valores. En otras palabras, no puede entender ningún archivo de configuración estructurado que haya puesto en secreto y, por lo tanto, no puede ayudarle a actualizar campos individuales en él.
Dado que se trata de un problema común, especialmente cuando se trata de aplicaciones heredadas, ofrecemos un ejemplo de una posible solución.
Sí, puede proporcionar al controlador sus propios certificados y este los consumirá. Consulte aquí para encontrar una solución alternativa.
kube-system
? Si instaló el controlador en un espacio de nombres diferente al kube-system
predeterminado, debe proporcionar este espacio de nombres a la herramienta de línea de comandos kubeseal
. Hay dos opciones:
Puede especificar el espacio de nombres mediante la opción de línea de comando --controller-namespace
:
kubeseal --controller-namespace sellado-secretosmisecreto.json
A través de la variable de entorno SEALED_SECRETS_CONTROLLER_NAMESPACE
:
exportar SEALED_SECRETS_CONTROLLER_NAMESPACE=secretos-sellados kubesealmisecreto.json
Nuestras imágenes están firmadas mediante cosign. Las firmas se han guardado en nuestro Registro de contenedores de GitHub.
Las imágenes hasta la versión 0.20.2 incluida se firmaron con Cosign v1. Las imágenes más recientes están firmadas con Cosign v2.
Es bastante sencillo verificar las imágenes:
# exportar COSIGN_VARIABLE configurando los signos de registro del contenedor de GitHub pathexport COSIGN_REPOSITORY=ghcr.io/bitnami-labs/sealed-secrets-controller/signs# verificar la imagen cargada en GHCRcosign verificar --key .github/workflows/cosign.pub ghcr. io/bitnami-labs/sealed-secrets-controller:latest# verificar la imagen cargada en Dockerhubcosign verificar --key .github/workflows/cosign.pub docker.io/bitnami/sealed-secrets-controller:latest
Si desea utilizar un controlador para más de un espacio de nombres, pero no para todos los espacios de nombres, puede proporcionar espacios de nombres adicionales usando la marca de línea de comando --additional-namespaces=
. Asegúrese de proporcionar roles y enlaces de roles adecuados en los espacios de nombres de destino, para que el controlador pueda administrar los secretos allí.
La respuesta es sí, puede configurar la cantidad de reintentos en su controlador usando la bandera --max-unseal-retries
. Esta bandera le permite configurar el número máximo de reintentos para desbloquear sus secretos sellados.
#secretos-sellados en Kubernetes Slack
Haga clic aquí para registrarse en la organización Kubernetes Slack.
kubeseal-convert
: https://github.com/EladLeev/kubeseal-convert
Extensión de código de Visual Studio: https://marketplace.visualstudio.com/items?itemName=codecontemplator.kubeseal
WebSeal: genera secretos en el navegador: https://socialgouv.github.io/webseal
Implementación de HybridEncrypt TypeScript: https://github.com/SocialGouv/aes-gcm-rsa-oaep
[DEPRACADO] Operador de secretos sellados: https://github.com/disposab1e/sealed-secrets-operator-helm