DEV Community

Raül Martínez i Peris
Raül Martínez i Peris

Posted on

Windows: container Windows + container Linux (III)

Índice

  • Sección primera (básico):
    • Docker en Windows. Apartado I: Instalar WSL2 (y Docker).
    • Docker en Windows. Apartado II: Instalar Docker en Windows 11.
  • Sección segunda (avanzado):
    • Docker en Windows. Apartado III: Confianza entre entornos.
    • Docker en Windows. Apartado IV: Configurar conexión entre Docker Windows y Docker WSL.
    • Docker en Windows. Apartado V: Instalar Portainer en el entorno WSL.
    • Docker en Windows. Apartado VI: Apuntes.

Con este artículo empezamos la sección avanzada. Además, este apartado lo dividiremos en dos partes: la primera para la creación un certificado CA; y, la segunda para la creación de los certificados TLS que necesitaremos.

Apartado III. Confianza entre entornos

¿Para qué necesitamos tener un certificado de una CA?

Vamos a conectar el docker de Windows con el docker de WSL, para lo cual al tener que realizar la conexión por dominio/IP necesitamos que ambas virtualizaciones confíen entre ellas... lo que no s obliga a tener certificados firmados por una CA. Aquí tenemos dos opciones: pagamos o no pagamos. Para esta sección de Docker nos interesa el aprendizaje de crear la CA y utilizarla.


Primera parte: Crear una CA (Autoridad Certificadora) para usos internos

Descargar e instalar OpenSSL

Descarga el instalador de OpenSSL Win32OpenSSL de slproweb. Este instalador es un empaquetado por un tercero, si necesitas el código de OpenSSL sin empaquetar tienes los enlaces al final del artículo. Sea cual sea la opción que tomes debe instalarlo antes de continuar.

Configurar OpenSSL

Abre una consola Powershell.

Lo primero que haremos es añadir la ruta del ejecutable al path:

[Environment]::SetEnvironmentVariable("PATH", "$env:PATH;C:\Program Files\OpenSSL-Win64\bin", [EnvironmentVariableTarget]::Machine)
Enter fullscreen mode Exit fullscreen mode

Asegúrate de haber realizado la instalación en la ruta indicada, o, en caso de que difiera actualiza los datos de la variable de entorno.

Una vez hecho esto debemos reiniciar la consola para que surta efecto.

Ubicación sugerida para los certificados

Normalmente la instalación de Docker crea todas las carpetas necesarias, pero, si no existiera lo correcto es crear la siguiente carpeta C:\ProgramData\certs:

New-Item -ItemType Directory -Force -Path "C:\ProgramData\certs"
Enter fullscreen mode Exit fullscreen mode

Generar los certificados utilizando OpenSSL

Antes de continuar: Recuerda que debes poner especial cuidado en la salvaguarda de las contraseñas, ficheros llave y certificados.

Generar la Llave y el Certificado de la CA (Autoridad Certificadora)

Para que un certificado actúe como CA, debe tener la extensión Basic Constraints con CA:TRUE.

Nos situamos en el directorio:

cd "C:\ProgramData\certs"
Enter fullscreen mode Exit fullscreen mode

Crea un archivo llamado ca.cnf con el siguiente contenido:

[ req ]
distinguished_name = req_distinguished_name
x509_extensions = v3_ca
prompt = no
[ req_distinguished_name ]
C = ES
ST = Comunitat Valenciana
L = Valencia
O = EMPRESA
OU = UNIDAD EMPRESARIAL
CN = Mi CA para Docker
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:TRUE
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
Enter fullscreen mode Exit fullscreen mode

Ajusta los campos C (Country), ST (State or Province), L (Locality), O (Organization), OU (Organizational Unit) y CN (Common Name) según tus necesidades.

Es importante utilizar un CN que nos permita tener una buena descripción de su cometido, por ejemplo un CN conveniente para este caso sería ca-$($env:COMPUTERNAME)-$($env:USERNAME). Al final del artículo hemos añadido información relevante para su correcta definición.

Genera el certificado llave:

openssl genrsa -aes256 -out ca-key.pem 4096
Enter fullscreen mode Exit fullscreen mode

Te pedirá una contraseña para la clave de la CA. Esta contraseña es necesaria para firmar otros certificados. Como es habitual, guárdatela en tu Keepass o similar.

Genera el certificado (te pedirá la contraseña que has introducido en la llave):

openssl req -new -x509 -days 3650 -key ca-key.pem -sha256 -out ca.pem -config ca.cnf
Enter fullscreen mode Exit fullscreen mode

Ahora para confirmar que es correcto, lanza el siguiente comando:

openssl x509 -in ca.pem -text -noout | Select-String "CA"
Enter fullscreen mode Exit fullscreen mode

En el resultado tendrás que ver que basicConstraints está como critical y con CA:TRUE.

Configurar los permisos de los archivos para WSL

Para ello entramos en una terminal Powershell en modo "Administrador" e introducimos:

wsl -d ubuntu
Enter fullscreen mode Exit fullscreen mode

Ahora nos situamos en el directorio certs:

cd /mnt/c/ProgramData/certs
Enter fullscreen mode Exit fullscreen mode

Ahora limpiamos los archivos sobrantes:

rm *.csr *.cnf *.srl
Enter fullscreen mode Exit fullscreen mode

Por último, vamos a cambiar los permisos:

chmod -v 0400 ca-key.pem
chmod -v 0444 ca.pem
Enter fullscreen mode Exit fullscreen mode

¿Porqué hemos cambiado los permisos desde la terminal de Ubuntu?

Por dos razones:

  • Es más simple que con Powershell.
  • Nos aseguramos que tenemos acceso a los archivos en el disco C: de Windows desde el entorno WSL.

Evidentemente, puedes optar por cambiar los permisos desde Powershell.


Segunda parte: Configuración de la comunicación interna de los entornos

Debes tener un certificado CA antes de continuar.

Generar certificados TLS

Antes de configurar Docker tanto en Windows como WSL necesitas generar los certificados TLS. Estos certificados asegurarán la comunicación entre el cliente Docker y el daemon Docker. Necesitarás una Autoridad Certificadora (CA), el cual ya lo habrás preparado anteriormente.

Normalmente la instalación de Docker crea todas las carpetas necesarias, pero, si no existiera lo correcto es crear la carpeta C:\ProgramData\docker\certs para los certificados:

New-Item -ItemType Directory -Force -Path "C:\ProgramData\docker\certs"
Enter fullscreen mode Exit fullscreen mode

Nos situamos en el directorio:

cd "C:\ProgramData\docker\certs"
Enter fullscreen mode Exit fullscreen mode

Generar los certificados utilizando OpenSSL

Es necesario que tengas un certificado de una CA para realizar los siguientes pasos como se indicó en el anterior apartado.

Si ha seguido las indicaciones del documento, tendrás en la carpeta C:\ProgramData\certs el certificado CA ya creado. Créate el enlace en una variable para acceder rápidamente a ellos:

$caPem = "C:\ProgramData\certs\ca.pem"
$caKeyPem = "C:\ProgramData\certs\ca-key.pem"
Enter fullscreen mode Exit fullscreen mode

Generar Clave y Certificado del Servidor para Docker en Windows

En este paso tendremos en cuenta que debemos configurarlo para que escuche a través de localhost.

openssl genrsa -out win-server-key.pem 4096
openssl req -subj "/CN=localhost" -sha256 -new -key win-server-key.pem -out win-server.csr
Enter fullscreen mode Exit fullscreen mode

Consultamos el nombre de nuestro equipo lanzando el comando:

hostname
Enter fullscreen mode Exit fullscreen mode

Ahora creamos el archivo extfile-win.cnf con el siguiente contenido utilizando el resultado de hostname (sustituyendo xNAMEx):

subjectAltName = DNS:localhost,IP:127.0.0.1,IP:::1,DNS:xNAMEx,DNS:wsl2docker.local
extendedKeyUsage = serverAuth
Enter fullscreen mode Exit fullscreen mode

Como es lógico, cambiamos el DNS indicado (xNAMEx) por el nombre de tu máquina, y, además introducimos un nuevo DNS que será utilizado para “conectar” el entorno Windows y WSL sin necesidad de depender de una IP (esto nos permite que el certificado continúe siendo válido incluso si nos cambia la IP).

Ahora firma la CSR del servidor de Windows con tu CA:

$caPem = "C:\ProgramData\certs\ca.pem"
$caKeyPem = "C:\ProgramData\certs\ca-key.pem"
Copy-Item -Path $caPem "C:\ProgramData\docker\certs\ca.pem"
openssl x509 -req -days 3650 -sha256 -in win-server.csr -CA ca.pem -CAkey $caKeyPem -CAcreateserial -out win-server-cert.pem -extfile extfile-win.cnf
Enter fullscreen mode Exit fullscreen mode

(te pedirá la contraseña de tu llave).

Generar Clave y Certificado del Servidor para Docker en WSL2

Seguimos los mismos pasos para el de WSL2:

openssl genrsa -out wsl-server-key.pem 4096
openssl req -subj "/CN=localhost" -sha256 -new -key wsl-server-key.pem -out wsl-server.csr
Enter fullscreen mode Exit fullscreen mode

Creamos el archivo configuración de extensiones extfile-wsl.cnf:

subjectAltName = DNS:localhost,IP:127.0.0.1,IP:::1,DNS:wsl2docker.local
extendedKeyUsage = serverAuth
Enter fullscreen mode Exit fullscreen mode

Firmamos el CSR del servidor de WSL2 con el CA:

openssl x509 -req -days 3650 -sha256 -in wsl-server.csr -CA ca.pem -CAkey $caKeyPem -CAcreateserial -out wsl-server-cert.pem -extfile extfile-wsl.cnf
Enter fullscreen mode Exit fullscreen mode

(te pedirá la contraseña de tu llave).

Generar Clave y Certificado del Cliente (para docker CLI)

Los mismos pasos:

openssl genrsa -out client-key.pem 4096
openssl req -subj "/CN=client" -new -key client-key.pem -out client.csr
Enter fullscreen mode Exit fullscreen mode

Creamos el archivo de configuración de extensiones extfile-client.cnf:

extendedKeyUsage = clientAuth
Enter fullscreen mode Exit fullscreen mode

Y firmamos el CSR:

openssl x509 -req -days 3650 -sha256 -in client.csr -CA ca.pem -CAkey $caKeyPem -CAcreateserial -out client-cert.pem -extfile extfile-client.cnf
Enter fullscreen mode Exit fullscreen mode

(te pedirá la contraseña de tu llave).

Configurar los permisos de los archivos

Aprovechamos que tenemos instalado WSL y terminamos de configurar los archivos desde la terminal de Ubuntu. Para ello entramos en una terminal powershell en modo "Administrador" e introducimos:

wsl -d ubuntu
Enter fullscreen mode Exit fullscreen mode

Ahora nos situamos en el directorio apropiado (certs de Docker):

cd /mnt/c/ProgramData/docker/certs
Enter fullscreen mode Exit fullscreen mode

Limpiamos los archivos sobrantes:

rm *.csr *.cnf *.srl
Enter fullscreen mode Exit fullscreen mode

Cambiamos los permisos:

chmod -v 0400 *-key.pem client-key.pem
chmod -v 0444 *-cert.pem client-cert.pem
Enter fullscreen mode Exit fullscreen mode

Salimos de la shell de Ubuntu:

exit
Enter fullscreen mode Exit fullscreen mode

Y cerramos la consola con permisos Administrador que hemos abierto.

Configurar Docker en Windows para utilizar los certificados TLS

Recordemos lo que tenemos. Los archivos resultantes se dividen en:

  • Clave CA o certificadora: archivos ca.pem y ca-key.pem. Estos archivos debes guardarlos offline en un lugar seguro.
  • Claves para el cliente docker: ca.pem, client-cert.pem y client-key.pem.

En cuanto a las claves para el cliente, terminarán siendo colocadas en otros directorios (pero esto lo veremos después): en WSL, en la carpeta ~/.docker/ y en windows en la carpeta %USERPROFILE%\.docker\. Vamos a ello.

Copiar las claves TLS a la carpeta de usuario

Primero, nos aseguramos de que los certificados de cliente (ca.pem, client-cert.pem, client-key.pem) están en %USERPROFILE%\.docker\ con el nombre adecuado. En la terminal de Powershell:

$userProfile = $env:USERPROFILE
$dockerDir = Join-Path $userProfile ".docker"
If (-not (Test-Path $dockerDir)) { New-Item -Path $dockerDir -ItemType Directory }
Copy-Item "$caPem" -Destination (Join-Path $dockerDir "ca.pem")
Copy-Item "C:\ProgramData\Docker\certs\client-cert.pem" -Destination (Join-Path $dockerDir "cert.pem")
Copy-Item "C:\ProgramData\Docker\certs\client-key.pem" -Destination (Join-Path $dockerDir "key.pem")
Enter fullscreen mode Exit fullscreen mode

Configuración del demonio

Utiliza Notepad++ (o el editor que prefieras) para crear el archivo:
C:\ProgramData\docker\config\daemon.json
con el contenido:

{
"hosts": ["tcp://0.0.0.0:2375", "npipe://"],
"tlsverify": true,
"tlscacert": "C:\\ProgramData\\docker\\certs\\ca.pem",
"tlscert": "C:\\ProgramData\\docker\\certs\\win-server-cert.pem",
"tlskey": "C:\\ProgramData\\docker\\certs\\win-server-key.pem"
}
Enter fullscreen mode Exit fullscreen mode

Configurar un contexto para Windows

Necesitaremos utilizar “contextos” de Docker, para entre otros, conectar sin problemas desde VSCode a Docker, o desde el otro entorno.

Pero, primero verificamos que no tenemos el contexto ya creado con anterioridad:

docker context ls
Enter fullscreen mode Exit fullscreen mode

(Nota: Si lo tienes deberías borrarlo, utiliza el comando docker context rm NombreContexto -f.)

Ahora, crea el contexto con el nombre “windows” para Windows:

docker context create windows --docker "host=tcp://localhost:2375,ca=$userProfile\.docker\ca.pem,cert=$userProfile\.docker\cert.pem,key=$userProfile\.docker\key.pem"
Enter fullscreen mode Exit fullscreen mode

Verifica que se ha creado correctamente:

docker context inspect windows
Enter fullscreen mode Exit fullscreen mode

Y actívalo:

docker context use windows
Enter fullscreen mode Exit fullscreen mode

Apuntes

Para crear una CA hay que tener en cuenta las siguientes normativas o estándares:

Enlaces

Siguiente artículo:

Top comments (0)