Skip to main content

Cómo mantener seguros los secretos de Docker (aunque no uses Kubernetes)

Escrito por

Marcelo Oliveira

hero docker secrets

24 de agosto de 2022

0 minutos de lectura

Los sistemas distribuidos basados en contenedores integran aplicaciones, recursos, servicios, bases de datos y otros elementos. Estos componentes suelen necesitar información confidencial, como claves de usuario, contraseñas, claves de API y certificados, para funcionar correctamente.

La administración de secretos es fundamental para manejar adecuadamente la información confidencial. Las implementaciones de Kubernetes suelen usar el tipo de recurso Secrets integrado y los controles RBAC asociados, pero ¿qué pasa si no implementas en Kubernetes? Muchas organizaciones simplemente no necesitan la potencia de Kubernetes o no quieren asumir la complejidad de ejecutarlo, pero aun así deben evitar el riesgo de filtraciones de datos o pérdida de contraseñas. Por suerte, el orquestador Swarm integrado en Docker ofrece una solución.

Este artículo analiza cómo administrar secretos en Docker y explora las prácticas recomendadas y los posibles riesgos de su uso. También presenta un ejercicio sencillo para crear y enumerar secretos de Docker, así como agregarlos y quitarlos de un servicio. Se supone que el lector tiene conocimientos básicos del entorno de ejecución de contenedores Docker y de su orquestador Swarm.

Cómo proteger los secretos de Docker

Cada vez que envías secretos o datos confidenciales dentro de tu organización, existe el riesgo de que se filtren datos o se pierdan contraseñas. Al trabajar en un proyecto de Docker en el que debes manejar información confidencial, como contraseñas, claves privadas, tokens y claves de API, debes definir una forma segura de almacenar y transmitir estos secretos a los contenedores.

Una de las peores prácticas es dejar datos confidenciales en el código fuente. Además de los problemas de seguridad, incluir secretos directamente en el código significa que tendrás que volver a crear la imagen cuando cambien los secretos.

Otra mala práctica es manejar información importante, como contraseñas y claves SSH, de forma “manual” y dejar información secreta en el disco local. Recuerda que los programas maliciosos o sin autorización también podrían leer tus archivos.

Los desarrolladores suelen recurrir a las variables de entorno para almacenar datos confidenciales. Esto puede funcionar en algunos casos, pero no se recomienda para contenedores de Docker. Las variables de entorno son incluso menos seguras que los archivos y son vulnerables de más formas, como las siguientes:

Por ejemplo, una aplicación podría volcar el context en un registro como parte del código de manejo de excepciones, y el registro podría incluir entonces los valores confidenciales de las variables de entorno.

Usar un administrador de secretos es mucho mejor que las opciones anteriores, ya que ofrece un lugar central para gestionar secretos en Docker Swarm. Un administrador de secretos ayuda a proteger el acceso a tus aplicaciones, servicios y recursos de TI con un servicio práctico para almacenar, administrar y recuperar secretos. Estos incluyen credenciales de bases de datos de API, claves, contraseñas, claves privadas SSH, certificados SSL y otros datos confidenciales que una aplicación necesita durante la ejecución.

Cómo administra Docker los secretos

Diagrama que muestra una interfaz web conectada a un grupo de consenso Raft con administradores, workers bloqueados, documentos internos, claves y una aplicación externa.

El diagrama anterior muestra que Docker usa Raft, un algoritmo de consenso para administrar un registro replicado en un sistema distribuido. Así, garantiza que los datos se mantengan coherentes en todo el swarm y en todos los servicios que se ejecutan en él. El algoritmo Raft transmite de forma coherente los secretos cifrados a todos los nodos administradores.

El diagrama también muestra los nodos trabajadores, instancias de Docker Engine dedicadas a ejecutar contenedores. Los nodos administradores distribuyen los secretos a los contenedores que forman parte del servicio con la clave.

Los secretos de Docker funcionan como una bóveda donde puedes guardar datos confidenciales. Solo puedes usarlos si tienes la clave de la bóveda, que debes obtener de los nodos de servicio a los que asignaste la clave.

El servicio de administración de secretos de Docker forma parte de su conjunto de herramientas de orquestación de contenedores y ofrece un proceso automatizado para mantener estos datos seguros.

En los servicios de Docker Swarm, los secretos están cifrados tanto cuando se almacenan como cuando se transmiten.

Los secretos de Docker se pueden administrar de forma centralizada y transmitir de manera segura a los contenedores que necesitan acceder a ellos. Cada secreto solo está disponible para los servicios a los que se les concedió acceso explícito, y únicamente mientras el servicio está en ejecución.

Cuando un servicio obtiene acceso a los secretos, los descifra y los comparte con el contenedor en un sistema de archivos en memoria. Cuando se detiene la tarea del contenedor, los secretos descifrados disponibles se desconectan de inmediato y se eliminan de la memoria del nodo.

Administrar secretos con la CLI de Docker

La funcionalidad integrada de Docker permite ingresar secretos y controlar de forma detallada qué servicios pueden acceder a ellos y en qué circunstancias pueden usarlos.

Este sencillo ejercicio crea un servicio MySQL con una contraseña de root y agrega las credenciales como secretos.

Como los secretos de Docker solo están disponibles para los servicios de swarm, debes configurar un Docker Swarm para ver cómo funcionan. Pero primero, asegúrate de haber instalado la línea de comandos de Docker (Docker CLI). Si aún no lo has hecho, inicializa el swarm o únete a uno:

docker swarm init

Swarm initialized: current node (wv4c3hvdwqlssjpaxzvvhy3vj) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join --token SWMTKN-1-3qizt7vyw8cbpii3nosl8ws7zr1npikrepr0qqh9ad7esucwon-bfxct86tefphzo8xiz8ue0tx6 192.168.65.3:2377

Ahora agrega un secreto a Docker.

Crea un archivo de texto para almacenar el secreto. El siguiente comando crea el archivo password.txt con la cadena this-is-a-mysql-password.

$ echo "this-is-a-mysql-password" > $HOME/password.txt

Ahora usa el comando docker secret create para crear un secreto nuevo a partir del archivo que creaste en el paso anterior:

$ docker secret create mysql-password-secret $HOME/password.txt

l1m5jvgcox1l96i6bjbz4dvnt

Ten en cuenta que la cadena l1m5jvgcox1l96i6bjbz4dvnt representa el ID del secreto, no el secreto en sí, por lo que probablemente será diferente en tu entorno.

Ahora veamos otra forma de usar el comando docker secret create. Aquí, omite el nombre del archivo estableciendo el último argumento, que representa el archivo, como el símbolo menos (-):

$ echo "another-mysql-password" | docker secret create another-mysql-secret -

Este comando genera un resultado como el siguiente:

q3bjo7wx4xqr45ma20lk5j2g7

Al omitir el archivo del que se leerá el secreto, el comando docker secret create lee la entrada estándar another-mysql-password.

Enumerar secretos de Docker

Para enumerar los secretos disponibles en Docker Swarm, ejecuta el comando docker secret ls:

$ docker secret ls

El resultado muestra los secretos que creaste en Docker Swarm:

ID                          NAME                    DRIVER    CREATED              UPDATED
q3bjo7wx4xqr45ma20lk5j2g7   another-mysql-secret              46 seconds ago       46 seconds ago
l1m5jvgcox1l96i6bjbz4dvnt   mysql-password-secret             About a minute ago   About a minute ago

Crear un servicio con secretos

Puedes crear un servicio usando uno de los secretos creados anteriormente.

Crea el servicio mysql-service y usa la opción --secret para dar acceso al contenedor al secreto another-mysql-secret:

$ docker service create --name mysql-service --secret another-mysql-secret mysql:5.7

Agregar secretos a un servicio existente o quitarlos

Puedes quitar un secreto de un servicio existente:

$ docker service update --secret-rm another-mysql-secret mysql-service

También puedes agregar un secreto a un servicio en ejecución:

$ docker service update --secret-add mysql-password-secret mysql-service

Al vincular un secreto a un servicio, Docker crea un archivo de texto con el nombre del secreto. El archivo contiene una cadena que representa el secreto y, de forma predeterminada, se encuentra en el directorio /run/secrets, montado en un sistema de archivos temporal (TMPFS) dentro del contenedor. En nuestro caso, el archivo está en la ruta /run/secrets/mysql-password-secret. Al crearse, el secreto queda disponible para todos los contenedores de ese servicio.

Alternativas externas para administrar secretos

Los secretos de Docker son una excelente solución, pero también deberías considerar delegar esta tarea en soluciones externas de almacenamiento de secretos. Esto es especialmente importante si tu organización ya tiene experiencia e inversiones en una plataforma específica.

Por ejemplo, si tu empresa ya usa Hashicorp Vault y tus aplicaciones están integradas con esta herramienta, hay pocas razones para cambiar a los secretos de Docker —o a los secretos de Kubernetes— solo porque vienen incluidos en la plataforma. Aprovecha los procesos, las bibliotecas y la experiencia existentes en torno a esa solución en tus servicios.

Algunas alternativas populares para administrar secretos son:

Mantén tus secretos seguros

Este artículo presentó el concepto de los secretos y su administración en el contexto de Docker Swarm, y explicó cómo Docker los gestiona. También mostró por qué usar un administrador de secretos es mucho mejor que incluir datos confidenciales directamente en el código, usar variables de entorno o administrarlos de forma manual.

La seguridad de los datos es uno de los pilares de una gobernanza corporativa eficaz. Con comandos de CLI y una arquitectura en memoria que permite implementar datos secretos con un control detallado, Docker ofrece herramientas sólidas de administración de secretos que te ayudan a implementar correctamente la seguridad de la información de tu organización.

Mantener los secretos fuera del alcance de miradas indiscretas es un paso para crear contenedores seguros. Snyk Code puede ayudarte a encontrar secretos incluidos directamente en el código, mientras que Snyk Container y Snyk Open Source te ayudan a elegir las imágenes base y los paquetes más seguros para tus contenedores. Y cuando estés listo para pasar a producción, Snyk IaC te ayuda a reducir los riesgos antes y después de la implementación. Empieza gratis hoy mismo para encontrar y corregir automáticamente vulnerabilidades en tu código, dependencias de código abierto, contenedores e infraestructura en la nube.

Seguridad de contenedores centrada en los desarrolladores

Snyk encuentra y corrige automáticamente vulnerabilidades en imágenes de contenedores y cargas de trabajo de Kubernetes.