“Introducción”
Cuando queremos probar algo en local (una aplicación web), dentro de un contenedor, no podemos utilizar https como desde Visual Studio o IIS. Si necesitamos sí o sí https, debemos configurar algunas cosas, como por ejemplo, un certificado autofirmado, nginx, etc. En este post vamos a detaler cómo hacerlo.
Pasos
Vamos a necesitar hacer un par de cosas, voy a detallar los pasos a seguir en una PC con Windows y una aplicación .NET Core, es que lo que yo uso.
Básicamente pondremos nuestra aplicación en un contenedor, configuraremos nginx para que haga de proxy y que además tenga https. Luego un docker compose que levante todo.
Crear certificado autofirmado
Para crear certificados autofirmados, podemos utilizar openssl. En Windows, podemos instalarlo desde aquí.
y ejecutar este comando:
localhost.conf
[req]
default_bits = 2048
default_keyfile = localhost.key
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = v3_ca
[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Texas
localityName = Locality Name (eg, city)
localityName_default = Dallas
organizationName = Organization Name (eg, company)
organizationName_default = localhost
organizationalUnitName = organizationalunit
organizationalUnitName_default = Development
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = localhost
commonName_max = 64
[req_ext]
subjectAltName = @alt_names
[v3_ca]
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = 127.0.0.1
opensslreq-x509-nodes-days365-newkeyrsa:2048-keyoutlocalhost.key-outlocalhost.crt-configlocalhost.conf-passinpass:12345678
Esto creará dos archivos, localhost.crt y localhost.key, estos archivos los usuaremos en nginx.
Ahora necesitamos registrar el certificado como confiable ya que es auto-firmado. (es decir, registrar en Windows como confiable)
En el Administrador de Certificados (certmgr.msc), puedes encontrar esta ubicación siguiendo estos pasos:
Abrimos el Administrador de Certificados.
- Para esto escribimos certmgr.msc en el diálogo Ejecutar (Win + R).
- En el Administrador de Certificados, expande el árbol de Certificados “Usuario Actual” en el panel izquierdo.
- Debajo de esto, expande la carpeta Autoridades de Certificación Raíz Confiables.
Hacemos clic en la carpeta Certificados bajo Autoridades de Certificación Raíz Confiables.
Esta es la ubicación equivalente a Cert:\CurrentUser\Root en PowerShell.
Luego
En el Administrador de Certificados (certlm.msc, Certificate Manager for local machine), puedes encontrar esta ubicación siguiendo estos pasos:
- Abre el Administrador de Certificados para la Máquina Local. Puedes hacer esto escribiendo certlm.msc en el diálogo Ejecutar (Win + R).
- En el Administrador de Certificados, expande el árbol Certificados (Computadora Local) en el panel izquierdo.
- Debajo de esto, expande la carpeta Personal.
- Haz clic en la carpeta Certificados bajo Personal.
Ahora nginx usará los archivos de certificado y clave para servir https. Y deberías estar bien.
Configurar nginx
Para esto simplemente vamos a crear un archivo de configuración para nginx, que será el siguiente:
nginx.conf
worker_processes1;events{worker_connections1024;}http{sendfileon;upstreamweb-api{serverapi:80;}server{listen80;server_namelocalhost;location/{return301https://$host$request_uri;}}server{listen443ssl;server_namelocalhost;ssl_certificate/etc/ssl/certs/localhost.crt;ssl_certificate_key/etc/ssl/private/localhost.key;location/{proxy_passhttp://web-api;proxy_redirectoff;proxy_http_version1.1;proxy_cache_bypass$http_upgrade;proxy_set_headerUpgrade$http_upgrade;proxy_set_headerConnectionkeep-alive;proxy_set_headerHost$host;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_headerX-Forwarded-Proto$scheme;proxy_set_headerX-Forwarded-Host$server_name;}}}
Le decimos a nginx que utilice el certificado y la clave que creamos antes, y que escuche en el puerto 443. y con el proxy_pass le decimos que redirija las peticiones al servicio que escucha en el puerto 80. (más adelante ese será el nombre del servicio en el docker compose)
Ahora creamos el Dockerfile para nginx:
FROM nginx:alpineCOPY ./nginx.conf /etc/nginx/nginx.confCOPY localhost.crt /etc/ssl/certs/localhost.crtCOPY localhost.key /etc/ssl/private/localhost.keyCMD ["nginx", "-g", "daemon off;"]
Básicamente copiamos el archivo de configuración y los archivos de certificado y clave al contenedor.
Configurar nuestra app
En este caso una simple aplicación .NET Core, que escucha en el puerto 80.
FROMmcr.microsoft.com/dotnet/sdk:8.0ASbuildWORKDIR /appCOPY *.csproj ./RUN dotnet restore
COPY . ./RUN dotnet publish -c Release -o out
FROMmcr.microsoft.com/dotnet/aspnet:8.0ASruntimeWORKDIR /appENV ASPNETCORE_HTTP_PORTS 80EXPOSE 80EXPOSE 443COPY --from=build /app/out ./CMD ["dotnet", "app.dll"]
Docker compose
version:"3.7"services:reverseproxy:build:context:./nginxdockerfile:Dockerfile.nginxports:-"8080:80"-"1443:443"restart:alwaysapi:depends_on:-reverseproxybuild:context:.dockerfile:Dockerfileports:-"8088:80"restart:always
Simplemente apuntamos los dos servicios a sus Dockerfiles, y abrimos el puerto 1443 para https.
Si vemos algún error en el navegador relacionado con https lo más probable es que no hayamos registrado el certificado como confiable.
Dejo por acá un repositorio con el código
Nos leemos.