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

Redirección de http a https en apache.

En los albores de internet, podríamos decir que todo era mas “seguro” y existían muchos menos ataques malintencionados que ahora, con lo que todas las webs funcionaban bajo el protocolo http.

Con el tiempo se detecto que ese protocolo era inseguro ya que el trafico viajaba sin cifrar, con lo que se creo el protocolo seguro “https”, con lo que si queremos que nuestra web funcione siempre en con el protocolos seguro debemos de redirigir todo el trafico http a https.

A continuación paso a explicar como hacerlo el servidor web apache.

Si lo hacemos en un entorno ubuntu/debian los pasos de instalación serian estos:

#Instalamos apache2 
apt-get install apache2

#Habilitamos el módulo SSL y  rewrite
a2enmod ssl
a2enmod rewrite 

Y en centos estos:

#Instalar apache2 
yum install http

# Instalamos el módulo SSL y openssl
yum install mod_ssl openssl

#Añadimos modulo en fichero configuracion
vi /etc/httpd/conf/httpd.conf
LoadModule rewrite_module modules/mod_rewrite.so

A continuación en el fichero de configuración de apache redirigimos el trafico.

#debian/ubuntu
/etc/apache2/sites-enabled/000-default.conf
#centos
vim /etc/httpd/conf.d/000-vhost.conf

<VirtualHost *:80>
        RewriteEngine on
        ReWriteCond %{SERVER_PORT} !^443$
        RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R,L]
</VirtualHost>

Con esta configuración forzaremos que todo trafico http vaya al puerto https.