Configuração essencial de TLS/HTTPS no Apache com mod_ssl

Capítulo 9

Tempo estimado de leitura: 8 minutos

+ Exercício

O que é TLS/HTTPS no Apache (e o papel do mod_ssl)

HTTPS é HTTP “por dentro” de uma conexão criptografada via TLS. Na prática, o navegador (ou o curl) negocia uma sessão segura com o servidor antes de trafegar requisições HTTP. Isso protege contra interceptação e adulteração do tráfego e permite autenticar o servidor por meio de um certificado.

No Apache, o suporte a TLS normalmente é fornecido pelo módulo mod_ssl. Ele habilita o Apache a escutar em 443/tcp e a servir Virtual Hosts com diretivas como SSLEngine, SSLCertificateFile e SSLCertificateKeyFile.

Passo a passo: habilitar HTTPS em um Virtual Host

1) Habilitar o módulo SSL e o listener em 443

Em distribuições baseadas em Debian/Ubuntu, o fluxo mais comum é habilitar o módulo e o site SSL padrão (se aplicável) e garantir que o Apache esteja escutando em 443:

sudo a2enmod ssl

Verifique se existe um arquivo de portas com a linha de escuta em 443 (o nome pode variar conforme a distro). O essencial é haver:

Listen 443

Recarregue o Apache para aplicar:

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

sudo apachectl configtest && sudo systemctl reload apache2

Em RHEL/CentOS/Rocky/Alma, o módulo costuma vir como pacote separado (mod_ssl) e a configuração padrão já inclui o listener. O ponto-chave é: o Apache precisa ter o módulo SSL carregado e estar escutando em 443.

2) Criar um certificado autoassinado (laboratório)

Para laboratório/testes internos, um certificado autoassinado é suficiente. Ele não será “confiável” para navegadores por padrão, mas permite validar a configuração TLS.

Crie um diretório para armazenar chave/cert (ajuste conforme seu padrão):

sudo install -d -m 0755 /etc/apache2/ssl

Gere chave privada e certificado autoassinado (válido por 365 dias). Substitua o CN pelo nome que você usará para acessar (ex.: site1.local ou um FQDN real):

sudo openssl req -x509 -nodes -newkey rsa:2048 -days 365 \
  -keyout /etc/apache2/ssl/site1.key \
  -out /etc/apache2/ssl/site1.crt \
  -subj "/C=BR/ST=SP/L=SaoPaulo/O=Lab/OU=Apache/CN=site1.local"

Ajuste permissões: a chave privada deve ser legível apenas por root (o Apache lê a chave ao iniciar/recarregar como root e depois faz drop de privilégios):

sudo chmod 600 /etc/apache2/ssl/site1.key
sudo chmod 644 /etc/apache2/ssl/site1.crt

Se você quiser evitar alerta de “nome não corresponde”, inclua Subject Alternative Name (SAN). Um jeito simples é usar um arquivo de configuração do OpenSSL. Exemplo (crie /tmp/site1-openssl.cnf):

[req]
distinguished_name=req_distinguished_name
x509_extensions=v3_req
prompt=no

[req_distinguished_name]
C=BR
ST=SP
L=SaoPaulo
O=Lab
OU=Apache
CN=site1.local

[v3_req]
subjectAltName=@alt_names

[alt_names]
DNS.1=site1.local
DNS.2=www.site1.local

Gere novamente usando esse arquivo:

sudo openssl req -x509 -nodes -newkey rsa:2048 -days 365 \
  -keyout /etc/apache2/ssl/site1.key \
  -out /etc/apache2/ssl/site1.crt \
  -config /tmp/site1-openssl.cnf

3) Criar/ajustar o Virtual Host em 443 com mod_ssl

Agora crie um vhost SSL (arquivo e caminho variam por distro). O essencial é que exista um bloco <VirtualHost *:443> com TLS habilitado e apontando para o certificado e a chave.

<VirtualHost *:443>
  ServerName site1.local
  # (Opcional) ServerAlias www.site1.local

  DocumentRoot /var/www/site1/public

  SSLEngine on
  SSLCertificateFile /etc/apache2/ssl/site1.crt
  SSLCertificateKeyFile /etc/apache2/ssl/site1.key

  # Boas práticas básicas (ajuste conforme sua política/compatibilidade)
  SSLProtocol -all +TLSv1.2 +TLSv1.3

  # Ciphers: em TLS 1.3 a seleção é diferente e geralmente não depende desta lista.
  # Para TLS 1.2, use um conjunto moderno e evite suites fracas.
  SSLCipherSuite HIGH:!aNULL:!MD5:!3DES:!RC4
  SSLHonorCipherOrder on

  # (Opcional) Ajuda a depurar qual vhost respondeu
  Header always set X-Served-By "site1-https"

  ErrorLog ${APACHE_LOG_DIR}/site1-ssl-error.log
  CustomLog ${APACHE_LOG_DIR}/site1-ssl-access.log combined
</VirtualHost>

Observações importantes:

  • SSLEngine on ativa TLS naquele vhost.
  • SSLCertificateFile aponta para o certificado (público).
  • SSLCertificateKeyFile aponta para a chave privada correspondente.
  • SSLProtocol aqui desabilita protocolos legados e habilita apenas TLS 1.2 e 1.3 (boa linha de base). Se você precisa suportar clientes muito antigos, isso pode exigir ajustes — mas evite TLS 1.0/1.1 quando possível.

Se você usar diretivas de Header (como no exemplo), garanta que o módulo de headers esteja habilitado:

sudo a2enmod headers

Ative o site (Debian/Ubuntu) e recarregue:

sudo a2ensite site1-ssl
sudo apachectl configtest && sudo systemctl reload apache2

Checagens de segurança iniciais

1) Redirecionar HTTP → HTTPS

Uma prática inicial importante é garantir que quem acessar em HTTP seja redirecionado para HTTPS. Faça isso no vhost de porta 80 do mesmo site (não no de 443).

<VirtualHost *:80>
  ServerName site1.local
  # (Opcional) ServerAlias www.site1.local

  # Redireciona tudo para HTTPS
  Redirect permanent / https://site1.local/

  ErrorLog ${APACHE_LOG_DIR}/site1-error.log
  CustomLog ${APACHE_LOG_DIR}/site1-access.log combined
</VirtualHost>

Alternativa mais flexível (preserva host e URI) usando mod_rewrite:

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Se usar rewrite, habilite o módulo:

sudo a2enmod rewrite

2) Evitar protocolos legados (quando aplicável)

Em nível básico, a linha abaixo já cobre a maior parte dos cenários modernos:

SSLProtocol -all +TLSv1.2 +TLSv1.3

Se você estiver em um ambiente com OpenSSL/Apache mais antigos que não suportam TLS 1.3, mantenha pelo menos TLS 1.2:

SSLProtocol -all +TLSv1.2

Evite reabilitar TLS 1.0/1.1 a menos que exista uma exigência real e temporária, pois reduz a segurança e pode causar alertas em scanners e navegadores.

Como validar a configuração (navegador e curl)

1) Validar no navegador

Acesse https://site1.local. Com certificado autoassinado, o navegador exibirá um aviso de segurança. Para laboratório, você pode prosseguir e então checar:

  • Se o cadeado aparece (após aceitar a exceção).
  • Se o certificado exibido corresponde ao CN/SAN esperado.
  • Se o redirecionamento de http://site1.local para HTTPS ocorre.

2) Validar com curl (incluindo certificado autoassinado)

Verifique o redirecionamento HTTP → HTTPS:

curl -I http://site1.local

Você deve ver um 301/302 com Location: https://....

Verifique a resposta em HTTPS. Como é autoassinado, use -k (inseguro, apenas para laboratório) para ignorar validação:

curl -k -I https://site1.local

Se você adicionou o header de depuração, confirme qual vhost respondeu:

curl -k -I https://site1.local | grep -i x-served-by

Para inspecionar o handshake e o certificado apresentado:

openssl s_client -connect site1.local:443 -servername site1.local -showcerts

Procure por:

  • Protocol : TLSv1.2 ou TLSv1.3
  • Cipher : com uma suite moderna
  • O certificado exibido e o subject/issuer

Como confirmar qual Virtual Host está atendendo na porta 443

1) Conferir o mapeamento de vhosts carregados

Use o comando do Apache que lista os vhosts e suas portas. Ele ajuda a identificar qual arquivo define o vhost em *:443 e qual é o “default” para aquela porta:

sudo apachectl -S

Na saída, observe as entradas relacionadas a *:443. O Apache escolhe o vhost por SNI (nome do host no TLS) quando há múltiplos vhosts em 443. Se o cliente não enviar SNI (raro hoje), o primeiro vhost definido para 443 tende a virar o default.

2) Testar SNI explicitamente (quando há múltiplos sites em 443)

Se você tem mais de um vhost SSL, valide qual certificado/vhost é servido para cada nome usando -servername:

openssl s_client -connect 127.0.0.1:443 -servername site1.local | openssl x509 -noout -subject -issuer

Repita para outro hostname e compare o subject. Isso confirma se o SNI está direcionando para o vhost correto.

3) Confirmar via header de identificação (técnica de laboratório)

Durante configuração, é comum inserir temporariamente um header diferente em cada vhost SSL para confirmar roteamento:

Header always set X-VHost "site1-443"

Então:

curl -k -I https://site1.local | grep -i x-vhost

Remova esse header quando terminar a validação para não expor detalhes desnecessários.

Checklist rápido de troubleshooting (quando não abre HTTPS)

SintomaVerificação objetivaAção típica
Conexão recusada em 443ss -lntp | grep :443Garantir Listen 443, módulo SSL habilitado e serviço ativo
Erro ao recarregar Apacheapachectl configtest e journalctl -u apache2/httpdCorrigir caminho/permissões de .key/.crt e sintaxe do vhost
Certificado “não corresponde ao nome”Ver SAN/CN no certificadoGerar certificado com SAN correto para o hostname usado
Vhost errado em 443apachectl -S e teste com openssl s_client -servernameAjustar ordem/definições e garantir ServerName correto em cada vhost

Agora responda o exercício sobre o conteúdo:

Ao configurar HTTPS no Apache, qual combinação descreve corretamente o que é necessário para um Virtual Host funcionar em 443 com TLS?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

Para servir HTTPS, o Apache precisa ter suporte a SSL carregado e escutar em 443. No vhost *:443, SSLEngine on ativa TLS e as diretivas de certificado/chave informam quais arquivos usar.

Próximo capitúlo

Integração com PHP no Apache: visão geral com PHP-FPM e mod_php

Arrow Right Icon
Capa do Ebook gratuito Apache para Iniciantes: Configuração Essencial, Virtual Hosts e Segurança Básica
56%

Apache para Iniciantes: Configuração Essencial, Virtual Hosts e Segurança Básica

Novo curso

16 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.