Como Activar Certificado Self-Signed no Apache para HTTPS no Linux

O site está a correr em HTTP simples e os browsers mostram “Não seguro” na barra de endereço. Não há orçamento para um certificado comercial, ou o servidor está numa rede interna que não é acessível da internet (pelo que Let’s Encrypt não funciona via validação HTTP-01). A solução é gerar um certificado self-signed com OpenSSL e configurar o Apache para servir HTTPS. O browser vai mostrar um aviso de segurança — esperado para certificados auto-assinados — mas a ligação fica encriptada e funcional. Este guia cobre a geração do certificado, a configuração do mod_ssl no Apache e o redireccionamento automático de HTTP para HTTPS.

Um certificado self-signed é adequado para ambientes de desenvolvimento, redes internas, painéis de administração e testes. Para sites públicos, deve usar-se Let’s Encrypt (gratuito) ou um certificado comercial — o aviso do browser num site público degrada a confiança do utilizador (Apache — SSL/TLS How-To).

⚠ **Atenção

Um certificado self-signed não é trusted** por nenhum browser por defeito. Os utilizadores verão um aviso “A ligação não é segura” ou “NET::ERR_CERT_AUTHORITY_INVALID”. Isto é normal e esperado — o utilizador tem de aceitar manualmente o risco para continuar. Para evitar este aviso, ver secção 8 (Alternativas).

1. O que Está a Acontecer — Como o HTTPS Funciona no Apache

O HTTPS (HTTP sobre TLS) encripta a comunicação entre o browser e o servidor. O Apache não faz encriptação nativamente — precisa do módulo mod_ssl, que é uma extensão que implementa TLS usando a biblioteca OpenSSL (Apache — mod_ssl).

O fluxo de HTTPS tem três componentes:

Componente O que é Ficheiro típico
Certificado Ficheiro público que identifica o servidor, assinado por uma CA (ou auto-assinado) server.crt
Chave privada Chave criptográfica que prova que o servidor é o dono do certificado server.key
mod_ssl Módulo Apache que usa o certificado + chave para negociar TLS com o cliente mod_ssl.so

Num certificado self-signed, o servidor assina o seu próprio certificado em vez de usar uma CA externa (DigiCert, Let’s Encrypt, etc.). Isto significa que o certificado é tecnicamente válido — a encriptação funciona — mas não há uma entidade externa a confirmar a identidade do servidor, pelo que os browsers mostram um aviso (Apache — SSL/TLS Introduction).

2. Cenários em que Este Artigo Se Aplica

Este guia aplica-se a:

  • Servidores web internos (intranet, painéis de administração) que não são acessíveis da internet
  • Ambientes de desenvolvimento e staging que precisam de HTTPS para testar funcionalidades
  • Servidores em redes isoladas (air-gapped) onde Let’s Encrypt não funciona
  • Qualquer servidor Apache HTTP Server 2.4 em Linux (Debian/Ubuntu, RHEL/CentOS/Fedora, Arch)

Não se aplica a:

  • Sites públicos acessíveis da internet — usar Let’s Encrypt (gratuito, automático, sem avisos do browser)
  • Apache Tomcat (servidor de aplicações Java) — o processo é diferente (JKS keystore em vez de ficheiros .crt/.key)
  • Nginx — embora o conceito seja o mesmo, a configuração é diferente

3. Passo 1 — Instalar o mod_ssl no Apache

O módulo mod_ssl não vem activado por defeito na maioria das distribuições Linux. Antes de o activar, confirma que o Apache está instalado e a correr.

3.1 Debian/Ubuntu

sudo apt update
sudo apt install apache2 ssl-cert
sudo a2enmod ssl
sudo systemctl restart apache2

O pacote ssl-cert em Debian/Ubuntu inclui um certificado self-signed pré-gerado em /etc/ssl/certs/ssl-cert-snakeoil.pem e a chave em /etc/ssl/private/ssl-cert-snakeoil.key. Este certificado pode ser usado para testes rápidos, mas não tem o nome do servidor correcto — melhor gerar um novo (Passo 2).

3.2 RHEL/CentOS/Fedora/Alma/Rocky

sudo dnf install httpd mod_ssl
sudo systemctl enable –now httpd

No RHEL/CentOS, o mod_ssl instala um ficheiro de configuração default em /etc/httpd/conf.d/ssl.conf que já tem um VirtualHost HTTPS na porta 443 com um certificado de teste. Vamos substituir esse certificado no Passo 2.

3.3 Arch Linux

sudo pacman -S apache
# mod_ssl já vem compilado no pacote apache do Arch
sudo systemctl restart httpd

No Arch, o mod_ssl está incluído no pacote apache por defeito — não precisa de ser activado separadamente. Mas precisa de ser carregado no httpd.conf (ver Passo 4).

3.4 Verificar que o mod_ssl está carregado

Depois de instalar, verifica que o módulo está activo:

# Debian/Ubuntu
apache2ctl -M | grep ssl# RHEL/CentOS
httpd -M | grep ssl

# Arch
httpd -M | grep ssl

O output deve mostrar ssl_module (shared). Se não aparecer, o módulo não foi activado correctamente.

4. Passo 2 — Gerar o Certificado Self-Signed com OpenSSL

O OpenSSL é a ferramenta canónica para gerar certificados. O processo cria dois ficheiros: a chave privada (que deve ser protegida) e o certificado público (que pode ser distribuído).

4.1 Gerar chave RSA + certificado num único comando

A forma mais rápida de gerar um certificado self-signed é usar um único comando openssl req que cria a chave e o certificado ao mesmo tempo:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/apache-selfsigned.key \
-out /etc/ssl/certs/apache-selfsigned.crt \
-subj “/C=PT/ST=Lisboa/L=Lisboa/O=Minha Empresa/CN=meuservidor.local”

Explicação de cada parâmetro:

Parâmetro O que faz
-x509 Gera um certificado auto-assinado em vez de um pedido de assinatura (CSR)
-nodes Não encripta a chave privada com passphrase — o Apache precisa de a ler sem intervenção
-days 365 O certificado é válido por 365 dias (1 ano)
-newkey rsa:2048 Cria uma nova chave RSA de 2048 bits
-keyout Caminho onde a chave privada é guardada
-out Caminho onde o certificado é guardado
-subj Informação do titular do certificado (Country/State/Locality/Organization/Common Name)

O CN (Common Name) deve corresponder ao nome do servidor que os clientes vão usar para aceder. Se o servidor é acedido como meuservidor.local, o CN deve ser meuservidor.local. Se houver um mismatch, o browser mostra um erro adicional “O certificado não é válido para este domínio”.

4.2 Gerar com SAN (Subject Alternative Names)

Os browsers modernos (Chrome, Firefox, Edge) ignoram o CN e usam SAN (Subject Alternative Names) para validar o certificado. Se precisares que o certificado cubra múltiplos nomes (ex: meuservidor.local e 192.168.1.100), gera com SAN:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/apache-selfsigned.key \
-out /etc/ssl/certs/apache-selfsigned.crt \
-subj “/C=PT/ST=Lisboa/L=Lisboa/O=Minha Empresa/CN=meuservidor.local” \
-addext “subjectAltName=DNS:meuservidor.local,DNS:meuservidor,IP:192.168.1.100”

O parâmetro -addext adiciona extensões X.509 ao certificado. DNS: cobre nomes de domínio, IP: cobre endereços IP. Podes listar múltiplos nomes separados por vírgulas.

4.3 Proteger as permissões da chave privada

A chave privada deve ser legível apenas pelo root (ou pelo utilizador que corre o Apache):

sudo chmod 600 /etc/ssl/private/apache-selfsigned.key
sudo chmod 644 /etc/ssl/certs/apache-selfsigned.crt

⚠ **Atenção

** Se a chave privada for legível por outros utilizadores do sistema, qualquer pessoa com acesso ao servidor pode decifrar o tráfego HTTPS. A permissão 600 (apenas root) é obrigatória.

4.4 Verificar o certificado gerado

Para confirmar que o certificado tem os valores correctos:

openssl x509 -in /etc/ssl/certs/apache-selfsigned.crt -text -noout | head -20

O output mostra o issuer (deve ser igual ao subject — auto-assinado), a validade e os SANs.

5. Passo 3 — Configurar o VirtualHost HTTPS no Apache

Com o certificado gerado, configura o Apache para o usar. A configuração varia consoante a distribuição.

5.1 Debian/Ubuntu — VirtualHost em /etc/apache2/sites-available/

Cria um ficheiro de configuração para o VirtualHost HTTPS:

sudo tee /etc/apache2/sites-available/default-ssl.conf > /dev/null << ‘EOF’

ServerName meuservidor.local
DocumentRoot /var/www/htmlSSLEngine on
SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key

Options Indexes FollowSymLinks
AllowOverride All
Require all granted

EOF

Depois activa o site e reinicia o Apache:

sudo a2ensite default-ssl
sudo systemctl reload apache2

5.2 RHEL/CentOS — Editar /etc/httpd/conf.d/ssl.conf

No RHEL/CentOS, o mod_ssl já instala um ficheiro de configuração. Edita-o para apontar para o novo certificado:

sudo sed -i ‘s|^SSLCertificateFile.*|SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt|’ /etc/httpd/conf.d/ssl.conf
sudo sed -i ‘s|^SSLCertificateKeyFile.*|SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key|’ /etc/httpd/conf.d/ssl.conf
sudo systemctl restart httpd

5.3 Arch Linux — Editar /etc/httpd/conf/httpd.conf

No Arch, garante que o mod_ssl está carregado e configura o VirtualHost:

# Garantir que mod_ssl está carregado (descomentar a linha se necessário)
sudo sed -i ‘s|^#LoadModule ssl_module|LoadModule ssl_module|’ /etc/httpd/conf/httpd.conf# Adicionar VirtualHost HTTPS no fim do httpd.conf
sudo tee -a /etc/httpd/conf/httpd.conf > /dev/null << ‘EOF’ Listen 443
ServerName meuservidor.local
DocumentRoot /srv/http

SSLEngine on
SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key

EOF

sudo systemctl restart httpd

5.4 Verificar a configuração antes de reiniciar

Antes de reiniciar o Apache, valida a configuração:

# Debian/Ubuntu
apache2ctl configtest# RHEL/CentOS/Arch
httpd -t

O output deve ser Syntax OK. Se houver erros, o Apache indica o ficheiro e a linha do problema.

6. Passo 4 — Activar Cifras Fortes e Protocolos Modernos

Por defeito, o Apache pode aceitar protocolos TLS antigos (TLS 1.0, TLS 1.1) que são considerados inseguros. Configura o mod_ssl para aceitar apenas TLS 1.2 e 1.3, com cifras fortes.

Adiciona as seguintes directivas dentro do VirtualHost HTTPS (ou na configuração global do mod_ssl):

SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off

Explicação:

Directiva O que faz
SSLProtocol -all +TLSv1.2 +TLSv1.3 Apenas TLS 1.2 e 1.3 — desactiva TLS 1.0/1.1 e SSLv2/v3
SSLCipherSuite Lista de cifras aceites — apenas cifras com forward secrecy (ECDHE) e AEAD (GCM, CHACHA20)
SSLHonorCipherOrder on O servidor escolhe a cifra preferida em vez de deixar o cliente escolher
SSLCompression off Desactiva compressão TLS — previne ataque CRIME
SSLSessionTickets off Desactiva session tickets — simplifica configuração em ambientes com múltiplos workers

Depois de adicionar, valida e reinicia:

apache2ctl configtest && sudo systemctl reload apache2
# ou em RHEL: httpd -t && sudo systemctl reload httpd

7. Passo 5 — Redireccionar HTTP para HTTPS Automaticamente

Para garantir que todos os utilizadores acedem via HTTPS, configura um redireccionamento do porto 80 (HTTP) para o porto 443 (HTTPS).

7.1 Via VirtualHost (recomendado)

Adiciona um VirtualHost na porta 80 que redirecciona tudo para HTTPS:

ServerName meuservidor.local
Redirect permanent / https://meuservidor.local/

Em Debian/Ubuntu, coloca isto num ficheiro separado (ex: /etc/apache2/sites-available/meuservidor.conf) e activa com a2ensite. Em RHEL/Arch, adiciona ao httpd.conf ou a um ficheiro em conf.d/.

7.2 Via .htaccess (alternativa)

Se não tiveres acesso à configuração do Apache, usa .htaccess no directório raiz do site:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

O mod_rewrite precisa de estar activado: sudo a2enmod rewrite (Debian/Ubuntu).

7.3 Verificar o redireccionamento

Depois de configurar, testa com curl:

curl -I http://meuservidor.local

O output deve mostrar 301 Moved Permanently com Location: https://meuservidor.local/.

Para mais detalhes sobre redireccionamento HTTP→HTTPS, ver o artigo Redireccionar HTTP para HTTPS Automaticamente no kbase.pt.

8. Passo 6 — Verificar e Testar a Configuração Completa

Depois de todos os passos, valida que o HTTPS está funcional.

8.1 Testar a ligação HTTPS com curl

# Testar HTTPS (ignorando o aviso de certificado self-signed)
curl -k https://meuservidor.local# Ver os detalhes do certificado
openssl s_client -connect meuservidor.local:443 -servername meuservidor.local < /dev/null 2>/dev/null | openssl x509 -text -noout | head -20

O parâmetro -k do curl ignora a verificação do certificado (necessário para self-signed). Sem -k, o curl rejeita a ligação com erro de CA desconhecida.

8.2 Testar a versão TLS negociada

Para confirmar que apenas TLS 1.2/1.3 é aceite:

# Testar TLS 1.2 (deve funcionar)
openssl s_client -connect meuservidor.local:443 -tls1_2 < /dev/null 2>/dev/null | grep “Protocol”# Testar TLS 1.1 (deve falhar)
openssl s_client -connect meuservidor.local:443 -tls1_1 < /dev/null 2>/dev/null | grep “Protocol”

O primeiro comando deve mostrar Protocol : TLSv1.2. O segundo deve falhar com erro ou mostrar no protocols available.

8.3 Verificar com um browser

Abre o browser em https://meuservidor.local. O browser mostra um aviso de segurança — clica em “Avançado” → “Continuar para meuservidor.local (não seguro)”. A página deve carregar com HTTPS activo (cadeado na barra de endereço, embora com aviso).

8.4 Tabela de Diagnóstico

Sintoma Causa Solução
curl: (7) Failed to connect — porta 443 Firewall a bloquear ou Apache não está a escutar 443 Verificar com ss -tlnp (procurar porta 443); se vazio, verificar Listen 443 no httpd.conf
curl: (60) SSL certificate problem Certificado self-signed não confiável Usar -k no curl ou importar certificado no browser/cliente
AH02572: Failed to configure at least one certificate Caminho do certificado ou chave errado Verificar SSLCertificateFile e SSLCertificateKeyFile — caminhos absolutos
ssl: SSL Library Error: error:0B080074 Permissões da chave privada chmod 600 /etc/ssl/private/apache-selfsigned.key e chown root:root
Página carrega em HTTP mas não em HTTPS mod_ssl não activado ou VirtualHost 443 em falta `apache2ctl -M grep ssl ou httpd -M grep ssl`
NET::ERR_CERT_COMMON_NAME_INVALID CN ou SAN não correspondem ao nome usado Regenerar certificado com CN/SAN correcto (ver Passo 2)

9. Outras Causas de Falhas de HTTPS no Apache

Nem todos os problemas de HTTPS vêm de configuração incorrecta. Outras causas:

  • Certificado expirado: Um certificado self-signed tem validade finita (365 dias no exemplo). Se expirar, o browser mostra NET::ERR_CERT_DATE_INVALID. Regenerar com -days 365 ou superior.
  • Chave privada e certificado não correspondem: Se a chave e o certificado foram gerados separadamente e não correspondem, o Apache regista SSL Library Error: error:0B080074. Verificar com openssl x509 -noout -modulus -in server.crt | openssl md5 e openssl rsa -noout -modulus -in server.key | openssl md5 — os hashes devem ser iguais.
  • SELinux a bloquear leitura da chave: No RHEL/CentOS com SELinux enforcing, o Apache pode não conseguir ler a chave privada. Corrigir com restorecon -Rv /etc/ssl/private/ ou colocar a chave em /etc/pki/tls/private/ (o path default do RHEL). Sintaxe validada contra documentação oficial — restorecon, Julho 2026.
  • Firewall (firewalld/ufw) a bloquear porta 443: Abrir a porta com firewall-cmd –add-service=https (RHEL) ou ufw allow 443/tcp (Ubuntu). Sintaxe validada contra documentação oficial — firewalld/ufw, Julho 2026.
  • Múltiplos VirtualHosts na mesma porta: Se há vários sites HTTPS na porta 443, é preciso SNI (Server Name Indication) — o Apache já suporta SNI por defeito em 2.4+, mas cada VirtualHost precisa do seu próprio ServerName. Documentado em (Apache — SSL/TLS How-To).
  • Browser faz cache do certificado antigo: Depois de regenerar o certificado, o browser pode manter o certificado antigo em cache. Limpar cache do browser ou testar em janela anónima.

10. Como Evitar Problemas no Futuro

Práticas para manter o HTTPS self-signed funcional:

  • Automatiza a renovação: Cria um cron job que regenera o certificado antes de expirar. Um certificado de 365 dias deve ser regenerado a cada 330 dias (margem de 35 dias).
  • Usa SAN em vez de apenas CN: Browsers modernos ignoram o CN e usam SAN. Sempre que possível, incluir -addext "subjectAltName=..." na geração.
  • Protege a chave privada: Permissões 600, owned por root. Nunca commitar a chave privada para git.
  • Documenta o certificado: Regista a data de criação, validade e nome do servidor. Um certificado esquecido que expira causa erros difíceis de diagnosticar.
  • Para sites públicos, usa Let’s Encrypt: Se o servidor é acessível da internet, Let’s Encrypt é gratuito, automático (via certbot) e não gera avisos no browser. Não há razão para usar self-signed em sites públicos.
  • Testa após mudanças: Depois de alterar a configuração do Apache, corre sempre apache2ctl configtest ou httpd -t antes de reiniciar. Um erro de sintaxe derruba o Apache.
  • Considera certificados de CA interna: Em ambientes empresariais, uma CA interna (ex: OpenSSL CA, Active Directory Certificate Services) permite gerar certificados confiáveis por todos os dispositivos do domínio sem avisos do browser.

Checklist Antes de Aplicar em Produção

Antes de aplicar qualquer comando deste artigo em ambiente produtivo, confirma:

  1. Apache instalado e a correr: systemctl status apache2 ou systemctl status httpd
  2. mod_ssl activo: apache2ctl -M | grep ssl ou httpd -M | grep ssl
  3. OpenSSL instalado (versão 3.0+): openssl version
  4. Porta 443 aberta no firewall: verificar com ss -tlnp que o Apache está a escutar 443, e regra de firewall activa
  5. Directório do site acessível: ls -la /var/www/html (Debian/Ubuntu) ou /srv/http (Arch) ou /var/www/html (RHEL)
  6. Backup da configuração actual: cp do ficheiro de configuração ssl (ex: default-ssl.conf) para .bak antes de editar (Debian) ou equivalente.

Artigos Relacionados