Instalar certificado PFX en nginx

Nos habrá pasado muchas veces, que nos pasan un certificado web en formato PFX y nos rompemos la cabeza para poder instalarlo en un servidor web apache o nginx.

Pues con esta pequeña entrada explico como extraer la clave privada, intermedia y publica del certificado PFX para poder utilizarlo en un servidor web apache o nginx.

Lanzamos estos comandos openssl para extraer las claves.

# Extraemos la clave pública
openssl pkcs12 -in ./certificado.pfx -clcerts -nokeys -out publica.crt

# Extraemos la clave intermedia
openssl pkcs12 -in ./certificado.pfx -clcerts -nokeys -chain -out intermedia.crt

# Extraemos la clave privada
openssl pkcs12 -in ./certificado.pfx -nocerts -nodes -out privada.rsa


Juntamos la clave intermedia y publica en un fichero fullchain.crt

cat intermedia.crt >> fullchain.crt
cat publica.crt >> fullchain.crt

Y creamos el fichero ssl.conf para utilizar el certificado en un nginx

server {
  server_name example.org;
  listen 443 ssl;
  ssl_certificate /etc/nginx/ssl/fullchain.crt;
  ssl_certificate_key /etc/nginx/ssl/privado.rsa;
  ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers         HIGH:!aNULL:!MD5;
}

Poner certificado https en nginx con Let’s encrypt y Docker

Poner certificados https muchas veces nos da verdaderos dolores de cabeza, pero para solucionarnos este problema se crearon los certificados Let’s encrypt que de una manera sencilla nos permite utilizar certificados gratuitos y renovarlos periódicamente.

En esta entrada voy a explicar a poner el certificado en entornos con docker y lo primero que vamos a hacer es crear el docker-compose.yml donde crearemos el contenedor para el nginx.

version: '3'

services:
  nginx:
    image: nginx:latest
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - ./nginx/conf.d/:/etc/nginx/conf.d/:ro

A continuación creamos el fichero de configuración del nginx ( ./nginx/conf.d/default.conf ) cambiando example.org pro nuestro dominio.

server {
    listen 80;
    listen [::]:80;

    server_name example.org www.example.org;
    server_tokens off;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://example.org$request_uri;
    }
}

Ahora arrancamos el contenedor y vemos como el nginx es accesible.

docker-compose up -d

El siguiente paso es crear el servicio certbot que se encargara de crear nuestro certificado editando el fichero docker-compose.yml.

version: '3'

services:

  webserver:
    image: nginx:latest
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - ./nginx/conf.d/:/etc/nginx/conf.d/:ro
      - ./certbot/www/:/var/www/certbot/:ro
      - ./certbot/conf.d/:/etc/nginx/ssl/:ro

  certbot:
    image: certbot/certbot:latest
    volumes:
      - ./certbot/www/:/var/www/certbot/:rw
      - ./certbot/conf.d/:/etc/letsencrypt/:rw

Volvemos a lanzar el docker-compose para crear los directorios que utilizara certbot

docker-compose up -d

Una vez cambiado el docker-compose.yml lanzamos el comando para crear los certificados, cambiando el dominio example.org por el nuestro.

docker-compose run --rm  certbot certonly --webroot --webroot-path /var/www/certbot/ -d example.org

Una vez que ya tengamos los certificados creados editamos el fichero de configuración del nginx (./nginx/conf.d/default.conf) cambiando el dominio example.org por el nuestro.

En el ejemplo uso el nginx como proxy para servir un tomcat.

server {
    listen 80;
    listen [::]:80;

    server_name example.org www.example.org;
    server_tokens off;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://example.org$request_uri;
    }
}

server {
    listen 443 default_server ssl http2;
    listen [::]:443 ssl http2;

    server_name example.org;

    ssl_certificate /etc/nginx/ssl/live/example.org/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/live/example.org/privkey.pem;
    
    location / {
      proxy_pass      http://127.0.0.1:8080;
    }
}

Ya por ultimo paramos el contenedor del nginx y recreamos los contenedores.

docker stop nginx

docker-compose up -d

Y ya tendriamos nuestra web accesible con https y certificado seguro.

Como ultimo paso añado el comando que tenemos que utilizar cuando queramos renovar el certificado.

docker-compose run --rm certbot renew