Como resolver “Este site não é seguro” em ambiente local com docker e docker-compose

Precisas de correr um site localmente por https, mas não sabes como o fazer através de uma ligação segura? Descubre como o fazer neste artigo.

Em primeiro, cria a estrutura abaixo numa pasta:

my-project
-- docker-compose.yml
-- nginx (folder)
---- Dockerfile
---- default.conf
---- mydomain.local.ext
-- index.php

Adiciona o código abaixo ao ficheiro docker-compose.yml.

version: "3"services:
nginx:
build: ./nginx
container_name: nginx
ports:
- 80:80
- 443:443
volumes:
- $PWD/nginx/default.conf:/etc/nginx/conf.d/default.conf
- $PWD:/usr/share/nginx/html
- ssl:/etc/ssl
php:
image: php:7.1-fpm
container_name: php
volumes:
- $PWD:/var/www/html
volumes:
ssl:

Adicionar o código abaixo ao ficheiro nginx/Dockerfile.

FROM nginx:1.12
ADD ./mydomain.local.ext /etc/ssl/mydomain.local.ext
RUN apt-get update \
&& apt-get install -y openssl \
&& NAME=mydomain.local \
&& openssl genrsa -out /etc/ssl/myCA.key 2048 \
&& openssl req -x509 -new -nodes -key /etc/ssl/myCA.key -sha256 -days 3650 -out /etc/ssl/myCA.pem \
-subj "/C=PT/ST=Lisbon/L=Lisbon/O=MyCompany/OU=IT Department/CN=$NAME" \
&& openssl genrsa -out /etc/ssl/$NAME.key 2048 \
&& openssl req -new -key /etc/ssl/$NAME.key -out /etc/ssl/$NAME.csr \
-subj "/C=PT/ST=Lisbon/L=Lisbon/O=MyCompany/OU=IT Department/CN=$NAME" \
&& openssl x509 -req -in /etc/ssl/$NAME.csr -CA /etc/ssl/myCA.pem -CAkey /etc/ssl/myCA.key -CAcreateserial \
-out /etc/ssl/$NAME.crt -days 3650 -sha256 -extfile /etc/ssl/$NAME.ext

PS: mydomain.local deve ser o domínio que queres usar.

Adiciona o código abaixo ao ficheiro nginx/mydomain.local.ext.

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = mydomain.local

PS: mydomain.local deve ser o domínio que queres usar.

Adiciona o código abaixo ao ficheiro nginx/default.conf.

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name mydomain.local;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /etc/ssl/mydomain.local.crt;
ssl_certificate_key /etc/ssl/mydomain.local.key;
server_name mydomain.local;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

location / {
root /usr/share/nginx/html;
index index.php index.html index.htm;
try_files $uri $uri/ /index.php?$uri&$args;
}

location ~ \.php$ {
root /var/www/html;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SERVER_NAME $http_host;
include fastcgi_params;
}
}

PS: mydomain.local deve ser o domínio que queres usar.

Adiciona o programa Olá Mundo ao ficheiro index.php.

<?php echo 'Olá Mundo'; ?>

Executa os container em background com o comando abaixo:

docker-compose up -d

Agora, podes aceder a https://mydomain.local no teu browser. Não te esqueças de adicionar mydomain.local ao teu ficheiro de hosts (/etc/hosts). Vais ver algo como a imagem abaixo.

Podes clicar no botão Advanced e de seguida no link Proceed to mydomain.local (unsafe). No entanto, vais continuar a receber a mensagem Your connection to this site is not secure.

Para resolver isto, basta copiar o ficheiro do Certificate Authority do container e adicioná-lo ao teu browser. Para copiar o Certificate Authority, executa o comando abaixo (eu vou copiá-lo para a pasta ~/Downloads, mas podes escolher outra qualquer):

docker cp nginx:/etc/ssl/myCA.pem ~/Downloads/myCA.pem

Como importar o Certificate Authority no Google Chrome

Abre o Google Chrome » Clica nos três pontos » Settings » Privacy and Security » Security » Manage Certificates » Authorities » Import » Choose the copied file » Check all the checkboxes » Click Ok » Fecha e re-abre o Google Chrome.

Como importar o Certificate Authority no FireFox

Abre o FireFox » Clica nos três pontos » Preferences » Privacy and Security » Certificates » View Certificates » Authorities » Import… » Choose the copied file » Check all the checkboxes » Click Ok.

Como usar os certificados em outros containers

Às vezes vais precisar de usar certificados em outros containers. Para fazer isso é muito simples, basta adicionar o volume ssl ao respectivo container. Abaixo, mostro-te como podes fazer isso num caso real (eu vou fazer isso para o Mosquitto Broker).

mqtt:
image: eclipse-mosquitto:1.6.12
container_name: mqtt
depends_on:
- nginx
ports:
- 1883:1883
- 1884:1884
volumes:
- ssl:/mosquitto/ssl

Neste caso, vais ter os certificados gerados pelo container Nginx no container MQTT na pasta /mosquitto/ssl.

Podes obter o código completo no GitHub https://github.com/luiscoutinh/fix-unsecure-connection

Full Stack Web Developer