Compartir comentarios
Las respuestas se generan en base a la documentación.

Proteger el socket del demonio de Docker

Por defecto, Docker se ejecuta a través de un socket UNIX no conectado a la red. También puede, de forma opcional, comunicarse utilizando SSH o un socket TLS (HTTPS).

Usar SSH para proteger el socket del demonio de Docker

Note

El USERNAME indicado debe tener permisos para acceder al socket de docker en la máquina remota. Consulta gestionar Docker como usuario no root para aprender cómo dar acceso al socket de docker a un usuario no root.

El siguiente ejemplo crea un docker context para conectarse con un demonio dockerd remoto en host1.example.com usando SSH, y como el usuario docker-user en la máquina remota:

$ docker context create \
    --docker host=ssh://[email protected] \
    --description="Remote engine" \
    my-remote-engine

my-remote-engine
Successfully created context "my-remote-engine"

Después de crear el contexto, utiliza docker context use para cambiar la CLI de docker y usarlo, y para conectarte al motor remoto:

$ docker context use my-remote-engine
my-remote-engine
Current context is now "my-remote-engine"

$ docker info
<prints output of the remote engine>

Utiliza el contexto default para volver al demonio por defecto (local):

$ docker context use default
default
Current context is now "default"

Como alternativa, utiliza la variable de entorno DOCKER_HOST para cambiar temporalmente la CLI de docker para conectarte al anfitrión remoto usando SSH. Esto no requiere crear un contexto y puede ser útil para establecer una conexión ad-hoc con un motor diferente:

$ export DOCKER_HOST=ssh://[email protected]
$ docker info
<prints output of the remote engine>

Consejos de SSH

Para obtener la mejor experiencia de usuario con SSH, configura ~/.ssh/config de la siguiente manera para permitir la reutilización de una conexión SSH para múltiples invocaciones de la CLI de docker:

ControlMaster     auto
ControlPath       ~/.ssh/control-%C
ControlPersist    yes

Usar TLS (HTTPS) para proteger el socket del demonio de Docker

Si necesitas que se pueda acceder a Docker a través de HTTP en lugar de SSH de manera segura, puedes habilitar TLS (HTTPS) especificando la bandera tlsverify y apuntando la bandera tlscacert de Docker a un certificado de CA de confianza.

En el modo de demonio, solo permite conexiones de clientes autenticados por un certificado firmado por esa CA. En el modo de cliente, solo se conecta a servidores con un certificado firmado por esa CA.

Important

El uso de TLS y la gestión de una CA es un tema avanzado. Familiarízate con OpenSSL, x509 y TLS antes de usarlo en producción.

Crear una CA, y claves de servidor y cliente con OpenSSL

Note

Reemplaza todas las instancias de $HOST en el siguiente ejemplo con el nombre DNS del anfitrión de tu demonio de Docker.

Primero, en la máquina anfitriona del demonio de Docker, genera las claves privada y pública de la CA:

$ openssl genrsa -aes256 -out ca-key.pem 4096
Generating RSA private key, 4096 bit long modulus
..............................................................................++
........++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem:
Verifying - Enter pass phrase for ca-key.pem:

$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
Enter pass phrase for ca-key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:Queensland
Locality Name (eg, city) []:Brisbane
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Docker Inc
Organizational Unit Name (eg, section) []:Sales
Common Name (e.g. server FQDN or YOUR name) []:$HOST
Email Address []:[email protected]

Ahora que tienes una CA, puedes crear una clave de servidor y una solicitud de firma de certificado (CSR). Asegúrate de que el "Common Name" coincida con el nombre de anfitrión que utilizas para conectarte a Docker:

Note

Reemplaza todas las instancias de $HOST en el siguiente ejemplo con el nombre DNS del anfitrión de tu demonio de Docker.

$ openssl genrsa -out server-key.pem 4096
Generating RSA private key, 4096 bit long modulus
.....................................................................++
.................................................................................................++
e is 65537 (0x10001)

$ openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr

A continuación, se firmará la clave pública con la CA:

Dado que las conexiones TLS se pueden realizar tanto a través de la dirección IP como del nombre DNS, es necesario especificar las direcciones IP al crear el certificado. Por ejemplo, para permitir conexiones usando 10.10.10.20 y 127.0.0.1:

$ echo subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1 >> extfile.cnf

Configura los atributos de uso extendido de la clave del demonio de Docker para que se utilicen únicamente para la autenticación del servidor:

$ echo extendedKeyUsage = serverAuth >> extfile.cnf

Ahora, genera el certificado firmado:

$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out server-cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=your.host.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:

Los complementos de autorización ( Authorization plugins) ofrecen un control más detallado para complementar la autenticación de TLS mutuo. Además de otra información descrita en el documento anterior, los complementos de autorización que se ejecutan en un demonio de Docker reciben la información del certificado de los clientes de Docker que se conectan.

Para la autenticación del cliente, crea una clave de cliente y una solicitud de firma de certificado:

Note

Para simplificar los siguientes pasos, también puedes realizar este paso en la máquina anfitriona del demonio de Docker.

$ openssl genrsa -out key.pem 4096
Generating RSA private key, 4096 bit long modulus
.........................................................++
................++
e is 65537 (0x10001)

$ openssl req -subj '/CN=client' -new -key key.pem -out client.csr

Para que la clave sea adecuada para la autenticación del cliente, crea un nuevo archivo de configuración de extensiones:

$ echo extendedKeyUsage = clientAuth > extfile-client.cnf

Ahora, genera el certificado firmado:

$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out cert.pem -extfile extfile-client.cnf
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:

Después de generar cert.pem y server-cert.pem, puedes eliminar de forma segura las dos solicitudes de firma de certificado y los archivos de configuración de extensiones:

$ rm -v client.csr server.csr extfile.cnf extfile-client.cnf

Con una umask por defecto de 022, tus claves secretas son legibles para cualquiera y editables por ti y tu grupo.

Para proteger tus claves de daños accidentales, quítales los permisos de escritura. Para hacerlas legibles únicamente por ti, cambia los modos de archivo de la siguiente manera:

$ chmod -v 0400 ca-key.pem key.pem server-key.pem

Los certificados pueden ser legibles para cualquiera, pero es recomendable quitar el acceso de escritura para evitar daños accidentales:

$ chmod -v 0444 ca.pem server-cert.pem cert.pem

Ahora puedes hacer que el demonio de Docker solo acepte conexiones de clientes que proporcionen un certificado de confianza de tu CA:

$ dockerd \
    --tlsverify \
    --tlscacert=ca.pem \
    --tlscert=server-cert.pem \
    --tlskey=server-key.pem \
    -H=0.0.0.0:2376

Para conectarte a Docker y validar su certificado, proporciona tus claves de cliente, certificados y la CA de confianza:

Tip

Este paso debe ejecutarse en tu máquina de cliente de Docker. Por lo tanto, debes copiar tu certificado de CA, tu certificado de servidor y tu certificado de cliente a esa máquina.

Note

Reemplaza todas las instancias de $HOST en el siguiente ejemplo con el nombre DNS del anfitrión de tu demonio de Docker.

$ docker --tlsverify \
    --tlscacert=ca.pem \
    --tlscert=cert.pem \
    --tlskey=key.pem \
    -H=$HOST:2376 version
Note

Docker sobre TLS debe ejecutarse en el puerto TCP 2376.

Warning

Como se muestra en el ejemplo anterior, no necesitas ejecutar el cliente docker con sudo o el grupo docker cuando utilizas autenticación por certificado. Eso significa que cualquiera que tenga las claves puede dar cualquier instrucción a tu demonio de Docker, otorgándole acceso de root a la máquina que aloja al demonio. ¡Guarda estas claves como lo harías con una contraseña de root!

Seguridad por defecto

Si quieres proteger tus conexiones del cliente de Docker por defecto, puedes mover los archivos al directorio .docker en tu directorio de inicio, y también configurar las variables DOCKER_HOST y DOCKER_TLS_VERIFY (en lugar de pasar -H=tcp://$HOST:2376 y --tlsverify en cada llamada).

$ mkdir -pv ~/.docker
$ cp -v {ca,cert,key}.pem ~/.docker

$ export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1

Ahora Docker se conecta de forma segura por defecto:

$ docker ps

Otros modos

Si no quieres tener una autenticación bidireccional completa, puedes ejecutar Docker en varios otros modos combinando las banderas.

Modos del demonio

  • tlsverify, tlscacert, tlscert, tlskey configurados: Autenticar clientes
  • tls, tlscert, tlskey: No autenticar clientes

Modos de cliente

  • tls: Autentica al servidor basándose en el conjunto de CA públicas/por defecto
  • tlsverify, tlscacert: Autentica al servidor basándose en la CA proporcionada
  • tls, tlscert, tlskey: Autentica con el certificado de cliente, no autentica al servidor basándose en la CA proporcionada
  • tlsverify, tlscacert, tlscert, tlskey: Autentica con el certificado de cliente y autentica al servidor basándose en la CA proporcionada

Si se encuentra, el cliente envía su certificado de cliente, por lo que basta con colocar tus claves en ~/.docker/{ca,cert,key}.pem. Alternativamente, si quieres guardar tus claves en otra ubicación, puedes especificar esa ubicación utilizando la variable de entorno DOCKER_CERT_PATH.

$ export DOCKER_CERT_PATH=~/.docker/zone1/
$ docker --tlsverify ps

Conectar al puerto seguro de Docker usando curl

Para usar curl para realizar solicitudes de API de prueba, debes usar tres banderas adicionales de la línea de comandos:

$ curl https://$HOST:2376/images/json \
  --cert ~/.docker/cert.pem \
  --key ~/.docker/key.pem \
  --cacert ~/.docker/ca.pem

Información relacionada