12k
All articles

Como Forçar HTTPS com .htaccess

Force HTTPS com .htaccess usando regras de reescrita do Apache, corrija loops atrás de CDN ou balanceadores e configure www e HSTS.

OpenReplay Team
OpenReplay Team
Como Forçar HTTPS com .htaccess

Para forçar HTTPS em todo o tráfego no Apache, adicione três linhas ao arquivo .htaccess na raiz do seu site: RewriteEngine On, RewriteCond %{HTTPS} off e RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301].

Se você já colou uma regra de redirecionamento encontrada em algum fórum e depois ficou assistindo o navegador entrar em loop até desistir, a regra em si provavelmente estava correta. O que geralmente quebra é o que está na frente do seu servidor.

Essa regra intercepta todas as requisições que chegam via HTTP simples e emite um redirecionamento permanente para a URL idêntica em HTTPS. Ela funciona no Apache com o mod_rewrite habilitado e um certificado SSL já instalado, e falha de maneiras específicas e previsíveis quando um CDN ou load balancer está na frente da sua origem. Este guia apresenta primeiro a regra pronta para uso, depois as variações por domínio, pasta e www, em seguida as correções para loops de redirecionamento e, por fim, o que fazer se você não estiver usando Apache.

Principais Conclusões

  • A regra canônica testa RewriteCond %{HTTPS} off e reescreve para https://%{HTTP_HOST}%{REQUEST_URI}, o que preserva o domínio e o caminho exatos solicitados pelo visitante em vez de fixar um único domínio no código.
  • R=301 emite um redirecionamento permanente e L interrompe o processamento de reescrita; durante os testes, use R (um 302 temporário) primeiro, pois os navegadores fazem cache de 301s de forma agressiva.
  • Forçar HTTPS só funciona se um certificado TLS/SSL válido já estiver instalado. Redirecionar sem um certificado torna o site inacessível, não seguro.
  • Atrás de um proxy que encerra TLS, %{HTTPS} nunca é on, então a regra entra em loop com ERR_TOO_MANY_REDIRECTS; teste %{HTTP:X-Forwarded-Proto} em vez disso.
  • Um loop de SSL Flexible do Cloudflare é uma má configuração do lado do Cloudflare, corrigida alterando o modo de criptografia, não editando o .htaccess.

Antes de começar: certificado SSL e mod_rewrite

Forçar HTTPS só funciona se um certificado TLS/SSL válido já estiver instalado no domínio. Redirecionar para HTTPS sem um certificado não torna o site seguro — torna-o inacessível, exibindo um aviso de segurança no navegador. (“Certificado SSL” é o termo comum na indústria; o protocolo em si é, na verdade, TLS.) Confirme que o certificado está ativo carregando https://seudominio.com diretamente no navegador e verificando o ícone de cadeado antes de modificar o .htaccess.

A regra abaixo depende do módulo mod_rewrite do Apache, que está habilitado por padrão na maioria das hospedagens compartilhadas e cPanel. O arquivo .htaccess fica na raiz do seu site, normalmente em public_html ou no document root do domínio. Edite-o pelo Gerenciador de Arquivos do cPanel (habilite “Mostrar Arquivos Ocultos” para ver dotfiles), via FTP ou por SSH. Faça backup do arquivo antes de editar para poder restaurá-lo caso alguma regra cause problemas.

A regra .htaccess para forçar HTTPS em todo o tráfego

Cole isso no arquivo .htaccess na raiz do seu site para redirecionar todas as requisições HTTP para HTTPS:

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

Linha por linha: RewriteEngine On ativa o mecanismo de reescrita. RewriteCond %{HTTPS} off dispara a regra somente quando a conexão ainda não está criptografada. RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} reconstrói a URL em HTTPS, e as variáveis %{HTTP_HOST} e %{REQUEST_URI} preservam o domínio e o caminho exatos solicitados pelo visitante, fazendo com que a regra funcione em múltiplos domínios sem forçar www silenciosamente.

Nas flags [L,R=301], R=301 emite um redirecionamento permanente e L interrompe o processamento de reescrita nessa regra. Durante os testes, use R sozinho (um 302 temporário) primeiro, pois os navegadores fazem cache de 301s de forma agressiva e desfazer um incorreto é trabalhoso; mude para R=301 somente após confirmar que o redirecionamento funciona corretamente.

Não repita RewriteEngine On. Se essa linha já existir no arquivo, adicione apenas o RewriteCond e o RewriteRule abaixo dela.

Variações: domínio específico, pasta e canonicalização de www

Para forçar HTTPS em apenas um domínio quando vários apontam para o mesmo document root, adicione uma condição em HTTP_HOST:

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

A flag NC torna a correspondência do host insensível a maiúsculas e minúsculas. Para combinar HTTPS com a canonicalização de www/sem www, o htaccessbook documenta como envolver ambos os redirecionamentos em um bloco de guarda do mod_rewrite:

<IfModule mod_rewrite.c>
	RewriteEngine On

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

	RewriteCond %{HTTP_HOST} !^www\. [NC]
	RewriteRule (.*) https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

A versão publicada desse bloco pressupõe que RewriteEngine On aparece antes no arquivo, por isso foi adicionado acima para que o trecho funcione de forma independente. A primeira regra move a requisição para HTTPS. A segunda adiciona www a um host que não o possui. Note que [L] encerra o processamento assim que uma regra corresponde, portanto uma requisição HTTP simples sem www gera dois redirecionamentos, não um: primeiro para HTTPS, depois para o host com www. Envolver as regras em <IfModule mod_rewrite.c> faz o site falhar de forma aberta (servindo via HTTP) em vez de gerar um erro 500 caso o mod_rewrite não esteja carregado.

Empilhar essas regras manualmente fica complicado quando você combina HTTPS, canonicalização de www, alguns redirecionamentos e um bloco de cache no mesmo arquivo — uma flag errada ou uma regra fora de ordem pode causar problemas em produção. O gerador de htaccess da OpenReplay monta o arquivo a partir de um conjunto de opções: forçar HTTPS, adicionar ou remover www, adicionar redirecionamentos 301 ou 302, ativar gzip e cache do navegador, bloquear IPs, mapear páginas de erro personalizadas. O resultado é comentado, atualiza conforme você altera as opções e roda inteiramente no navegador, então você pode copiá-lo ou baixá-lo e compará-lo com o que já tem.

Corrigindo ERR_TOO_MANY_REDIRECTS atrás de um CDN ou load balancer

Se o seu redirecionamento causar ERR_TOO_MANY_REDIRECTS, o navegador seguiu redirecionamentos demais e desistiu. A causa mais comum é um proxy ou load balancer que encerra TLS. O TLS termina no proxy, então %{HTTPS} nunca é on na origem, a regra dispara em todas as requisições e o loop nunca se encerra. A solução é confiar no esquema encaminhado:

<IfModule mod_rewrite.c>
	RewriteEngine On
	RewriteCond %{HTTP:X-Forwarded-Proto} !https
	RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

Aqui, RewriteCond %{HTTP:X-Forwarded-Proto} !https lê o cabeçalho X-Forwarded-Proto definido pelo proxy, fazendo a regra disparar somente quando a conexão original do visitante era HTTP. Teste com R antes de promover para R=301.

Um loop de SSL Flexible do Cloudflare é um problema diferente com uma solução diferente. Com a criptografia Flexible, o trecho entre o Cloudflare e o seu servidor não é criptografado, então uma regra na origem que insiste em HTTPS continua enviando a requisição de volta em loop. O Cloudflare oferece duas saídas: remover o redirecionamento HTTPS na origem, ou elevar a zona para Full ou mais restrito, o que exige um certificado na própria origem. Qualquer uma das alterações é feita no painel do Cloudflare, não no .htaccess. Um visitante no modo Flexible ainda navega via HTTPS, e o esquema que o Cloudflare reporta em X-Forwarded-Proto espelha a conexão do próprio visitante, então o teste de cabeçalho acima não causará falsos positivos aqui. Ainda assim, corrigir o modo de criptografia é a solução definitiva.

Após qualquer alteração, limpe o cache e os cookies do navegador antes de testar novamente, pois um 301 em cache pode mascarar uma correção. Um loop condicional que afeta apenas usuários chegando por um caminho específico via proxy é invisível em um único teste manual no seu próprio navegador. A reprodução de sessão de um site pós-migração pode revelar esse loop de redirecionamento intermitente — e quebras de conteúdo misto — como um padrão de bounce infinito que usuários reais enfrentam.

Quando .htaccess não é a ferramenta certa

.htaccess é exclusivo do Apache e só é lido em hospedagens baseadas nele. No Nginx não existe arquivo .htaccess. Você força HTTPS com um bloco de servidor que escuta na porta 80 e retorna um redirecionamento:

server {
    listen 80;
    server_name seudominio.com www.seudominio.com;
    return 301 https://$host$request_uri;
}

Mantenha o return 301 apenas no bloco da porta 80; colocá-lo dentro do bloco 443 recria o loop. Em stacks modernas, a aplicação de HTTPS geralmente pertence à camada de CDN, plataforma ou load balancer, e não à configuração do servidor.

Assim que o redirecionamento funcionar, reforce-o com um cabeçalho HSTS para que os navegadores se conectem automaticamente via HTTPS e ignorem completamente a requisição HTTP insegura. HSTS é definido na RFC 6797; o guia de HSTS da OWASP recomenda Strict-Transport-Security: max-age=63072000; includeSubDomains; preload. Trate o preload como uma via de mão única: remover um domínio da lista é lento e, enquanto aguarda, os visitantes podem ficar sem acesso ao domínio e a tudo que está abaixo dele caso você precise voltar para HTTP.

Escolha a regra que corresponde à sua configuração, implante-a com um 302 temporário, verifique se o redirecionamento resolve em um único salto, depois promova para um 301 permanente e adicione HSTS por cima. Essa sequência força HTTPS sem os loops de redirecionamento e erros em cache que transformam uma mudança de cinco minutos em uma interrupção de serviço.

Perguntas Frequentes

Qual é a diferença entre um redirecionamento 301 e um 302 ao forçar HTTPS?

Um 301 é um redirecionamento permanente e um 302 é temporário. Os navegadores fazem cache de 301s de forma agressiva e os mantêm por muito tempo, então um 301 incorreto é difícil de reverter. Ao testar um redirecionamento HTTPS, use R (um 302) nas flags do RewriteRule primeiro, confirme que o redirecionamento resolve corretamente em um único salto e depois promova para R=301 para a versão permanente.

Como verifico se o redirecionamento HTTPS está resolvendo corretamente sem apenas limpar o cache do navegador?

Execute curl -IL http://seudominio.com na linha de comando. A flag -I solicita apenas os cabeçalhos e -L segue os redirecionamentos, então você vê a cadeia completa. Uma configuração correta retorna um único 301 com um cabeçalho Location apontando para a URL https, seguido de um 200 no endereço seguro. Se você ver 301s repetidos ou um redirecionamento de volta para http, há um loop. Esse método é determinístico, ao contrário de inspecionar uma aba do navegador com cache.

Por que o redirecionamento HTTPS retorna um erro 500 em vez de redirecionar?

Um erro 500 geralmente significa que o mod_rewrite não está carregado, mas sua regra chama RewriteEngine ou RewriteRule diretamente. Envolva as regras em um bloco IfModule mod_rewrite.c para que o Apache as ignore e sirva via HTTP em vez de falhar quando o módulo estiver ausente. Na maioria das hospedagens compartilhadas e cPanel, o mod_rewrite está habilitado por padrão, mas o bloco de guarda é o padrão seguro caso você não possa confirmar isso.

A regra HTTPS do .htaccess funciona no AWS Application Load Balancer ou outros proxies que encerram TLS?

Não com a regra padrão %{HTTPS} off. Quando um AWS ALB ou load balancer similar encerra TLS, a conexão criptografada termina no proxy e a origem Apache sempre recebe HTTP simples, então %{HTTPS} nunca é on e a regra entra em loop com ERR_TOO_MANY_REDIRECTS. Em vez disso, teste RewriteCond %{HTTP:X-Forwarded-Proto} !https, que lê o cabeçalho definido pelo proxy para reportar o protocolo original do visitante.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.