Https em localhost + https no docker + webpack

Precisei trabalhar com uma integração com iframes e login que envolvia o uso de cookies configurados como “SameSite=None; Secure”. Escrevi sobre isso neste outro artigo.

Para trabalhar com esta abordagem era necessário um ambiente com https. E podem existir outras razões pelas quais você precise testar algo em ambiente local com https. Este artigo descreve este processo tanto para apache sem docker como para softwares rodando em PHP com apache e com docker. Incluo também observações sobre uso com webpack devserver para integração com o front-end.

Observação: todas as referências estão para uso no Linux.

As configurações são muito simples. O que muitas vezes atrapalha é saber onde colocar as coisas.

De forma geral o que temos que fazer são DOIS PASSOS.

  1. Gerar um certificado local auto assinado;
  2. Informar o apache para usar este certificado que estará na nossa máquina local.

Naturalmente virão os detalhes referentes a como gerar o certificado, onde salvá-lo, como configurar, especialmente no docker e por aí vai.

Antes de irmos aos detalhes talvez você prefira ir diretamente nos artigos em inglês que me ajudaram:

  • YeahHub: Foi minha principal fonte de tutorial por organizar os passos muito cuidadosamente;
  • LinuxHint: É tão bom como o primeiro, usei como referência para me ajudar a avaliar se o primeiro estava adequado;
  • SslShopper: Como é organizado em menos passos foi deste que tive a percepção mais clara de que no fim das contas, são apenas dois macro passos.

Gerar o certificado local auto assinado

Para nosso uso, um certificado auto assinado serão dois arquivos, um arquivo público do certificado e o arquivo privado do certificado que rodarão em máquina local. Este certificado não precisa ter absolutamente nada demais. Precisamos apenas gerar estes dois arquivos com o programa adequado e depois informar ao Apache onde estão estes arquivos.

Uma forma de gerar este cerificado é com o comando abaixo usando o “openssl”.

sudo openssl req -x509 -nodes -days 1095 -newkey rsa:2048 -out /etc/ssl/certs/server.crt -keyout /etc/ssl/private/server.key

O mais importante neste comando é o final dele onde você informa a pasta onde os arquivos serão gerados. Neste exemplo está em “/etc/ssl/” mas você pode colocar onde quiser.

O programa irá pedir alguns dados, você pode colocar qualquer informação em todas as perguntas, é irrelevante.

Agora, se formos dar uma olhada na pasta onde o arquivo .crt foi gerado, teremos uma surpresa ao ver que o certificado é composto de uma grande quantidade de outros arquivos menores:

Isso será relevante mais à frente.

Com o certificado gerado, precisamos agora informá-lo ao apache.

Configurando o Certificado no Apache

Agora, basta entrar no arquivo de configuração do seu site no apache, que pode ser o default-ssl.conf ou algum específico para o site e adicionar o caminho do certificado nas diretivas:

SSLCertificateFile /etc/ssl/certs/server.crt
SSLCertificateKeyFile /etc/ssl/private/server.key

Caso você esteja editando um arquivo de configuração pessoal de um side vai precisar adicionar esta configuração dentro de uma configuração para a porta 443 e com “SSLEngine On”. Segue exemplo:

<VirtualHost *:443>
    ServerName meusitebonitao.local
    DocumentRoot /home/eu/www/meusitebonitao
    ...
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/server.crt
    SSLCertificateKeyFile /etc/ssl/private/server.key
    ...
</VirtualHost>

Reinicie o apache e acesse seu site local agora com https. Ex: https://meusitebonitao.local

Você verá o famoso aviso do navegados dizendo que seu site não é seguro. Basta clicar em avançar, adicionar exceção e seguir em frente. O certificado é totalmente falso, não poderíamos esperar algo melhor que isso não é? 😉

Configurando o certificado com apache o Docker

Para o bom funcionamento com docker precisamos entender como sobrescrever o arquivo de configuração do apache dentro do docker e como fazer o container acessar os arquivos do certificado.

Embora o processo continue bem simples, apenas informar o apache sobre o certificado, temos que suprir duas carências primeiro:

  1. Como o certificado ser lido dentro do container;
  2. Como configurar o apache dentro de um container docker PHP.

Minha principal fonte de referência foi este artigo aqui, ele é muito completo, mostra inclusive os passos anteriores que já apresentei aqui e foca totalmente na configuração do docker: https://dockerwebdev.com/tutorials/docker-php-development/

Eu fiz algumas coisas diferentes deste artigo. Então, sugiro dar uma olhada lá antes de continuar aqui para ter um bom entendimento das duas possibilidades. Vamos lá.

Criando o certificado dentro do Docker

Nós precisamos que o docker consiga ler o certificado. Para isso os arquivos do certificado precisam ser acessíveis na estrutura de diretórios do container. Existem algumas formas de fazer isso:

  • Criar o certificado no processo de build da imagem;
  • Copiar a pasta que contém os certificados para uma pasta do container no build da imagem;
  • Montar um volume;
  • Colocar o certificado na própria estrutura de pastas do projeto.

Embora avalie que se conseguir fazer a primeira possibilidade seria o melhor dos cenários, eu fui, por comodidade para a última opção. Eu simplesmente coloquei o certificado em uma pasta dentro do projeto copiando ele do diretório onde foi gerado:

Imagem do certificados na pasta public do projeto

Embora o local onde eu coloquei os arquivos seja bastante questionável (pasta public) você coloca onde quiser, não faz diferença nenhuma. E você pode ou não fazer o commit do certificado. Depende de como vai trabalhar com a equipe. Idealmente você ignorará a pasta e cada dev pode cuidar do seu certificado local. Não é importante, porque, lembrando, é um certificado falso, útil somente para fins de teste em ambiente local.

O único segredo é que muitos arquivos do certificado são links simbólicos, eu preferi copiar os arquivos integralmente, para isso é importante usar a diretiva “-L” que ao invés de copiar o link simbólico, copia o conteúdo dos arquivos mesmo:

cd /public/ssl/
sudo cp -L -rf /etc/ssl/* .

Configurando o certificado no Docker

Eu utilizo em projetos o docker compose. Minha imagem PHP é a imagem oficial “php:8.0-apache-buster”.

No arquivo de build da imagem é importante garantir a instalação do módulo de ssl do apache.

No arquivo docker-compose.yaml adicione as seguintes configurações:

O importante na imagem acima são as configurações de portas e de volumes.

Eu evito usar as portas padrão 80 e 443 porque em algumas situações eu uso o apache localmente sem docker, então, deixo estas portas para o uso sem docker. No docker, tento personalizar. Assim, neste projeto a porta http normal ficou a 91 e a porta https ficou a 14443.

Os dois arquivos de volumes são o que importam para configurarmos, primeiro o mais simples, o arquivo ports.conf.

Este arquivo tem o seguinte conteúdo:

E no arquivo de configuração o nosso default.conf eu adicionei a seguinte configuração:

Perceba que a configuração é o padrão, mas com as inclusões da porta 14443 que estou usando internamente no Docker e a MESMÍSSIMA configuração que fizemos no apache sem docker, apenas, claro, alterando o caminho dos arquivos de certificado que precisam ser relativos à estrutura de pastas do docker.

Está pronto?

Bem, no meu caso, com projetos em Symfony e WordPress eu precisei fazer pequenas alterações nas configurações de ambos para usar https. Mas esta é uma questão de cada software.

Você também vai precisar normalmente adicionar uma exceção de segurança no seu navegador de internet.

E no meu caso aqui ficou faltando o css/js que, gerado pelo webpack devserver com localhost. Eu queria deixar tudo funcionando com https, então, vamos lá:

Https no webpack devserver

O webpack já vem praticamente pronto para ser usado. Existe uma opção do devserver para habilitar o https: https://webpack.js.org/configuration/dev-server/#devserverhttps

Sendo necessário, para funcionar, apenas configurar a opção dentro do webpack.config.js ou adicionando no comando que executa o devserver:

Eu aqui utilizo o Encore do Symfony encapsulando algumas configurações do webpack, mas a opção funciona diretamente no dev-server sem problemas.

Está resolvido? Não. não está.

Porque vamos também precisar adicionar uma exceção de segurança no domínio e porta que está sendo usado pelo webpack. Então, abra o navegador e digite o endereço que o web dev-server utiliza para gerar os arquivos. No meu exemplo:

https://0.0.0.0:9090/

Adicione a exceção de segurança e volte ao site principal. Agora sim, tudo deve funcionar.

=)

Precisando e alguma ajuda me procura no Twitter.