Docker Logo

Configurando Docker para acceso a través de HTTPs

Comentaba en el artículo anterior que activar el extremo de escucha HTTP en Docker para que otras máquinas de la red pudieran acceder al motor no era una buena práctica. Esto se debe a que al habilitarlo estamos dando acceso a cualquier persona que conozca la combinación de IP y puerto donde tenemos nuestra instancia de Docker en ejecución. Para protegerlo será necesario configurar Docker para que haga uso de la conexión a través de HTTPs.

El proceso de configuración no es trivial ya que lleva involucrado la creación de certificados para el servidor y los diferentes clientes que se conecten. Gracias a ellos, es posible establecer una relación de confianza entre ambos extremos de la conexión y así, en el caso de que otra persona se intente conectar sin disponer de los certificados correctos, el motor de Docker rechazará la conexión. Para crearlos necesitaremos trabajar con OpenSSL dentro de nuestra máquina con Linux.

A la hora de trabajar con sistemas de clave pública es necesario tener mucho cuidado en la configuración y gestión de su información como las claves privadas. Este artículo no entra en detalles de cómo montar una buena solución basada en OpenSSL, únicamente emplea los elementos necesarios para mostrar la configuración del acceso por HTTPs en Docker

Tras esta pequeña advertencia comenzamos.

Creando nuestra entidad certificadora

Para tener un poco ordenada la información relacionado con este proceso de generar los certificados trabajaremos con un directorio a nivel local de nuestro usuario. Dentro del mismo, crearemos varias subcarpetas para guardar los diferentes ficheros involucrados ref. En la primera guardaremos los certificados emitidos, en la segunda las peticiones para generar nuevos certificados, en la tercera la lista de revocación de certificados y por último, la que contendrá la información privada de nuestra CA. Necesitaremos protegerla para evitar el acceso por otros usuarios.

mkdir -p $HOME/CA/{certsdb,certreqs,crl,private}
chmod 700 CA/private

En el siguiente paso, crearemos los dos ficheros necesarios por nuestra entidad certificadora. El fichero index.txt es empleado por OpenSSL para llevar un listado de los certificados firmados y el fichero ca.srl los números de serie. Ambos forman la base de datos de nuestra entidad.

cd CA
echo "01" > ca.srl
touch index.txt

Tras ello, generaremos nuestra clave RSA privada de tamaño 2048 bits. Durante el proceso nos pedirá la clave de paso que queremos usar para protegerla.

openssl genrsa -des3 -out "CA/private/ca-private-key.pem" 2048
Configurando la entidad certificadora para Docker
Configurando la entidad certificadora para Docker

El siguiente paso será obtener la clave pública de nuestra entidad certificadora. Los campos que nos piden los podemos completar con nuestra información correcta o no, según deseamos. El que será importante será el definir el FQDN de nuestro servidor.

openssl req -new -x509 -days 365 -key "CA/private/ca-private-key.pem" -out "CA/private/ca-public-key.pem"
Configurando la entidad certificadora para Docker
Configurando la entidad certificadora para Docker

Generando el certificado para el servidor

Una vez que hemos terminado con nuestra entidad certificadora nos toca configurar ahora el certificado para nuestro motor de Docker. Para ello, tendremos que generar una nueva clave privada de forma similar a lo que hemos hecho anteriormente. Necesitaremos introducir una nueva clave de paso para protegerla.

openssl genrsa -des3 -out "CA/private/server-private-key.pem" 2048

Una vez que la tenemos el siguiente paso es solicitar una petición de firma de nuestro certificado, también conocido como Certificate Signing Request . Es muy importante sustituir el parámetro CN, Common Name, por el nombre del servidor al que nos conectaremos. En mi caso será jangelfdez.cloudapp.net. Será necesario introducir la clave que hemos definido en el paso anterior.

openssl req -subj '/CN=jangelfdez.cloudapp.net' -new -key "CA/private/server-private-key.pem" -out "CA/certreqs/server.csr"

Tras haber hecho la solicitud el siguiente paso es firmar nuestra clave por nuestra entidad certificadora. Para ello, ejecutamos lo siguiente.

openssl x509 -req -days 365 -in "CA/certreqs/server.csr" -CA "CA/private/ca-public-key.pem" -CAkey "CA/private/ca-private-key.pem" -CAserial "CA/ca.srl" -out "CA/certsdb/server-cert.pem"
Configurando la entidad certificadora para Docker
Configurando la entidad certificadora para Docker

Generando el certificado para el cliente

Este proceso será muy parecido al del apartado anterior, la única diferencia será que necesitaremos configurar una de las extensiones del certificado para que permita ser utilizado para autenticación. Por lo tanto, comenzamos creando la clave privada y generando la petición de firma de nuestro certificado.

openssl genrsa -des3 -out "CA/private/client-private-key.pem" 2048
openssl req -subj '/CN=client' -new -key "CA/private/client-private-key.pem" -out "CA/certreqs/client.csr"

Una vez que lo tenemos, configuramos la extensión para autenticación. Únicamente será necesario definir una pareja clave-valor y pasarle el fichero a la hora de firmar la petición.

echo extendedKeyUsage = clientAuth > extfile.cnf
openssl x509 -req -days 365 -in "CA/certreqs/client.csr "CA/private/ca-public-key.pem" -CAkey "CA/private/ca-private-key.pem" -CAserial "CA/ca.srl" -out "CA/certsdb/client-cert.pem" -extfile extfile.cnf

Configurando Docker para hacer uso de HTTPs

La parte complicada ya la hemos terminado, ahora necesitaremos dos cosas más antes de tener listo el acceso por HTTPs. En primer lugar, eliminar la frase de paso de las claves de nuestro cliente y servidor.

openssl rsa -in "CA/private/server-private-key.pem" -out "CA/private/server-private-key.pem"
openssl rsa -in "CA/private/client-private-key.pem" -out "CA/private/client-private-key.pem"

Tras ello, arrancamos nuestro motor de Docker pasándole los parámetros que especifican su certificado y clave correspondiente.

docker -d --tlsverify --tlscacert="CA/private/ca-public-key.pem" --tlscert="CA/certsdb/server-cert.pem" --tlskey="CA/private/server-private-key.pem" -H=0.0.0.0:2376
Ejecutando Docker con HTTPs
Ejecutando Docker con HTTPs

El servidor ya está configurado correctamente para aceptar únicamente peticiones a través de HTTPs y que se autentiquen con un certificado firmado por nuestra autoridad certificadora en el puerto 2376. Por lo tanto, faltará a nuestro cliente indicarle que queremos utilizar este tipo de autenticación lanzándolo con los siguientes parámetros.

docker.exe --tlsverify --tlscacert="C:\Users\jangelfdez\Desktop\ca-public-key.pem" --tlscert="C:\Users\jangelfdez\Desktop\client-cert.pem" --tlskey="C:\Users\jangelfdez\Desktop\client-private-key.pem" -H=jangelfdez.cloudapp.net:2376 info

Y con ello tendremos nuestro cliente desde Windows 10 conectado a nuestro motor de Docker a través de HTTPs.

Cliente de Windows de Docker conectado por HTTPs
Cliente de Windows de Docker conectado por HTTPs

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.