# Configurar corretamente o TLS e o HTTPS

> Configuração TLS para servidores web segundo a BSI TR-02102 e o TLSRef: protocolos, cipher suites, certificados e verificação para Nginx, Apache e PHP.

Fonte: https://phpsos.de/pt/blog/tls-https-richtig-konfigurieren/  
Atualizado em: 25/10/2026  
Prestador: PHP SOS, Assistência de emergência PHP e segurança de servidores. Ajuda imediata por WhatsApp: https://wa.me/491736494914?text=Ol%C3%A1%2C%20PHP%20SOS%2C%20precisamos%20de%20ajuda%20com%20o%20nosso%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**Em resumo:** Uma configuração TLS sólida para servidores web oferece apenas TLS 1.2 e TLS 1.3, usa cipher suites com forward secrecy e cifragem autenticada (AES-GCM, ChaCha20-Poly1305) e um certificado com chave ECDSA ou RSA suficientemente longa, que se renova automaticamente. Servem de orientação a diretiva TR-02102-2 do BSI (Gabinete Federal Alemão para a Segurança da Informação) e as recomendações Server-Side TLS do TLSRef. Verifique o resultado a partir do exterior e não se esqueça das ligações que o próprio PHP estabelece.

## Porque é que as definições TLS antigas sobrevivem tanto tempo

O cadeado no navegador está lá, portanto a cifragem é dada como resolvida. É assim que pensam muitos operadores, e é por isso que a configuração TLS permanece muitas vezes inalterada durante anos. Vem então da altura em que o servidor foi montado, de um modelo copiado ou dos valores por defeito de um painel.

O problema: as recomendações mudam. As versões de protocolo são substituídas, certos procedimentos passam a ser considerados fracos, surgem novos métodos de troca de chaves. O BSI publicou a TR-02102 mais recentemente na versão 2026-01, de 27.01.2026, e aí já remete para procedimentos híbridos pós-quânticos para o TLS 1.3. Quem não olha para as suas definições há anos está, com grande probabilidade, desatualizado.

Quem, de qualquer modo, está agora a verificar servidores por causa do PHP2Shell pode ver a configuração TLS de uma só vez. Não fecha a vulnerabilidade PHP, mas faz parte de qualquer reforço de segurança bem feito.

## Em que se baseia uma boa configuração TLS para servidores web

Duas fontes são particularmente úteis para operadores na Alemanha. A **BSI TR-02102** avalia procedimentos criptográficos; a parte 2 trata do TLS. Dirige-se sobretudo a programadores e planeadores e, para autoridades e áreas reguladas, é muitas vezes a referência. As **recomendações Server-Side TLS**, antes mantidas na wiki da Mozilla, continuam hoje no TLSRef e fornecem perfis concretos e copiáveis.

O TLSRef distingue, na versão 6.0, dois perfis:

| Característica | Intermediate (para a maioria dos sites) | Modern |
|---|---|---|
| Protocolos | TLS 1.2 e TLS 1.3 | apenas TLS 1.3 |
| Cipher suites TLS 1.2 | ECDHE com AES-GCM ou ChaCha20-Poly1305 | nenhuma |
| Grupos de troca de chaves | X25519MLKEM768, X25519, prime256v1, secp384r1 | como o Intermediate |
| Certificado | ECDSA P-256 recomendado ou RSA de 2048 bits | ECDSA P-256 |
| Validade do certificado | 90 dias recomendados, no máximo 366 dias | 90 dias |
| HSTS max-age | dois anos | dois anos |

Para sites públicos, o Intermediate é o ponto de partida habitual. O perfil exclui equipamentos muito antigos, mas cobre os navegadores e sistemas operativos atuais. O grupo híbrido X25519MLKEM768 exige uma biblioteca TLS atual. Verifique se a sua versão do OpenSSL o conhece antes de o registar.

## Nginx e Apache: um ponto de partida seguro

Os exemplos seguintes implementam o perfil Intermediate. Os caminhos são marcadores de posição, a lista de cipher suites aplica-se ao TLS 1.2; o TLS 1.3 traz os seus próprios procedimentos padrão seguros.

```nginx
server {
    listen 443 ssl;
    server_name www.example.de;

    ssl_certificate     /etc/ssl/example/fullchain.pem;
    ssl_certificate_key /etc/ssl/example/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;
}

server {
    listen 80;
    server_name www.example.de;
    return 301 https://$host$request_uri;
}
```

```apache
SSLProtocol             -all +TLSv1.2 +TLSv1.3
SSLCipherSuite          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
SSLHonorCipherOrder     off
```

O segundo bloco `server` redireciona de forma permanente os acessos não cifrados para HTTPS. O redirecionamento deve apontar diretamente para o endereço final e não passar por várias etapas intermédias. Verifique depois também os recursos incorporados: imagens, scripts ou tipos de letra que ainda sejam carregados por HTTP provocam avisos no navegador ou são bloqueados.

A definição em que o cliente escolhe a ordem corresponde à recomendação do TLSRef: todos os procedimentos oferecidos são considerados seguros e, assim, os equipamentos sem aceleração AES podem preferir o ChaCha20. Após cada alteração, teste a configuração (`nginx -t` ou `apachectl configtest`) e recarregue o serviço. O cabeçalho HSTS adequado e outras indicações para o navegador são descritos no guia [Security headers para sites](https://phpsos.de/pt/ratgeber/sicherheits-header/).

> **Dica:**
> Painéis como o Plesk ou o cPanel substituem muitas vezes as alterações próprias em ficheiros gerados. Defina aí as indicações de TLS através das definições ou dos modelos previstos pelo painel.

## Certificados: chave, cadeia, renovação

Grande parte dos problemas de TLS na prática nada tem a ver com cipher suites, mas com certificados. Erros típicos são uma cadeia incompleta, em que falta o certificado intermédio, certificados expirados em domínios secundários e chaves privadas com permissões de ficheiro demasiado abertas.

Três regras ajudam:

1. **Renovar automaticamente** e monitorizar a renovação. Validades curtas, como as que o TLSRef recomenda, só são praticáveis com automatização.
2. **Proteger as chaves privadas:** legíveis apenas para o root e o processo do servidor web, nunca no webroot, nunca num repositório.
3. **Registar todos os nomes:** domínio principal, www, subdomínios para loja, staging, interface web de correio e painéis.

Quem usa certificados em vários locais, por exemplo em CDN, balanceador de carga e servidor de origem, deve manter uma visão geral: que certificado está instalado onde, quem o renova e quando expira. Sem essa visão geral, um certificado expirado só é detetado, muitas vezes, quando os clientes se queixam.

## Como verificar a sua configuração a partir do exterior

Os comandos seguintes são simples verificações e não alteram nada. Substitua o nome do anfitrião pelo seu:

```bash
# TLS 1.3 e TLS 1.2 devem funcionar
openssl s_client -connect www.example.de:443 -servername www.example.de -tls1_3 </dev/null
openssl s_client -connect www.example.de:443 -servername www.example.de -tls1_2 </dev/null
# O TLS 1.1 deve falhar
openssl s_client -connect www.example.de:443 -servername www.example.de -tls1_1 </dev/null
# Validade e titular do certificado fornecido
openssl s_client -connect www.example.de:443 -servername www.example.de </dev/null 2>/dev/null | openssl x509 -noout -subject -dates
```

Uma falha no teste do TLS 1.1 pode dever-se também ao facto de a sua versão local do OpenSSL já nem sequer oferecer o protocolo antigo. Para um relatório completo sobre todos os procedimentos oferecidos, serve um scanner TLS especializado. Verifique cada subdomínio individualmente, pois muitas vezes correm com definições próprias.

## O que se esquece: TLS onde o próprio PHP é cliente

As aplicações PHP estabelecem muitas ligações por si próprias: a prestadores de pagamento, transportadoras, interfaces, servidores de correio e bases de dados. Aqui, o erro mais frequente não é uma definição fraca, mas uma verificação do certificado desligada, muitas vezes como solução rápida para um problema no desenvolvimento.

```php
<?php
// Seguro: certificado e nome do anfitrião são verificados (manter o comportamento por defeito)
$ch = curl_init('https://api.partner.example/v1/status');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_TIMEOUT        => 10,
]);
$antwort = curl_exec($ch);
```

Procure no código `CURLOPT_SSL_VERIFYPEER` com `false` e `verify_peer` em contextos de stream. Cada ocorrência anula, na prática, a proteção do TLS para essa ligação. Onde os serviços estão atrás de uma CDN, também o troço entre a CDN e o servidor de origem deve usar um certificado válido e verificado. Mais definições do servidor web para ambientes PHP encontra em [Configurar o Nginx para PHP com segurança](https://phpsos.de/pt/blog/nginx-fuer-php-absichern/), e referências para todo o reforço de segurança em [CIS-Benchmarks e módulos do BSI para servidores web](https://phpsos.de/pt/blog/cis-benchmarks-bsi-bausteine/).

## Como ajuda concretamente a PHP SOS?

- Registamos todos os nomes de anfitrião e serviços com TLS, incluindo painéis, staging e interfaces web de correio.
- Comparamos as definições com a TR-02102 e o perfil TLSRef adequado e documentamos os desvios deliberados.
- Passamos os certificados para renovação automática com monitorização.
- Procuramos no código da aplicação verificações de certificado desligadas e mostramos a correção.

O TLS é um módulo do nosso [reforço de segurança de servidores para servidores web PHP](https://phpsos.de/pt/leistungen/server-haertung/); a relação com a situação atual é explicada em [O que é o PHP2Shell?](https://phpsos.de/pt/php2shell/was-ist-php2shell/).


## Perguntas frequentes

**Ainda tenho de oferecer TLS 1.0 e TLS 1.1?**  
Em regra, não. As recomendações atuais, como o perfil Intermediate do TLSRef, fixam o TLS 1.2 como limite inferior. Quem precisa de protocolos mais antigos para equipamentos legados deve decidi-lo de forma consciente, documentá-lo e limitá-lo a um serviço separado.

**Um certificado gratuito é menos seguro do que um comprado?**  
Para a cifragem, não faz diferença. O que conta são o tipo e o comprimento da chave, uma cadeia de certificados completa e uma renovação automática fiável. As diferenças estão no âmbito da verificação, na validade e no serviço do fornecedor.

**Basta o HTTPS entre o visitante e a CDN?**  
Não. Também a ligação entre a CDN e o servidor de origem deve ser cifrada e verificar o certificado da origem. Caso contrário, os dados circulam na rede sem cifragem ou sem verificação no segundo troço.

**O que tem o TLS a ver com o PHP2Shell?**  
Diretamente, nada. O TLS protege os dados no caminho de transporte, o PHP2Shell afeta o interpretador PHP no servidor. Uma ligação cifrada transporta também pedidos de ataque de forma fiável, por isso a atualização do PHP continua a ser obrigatória, independentemente disso.

## Fontes

- [BSI TR-02102: procedimentos criptográficos, parte 2 TLS](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/Technische-Richtlinien/TR-nach-Thema-sortiert/tr02102/tr-02102.html)
- [TLSRef: Server-Side TLS Guidelines](https://docs.tlsref.org/)
- [Documentação do Nginx](https://nginx.org/en/docs/)
- [Apache HTTP Server: documentação](https://httpd.apache.org/docs/)
