Certificado SSL para aplicaciones web de Docker

En este artículo quiero compartir con ustedes un método para crear un certificado SSL para su aplicación web que funciona en Docker, ya que no encontré una solución similar en la parte de habla rusa de Internet.

Certificado SSL para aplicaciones web de Docker

Más detalles debajo.

Teníamos Docker v.17.05, docker-compose v.1.21, Ubuntu Server 18 y una pizca de Let’sEncrypt puro. No es que sea necesario desplegar producción en Docker. Pero una vez que comienzas a construir en Docker, se vuelve difícil detenerse.

Así que para empezar, proporcionaré las configuraciones estándar que teníamos en la etapa de dev, es decir, sin el puerto 443 y SSL en general:

docker-compose.yml

version: '2'
services:
    php:
        build: .\/php-fpm
        volumes:
            - .\/StomUp:\/var\/www\/StomUp
            - .\/php-fpm\/php.ini:\/usr\/local\/etc\/php\/php.ini
        depends_on:
            - mysql
        container_name: "StomPHP"
    web:
        image: nginx:latest
        ports:
            - "80:80"
            - "443:443"
        volumes:
            - .\/StomUp:\/var\/www\/StomUp
            - .\/nginx\/main.conf:\/etc\/nginx\/conf.d\/default.conf
        depends_on:
            - php
    mysql:
        image: mysql:5.7
        command: mysqld --sql_mode=""
        environment:
            MYSQL_ROOT_PASSWORD: xxx
        ports:
            - "3333:3306"

nginx\/main.conf

 server {
    listen 80;
    server_name *.stomup.ru stomup.ru;
   root \/var\/www\/StomUp\/public;
     client_max_body_size 5M;

    location \/ {
        # intentar servir el archivo directamente, volver a index.php
        try_files $uri \/index.php$is_args$args;
  }

    location ~ ^\/index.php(\/|$) {
      #fastcgi_pass unix:\/var\/run\/php7.2-fpm.sock;
       fastcgi_pass php:9000;
       fastcgi_split_path_info ^(.+.php)(\/.*)$;
      include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
       fastcgi_param DOCUMENT_ROOT $realpath_root;
        fastcgi_buffer_size 128k;
       fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
       internal;
    }

    location ~ .php$ {
        return 404;
    }

     error_log \/var\/log\/nginx\/project_error.log;
    access_log \/var\/log\/nginx\/project_access.log;
}

A continuación, necesitamos implementar SSL. Para ser honesto, estudié la zona com durante aproximadamente 2 horas. Todas las opciones propuestas allí son interesantes. Pero en esta etapa del proyecto, necesitábamos (el negocio) integrar rápida y confiablemente SSL Let’sEncrypt a nginx al contenedor y no más.

Primero instalamos en el servidor certbot
sudo apt-get install certbot

Después generamos certificados wildcard para nuestro dominio

sudo certbot certonly -d stomup.ru -d *.stomup.ru --manual --preferred-challenges dns


después de ejecutar certbot, se nos proporcionarán 2 registros TXT que deben ser indicados en la configuración de DNS.

_acme-challenge.stomup.ru TXT {laClaveQueTeDioCertBot}


Y presionamos enter.

Después de esto, certbot verificará la existencia de esos registros en DNS y creará los certificados para usted.
si has añadido el certificado, pero certbot no lo encontró, intenta reiniciar el comando en 5-10 minutos..

Ahora somos orgullosos propietarios de un certificado Let’sEncrypt por 90 días, pero ahora necesitamos integrarlo en Docker.

Para ello, simplemente en el docker-compose.yml, en la sección de nginx, vinculamos los directorios.

Ejemplo de docker-compose.yml con SSL

version: '2'
services:
    php:
        build: ./php-fpm
        volumes:
            - ./StomUp:/var/www/StomUp
            - /etc/letsencrypt/live/stomup.ru/:/etc/letsencrypt/live/stomup.ru/
            - ./php-fpm/php.ini:/usr/local/etc/php/php.ini
        depends_on:
            - mysql
        container_name: "StomPHP"
    web:
        image: nginx:latest
        ports:
            - "80:80"
            - "443:443"
        volumes:
            - ./StomUp:/var/www/StomUp
            - /etc/letsencrypt/:/etc/letsencrypt/
            - ./nginx/main.conf:/etc/nginx/conf.d/default.conf
        depends_on:
            - php
    mysql:
        image: mysql:5.7
        command: mysqld --sql_mode=""
        environment:
            MYSQL_ROOT_PASSWORD: xxx
        ports:
            - "3333:3306"

¿Vinculamos? Genial, continuamos:

Ahora necesitamos modificar la configuración nginx para trabajar con 443 el puerto y SSL en general:

Ejemplo de la configuración main.conf con SSL

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

	server_name *.stomup.ru stomup.ru;
	set $base /var/www/StomUp;
	root $base/public;

	# SSL
	ssl_certificate /etc/letsencrypt/live/stomup.ru/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/stomup.ru/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/stomup.ru/chain.pem;

      client_max_body_size 5M;

      location / {
          # try to serve file directly, fallback to index.php
          try_files $uri /index.php$is_args$args;
      }

      location ~ ^/index.php(/|$) {
          #fastcgi_pass unix:/var/run/php7.2-fpm.sock;
          fastcgi_pass php:9000;
          fastcgi_split_path_info ^(.+.php)(/.*)$;
          include fastcgi_params;
          fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
          fastcgi_param DOCUMENT_ROOT $realpath_root;
          fastcgi_buffer_size 128k;
          fastcgi_buffers 4 256k;
          fastcgi_busy_buffers_size 256k;
          internal;
      }

      location ~ .php$ {
          return 404;
      }

      error_log /var/log/nginx/project_error.log;
      access_log /var/log/nginx/project_access.log;
}


# HTTP redirect
server {
	listen 80;
	listen [::]:80;

	server_name *.stomup.ru stomup.ru;

	location / {
		return 301 https://stomup.ru$request_uri;
	}
}

Después de estas maniobras, vamos al directorio con Docker-compose, escribimos docker-compose up -d. Y verificamos la operatividad de SSL. Todo debería funcionar.

No olviden que el certificado Let’sEncrypt se emite por 90 días y necesitarán renovarlo con el comando sudo certbot renew, y luego reiniciar el proyecto con el comando docker-compose restart

Como alternativa, agregar esta secuencia en crontab.

En mi opinión, esta es la forma más sencilla de conectar SSL a una aplicación web en Docker.

P.D. Tengan en cuenta que todos los scripts presentados en el texto no son definitivos, actualmente el proyecto se encuentra en una fase de desarrollo profundo, por lo que les pido que no critiquen las configuraciones, ya que cambiarán muchas veces.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster