Seguridad de la Conectividad Remota del Daemon de Docker
Anteriormente en este capítulo, vimos cómo configurar el daemon de Docker para aceptar conexiones remotas. Sin embargo, con el enfoque que seguimos, cualquier persona puede conectarse a nuestro daemon de Docker. Podemos asegurar nuestra conexión con Seguridad de Capa de Transporte (http://en.wikipedia.org/wiki/Transport_Layer_Security).
Podemos configurar TLS utilizando la Autoridad de Certificación (CA) existente o creando la nuestra. Para simplificar, crearemos la nuestra, lo que no se recomienda para producción. En este ejemplo, asumimos que nuestro host que ejecuta el daemon de Docker es dockerhost.example.com.
Preparación
Asegúrate de tener la biblioteca openssl instalada.
Cómo hacerlo…
- Crea un directorio en tu host para poner nuestra CA y otros archivos relacionados:
$ mkdir -p /etc/docker/keys
$ cd /etc/docker/keys
- Crea la clave privada y pública de la CA:
$ openssl genrsa -aes256 -out ca-key.pem 4096
$ openssl req -new -x509 -days 365 -key ca-key.pem \
-sha256 -out ca.pem

- Ahora, creemos la clave del servidor y la solicitud de firma de certificado. Asegúrate de que el nombre común coincida con el nombre de host del sistema del daemon de Docker. En nuestro caso, es
dockerhost.example.com:
$ openssl genrsa -out server-key.pem 4096
$ openssl req -subj "/CN=dockerhost.example.com" \
-new -key server-key.pem -out server.csr

- Los clientes pueden conectarse al daemon de Docker utilizando el nombre de DNS o la dirección IP del host de Docker. Por lo tanto, el nombre de DNS y la dirección IP deben estar incluidos en el certificado como una extensión. Además, agregue los atributos de uso extendido de la clave del daemon de Docker para que se utilicen solo para autenticación de servidor. Ambas piezas de información se capturan en el archivo
extfile.cnf, como se muestra aquí:
![]()
Aquí, 192.168.33.101 y 10.0.2.15 son las direcciones IP de dos interfaces de red, y 127.0.0.1 es la dirección de bucle invertido.
- Continúa para generar la clave:
$ openssl x509 -req -days 365 -sha256 -in server.csr \
-CA ca.pem -CAkey ca-key.pem -CAcreateserial \
-out server-cert.pem -extfile extfile.cnf

- Para la autenticación del cliente, crea una clave del cliente y una solicitud de firma de certificado:
$ openssl genrsa -out key.pem 4096
$ openssl req -subj '/CN=client' -new -key key.pem \
-out client.csr

- Para hacer que la clave sea adecuada para la autenticación del cliente, crea un archivo de configuración de extensión y firma la clave pública:
$ echo extendedKeyUsage = clientAuth > client-extfile.cnf
$ openssl x509 -req -days 365 -sha256 -in client.csr \
-CA ca.pem -CAkey ca-key.pem -CAcreateserial \
-out cert.pem -extfile client-extfile.cnf

- Después de generar
cert.pemyserver-cert.pem, podemos eliminar con seguridad ambas solicitudes de firma de certificado:
$ rm -rf client.csr server.csr
- Para proteger las claves de daños accidentales, elimina los permisos de escritura de estos archivos de clave:
ca-key.pem,key.pemyserver-key.pem. Además, limita el permiso de lectura de estos archivos solo para elroot:
$ chmod 0400 ca-key.pem key.pem server-key.pem
Los archivos de certificado ca.pem, server-cert.pem y cert.pem necesitan un acceso de lectura más amplio, así que da acceso de lectura para todos estos archivos de certificado, como se muestra aquí:
$ chmod 0444 ca.pem server-cert.pem cert.pem
- Detén el daemon si está ejecutándose en
dockerhost.example.comutilizando el comandosystemctl stop docker. Luego, inicia el daemon de Docker manualmente desde/etc/docker/keys:
$ dockerd --tlsverify \
--tlscacert=ca.pem \
--tlscert=server-cert.pem \
--tlskey=server-key.pem \
-H=0.0.0.0:2376
- Desde otra terminal, ve a
/etc/docker/keys. Ejecuta el siguiente comando para conectarte al daemon de Docker:
$ cd /etc/docker/keys
$ docker --tlsverify \
--tlscacert=ca.pem \
--tlscert=cert.pem \
--tlskey=key.pem \
-H=127.0.0.1:2376 version
El cliente de Docker puede conectarse sin problemas al daemon de Docker a través de TLS y obtener la versión del servidor.
Cómo funciona…
Una vez que configuramos el daemon de Docker para utilizar TLS como transporte, solo acepta conexiones TLS seguras para el cliente y cumple con la solicitud del cliente.
Hay más…
En esta receta, utilizamos las opciones --tlscacert, --tlscert y --tlskey del comando docker para conectarnos al daemon de Docker habilitado para TLS. Invocar el comando docker utilizando una lista tan larga de opciones es bastante incómodo. Sin embargo, podemos evitar este problema haciendo lo siguiente:
-
Copia los archivos
ca.pem,cert.pemykey.pemal directorio$HOME/.dockerdel usuario. -
Modifica la propiedad del archivo para que pertenezca al usuario utilizando el comando
chown. -
Establece
DOCKER_HOSTen la dirección del daemon, como se muestra aquí:
$ export DOCKER_HOST=tcp://127.0.0.1:2376
- Establece
DOCKER_TLS_VERIFYen1, como se muestra aquí:
$ export DOCKER_TLS_VERIFY=1
Ahora, puedes ejecutar el comando docker como si estuvieras ejecutándolo en el socket de Unix.
En esta receta, lanzamos el daemon de Docker desde la línea de comandos, lo que es bueno para pruebas. Sin embargo, el daemon de Docker debe estar configurado para iniciarse con Systemd. Puedes lograr esto editando el archivo de unidad del servicio de Docker, como se describe en la receta Configuración del daemon de Docker para conectividad remota, con la siguiente excepción notada para ExecStart:
ExecStart=/usr/bin/dockerd \
--tlsverify \
--tlscacert=/etc/docker/keys/ca.pem \
--tlscert=/etc/docker/keys/server-cert.pem \
--tlskey=/etc/docker/keys/server-key.pem \
-H=0.0.0.0:2376
Aquí, hemos separado el comando en varias líneas para mejorar la legibilidad. Sin embargo, debe estar en una sola línea en el archivo de unidad.
- El comando
curltambién puede conectarse de forma segura al daemon de Docker habilitado para TLS, como se muestra aquí:
$ curl --cacert ${HOME}/.docker/ca.pem \
--cert ${HOME}/.docker/cert.pem \
--key ${HOME}/.docker/key.pem \
https://127.0.0.1:2376/version
Ver también
- La documentación en el sitio web de Docker: https://docs.docker.com/engine/security/https/