Cómo forzar HTTPS con .htaccess
Fuerza HTTPS con .htaccess usando reglas de reescritura de Apache, corrige bucles tras CDN o balanceadores y configura www y HSTS.
Para forzar HTTPS en todo el tráfico en Apache, añade tres líneas al archivo .htaccess en la raíz de tu sitio: RewriteEngine On, RewriteCond %{HTTPS} off y RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301].
Si alguna vez has pegado una regla de redirección tomada de un foro y luego has visto cómo el navegador entraba en un bucle hasta rendirse, lo más probable es que la regla en sí fuera correcta. Lo que suele romperla es lo que se encuentra delante de tu servidor.
Esta regla intercepta cada solicitud que llega por HTTP plano y emite una redirección permanente a la misma URL en HTTPS. Funciona en Apache con mod_rewrite habilitado y un certificado SSL ya instalado, y falla de maneras específicas y predecibles cuando hay una CDN o un balanceador de carga delante de tu servidor de origen. Esta guía te ofrece primero la regla lista para copiar y pegar, luego las variantes por dominio, carpeta y www, después las soluciones para los bucles de redirección, y finalmente qué hacer si no estás usando Apache.
Puntos clave
- La regla canónica evalúa
RewriteCond %{HTTPS} offy reescribe ahttps://%{HTTP_HOST}%{REQUEST_URI}, lo que preserva el dominio y la ruta exactos que el visitante solicitó, en lugar de codificar un único dominio de forma fija. R=301emite una redirección permanente yLdetiene el procesamiento de reescritura; durante las pruebas, usa primeroR(una redirección temporal 302), ya que los navegadores almacenan en caché las redirecciones 301 de forma agresiva.- Forzar HTTPS solo funciona si ya hay un certificado TLS/SSL válido instalado. Redirigir sin uno hace que el sitio sea inaccesible, no seguro.
- Detrás de un proxy que termina TLS,
%{HTTPS}nunca eson, por lo que la regla entra en bucle conERR_TOO_MANY_REDIRECTS; en su lugar, evalúa%{HTTP:X-Forwarded-Proto}. - Un bucle de SSL Flexible de Cloudflare es una configuración incorrecta del lado de Cloudflare que se corrige cambiando el modo de cifrado, no editando
.htaccess.
Antes de empezar: certificado SSL y mod_rewrite
Forzar HTTPS solo funciona si ya hay un certificado TLS/SSL válido instalado en el dominio. Redirigir a HTTPS sin un certificado no asegura el sitio, sino que lo hace inaccesible tras una advertencia de seguridad del navegador. (“Certificado SSL” es el término habitual en la industria; el protocolo en realidad es TLS.) Confirma que el certificado está activo cargando https://tudominio.com directamente en un navegador y verificando que aparece el candado antes de tocar el archivo .htaccess.
La regla que se muestra a continuación depende del módulo mod_rewrite de Apache, que está habilitado por defecto en la mayoría de los alojamientos compartidos y con cPanel. El archivo .htaccess se encuentra en la raíz de tu sitio, normalmente en public_html o en el directorio raíz del dominio. Puedes editarlo a través del Administrador de archivos de cPanel (activa “Mostrar archivos ocultos” para ver los dotfiles), por FTP o mediante SSH. Haz una copia de seguridad del archivo antes de editarlo para poder restaurarlo si alguna regla falla.
Discover how at OpenReplay.com.
La regla .htaccess para forzar HTTPS en todo el tráfico
Pega esto en el archivo .htaccess en la raíz de tu sitio para redirigir todas las solicitudes HTTP a HTTPS:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Línea por línea: RewriteEngine On activa el motor de reescritura. RewriteCond %{HTTPS} off ejecuta la regla solo cuando la conexión no está cifrada. RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} reconstruye la URL en HTTPS, y las variables %{HTTP_HOST} y %{REQUEST_URI} preservan el dominio y la ruta exactos que el visitante solicitó, por lo que la regla funciona en múltiples dominios y nunca fuerza www de forma silenciosa.
En los flags [L,R=301], R=301 emite una redirección permanente y L detiene el procesamiento de reescritura en esa regla. Durante las pruebas, usa primero R solo (una redirección temporal 302), ya que los navegadores almacenan en caché las redirecciones 301 de forma agresiva y una incorrecta es difícil de revertir; cambia a R=301 solo una vez que hayas confirmado que la redirección se resuelve correctamente.
No repitas RewriteEngine On. Si la línea ya existe en el archivo, añade únicamente RewriteCond y RewriteRule debajo de ella.
Variantes: dominio específico, carpeta y canonicalización de www
Para forzar HTTPS en un único dominio cuando varios apuntan al mismo directorio raíz, añade una condición sobre HTTP_HOST:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^yourdomain\.com [NC]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
El flag NC hace que la coincidencia del host sea insensible a mayúsculas y minúsculas. Para combinar HTTPS con la canonicalización de www/sin www, htaccessbook documenta cómo envolver ambas redirecciones en un bloque de control de 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>
La versión publicada de este bloque asume que RewriteEngine On aparece antes en el archivo, por lo que se ha añadido arriba para que el fragmento funcione de forma independiente. La primera regla mueve la solicitud a HTTPS. La segunda añade www a un host que no lo tiene. Ten en cuenta que [L] detiene el procesamiento en cuanto una regla coincide, por lo que una solicitud HTTP plana sin www genera dos redirecciones, no una: primero a HTTPS y luego al host con www. Envolver las reglas en <IfModule mod_rewrite.c> hace que el sitio falle de forma abierta (sirviendo por HTTP) en lugar de lanzar un error 500 si mod_rewrite no está cargado.
Combinar estas reglas manualmente se vuelve complicado cuando mezclas HTTPS, canonicalización de www, algunas redirecciones y un bloque de caché en el mismo archivo; un flag erróneo o una regla en el orden incorrecto puede causarte problemas en producción. El generador de htaccess de OpenReplay ensambla el archivo a partir de un conjunto de opciones: forzar HTTPS, añadir o eliminar www, añadir redirecciones 301 o 302, activar gzip y caché del navegador, bloquear IPs y mapear páginas de error personalizadas. El resultado está comentado, se actualiza a medida que cambias las opciones y se ejecuta completamente en tu navegador, por lo que puedes copiarlo o descargarlo y compararlo con lo que ya tienes.
Solución de ERR_TOO_MANY_REDIRECTS detrás de una CDN o balanceador de carga
Si tu redirección provoca ERR_TOO_MANY_REDIRECTS, el navegador ha seguido demasiados saltos y se ha rendido. La causa habitual es un proxy o balanceador de carga que termina TLS. TLS finaliza en el proxy, por lo que %{HTTPS} nunca es on en el servidor de origen, la regla se ejecuta en cada solicitud y el bucle nunca se rompe. La solución es confiar en el esquema reenviado:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
Aquí, RewriteCond %{HTTP:X-Forwarded-Proto} !https lee la cabecera X-Forwarded-Proto que establece el proxy, por lo que la regla solo se ejecuta cuando la conexión original del visitante era HTTP. Prueba con R antes de promover a R=301.
Un bucle de SSL Flexible de Cloudflare es un problema diferente con una solución diferente. Con el cifrado Flexible, el salto entre Cloudflare y tu servidor no está cifrado, por lo que una regla en el servidor de origen que insiste en HTTPS sigue reenviando la solicitud en un bucle. Cloudflare ofrece dos salidas: eliminar la redirección HTTPS en el servidor de origen, o subir la zona a Full o más estricto, lo que requiere un certificado en el propio servidor de origen. Cualquiera de los dos cambios se realiza en el panel de Cloudflare, no en .htaccess. Un visitante en modo Flexible sigue navegando por HTTPS, y el esquema que Cloudflare reporta en X-Forwarded-Proto refleja la conexión del propio visitante, por lo que la prueba de cabecera anterior no generará falsos positivos. Corregir el modo de cifrado sigue siendo la solución real.
Tras cualquier cambio, borra la caché y las cookies del navegador antes de volver a probar, ya que una redirección 301 en caché puede ocultar una corrección. Un bucle condicional que solo afecta a los usuarios que llegan a través de una ruta con proxy es invisible en una prueba manual desde tu propio navegador. La reproducción de sesiones de un sitio tras una migración puede revelar ese bucle de redirección intermitente, así como los errores de contenido mixto, como un patrón de rebote infinito que afecta a usuarios reales.
Cuándo .htaccess no es la herramienta adecuada
.htaccess es exclusivo de Apache y solo se lee en alojamientos basados en Apache. En Nginx no existe el archivo .htaccess. Para forzar HTTPS se utiliza un bloque de servidor que escucha en el puerto 80 y devuelve una redirección:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$host$request_uri;
}
Mantén return 301 solo en el bloque del puerto 80; colocarlo dentro del bloque 443 recrea el bucle. En stacks modernos, la aplicación de HTTPS suele corresponder a la capa de CDN, plataforma o balanceador de carga, en lugar de a la configuración del servidor.
Una vez que tu redirección funcione, refuérzala con una cabecera HSTS para que los navegadores se conecten automáticamente por HTTPS y omitan la solicitud HTTP insegura por completo. HSTS está definido en el RFC 6797; la guía de referencia de HSTS de OWASP recomienda Strict-Transport-Security: max-age=63072000; includeSubDomains; preload. Trata preload como una decisión irreversible: eliminar un dominio de la lista es un proceso lento, y mientras esperas, los visitantes pueden quedar bloqueados fuera del dominio y todo lo que hay bajo él si alguna vez necesitas volver a HTTP.
Elige la regla que se adapte a tu configuración, despliégala con una redirección temporal 302, verifica que se resuelve en un único salto y luego promociónala a una redirección permanente 301 y añade HSTS encima. Esta secuencia fuerza HTTPS sin los bucles de redirección ni los errores en caché que convierten un cambio de cinco minutos en una interrupción del servicio.
Preguntas frecuentes
¿Cuál es la diferencia entre una redirección 301 y una 302 al forzar HTTPS?
Una redirección 301 es permanente y una 302 es temporal. Los navegadores almacenan en caché las redirecciones 301 de forma agresiva y las retienen durante mucho tiempo, por lo que una 301 incorrecta es difícil de revertir. Al probar una redirección HTTPS, usa primero R (una 302) en los flags de RewriteRule, confirma que la redirección se resuelve correctamente en un único salto y luego promociónala a R=301 para la versión permanente.
¿Cómo verifico que mi redirección HTTPS se resuelve correctamente en lugar de simplemente borrar la caché del navegador?
Ejecuta curl -IL http://tudominio.com desde la línea de comandos. El flag -I solicita solo las cabeceras y -L sigue las redirecciones, por lo que puedes ver la cadena completa. Una configuración correcta devuelve una única redirección 301 con una cabecera Location apuntando a la URL https, seguida de un 200 en la dirección segura. Si ves redirecciones 301 repetidas o una redirección de vuelta a http, tienes un bucle. Esto es determinista, a diferencia de inspeccionar una pestaña del navegador con caché.
¿Por qué mi redirección HTTPS lanza un error 500 en lugar de redirigir?
Un error 500 normalmente significa que mod_rewrite no está cargado pero tu regla llama directamente a RewriteEngine o RewriteRule. Envuelve las reglas en un bloque IfModule mod_rewrite.c para que Apache las omita y sirva por HTTP en lugar de fallar cuando el módulo no está presente. En la mayoría de los alojamientos compartidos y con cPanel, mod_rewrite está habilitado por defecto, pero el bloque de control es el patrón seguro si no puedes confirmarlo.
¿Funciona la regla HTTPS de .htaccess en AWS Application Load Balancer u otros proxies que terminan TLS?
No con la regla estándar %{HTTPS} off. Cuando un AWS ALB o un balanceador de carga similar termina TLS, la conexión cifrada finaliza en el proxy y tu servidor de origen Apache siempre recibe HTTP plano, por lo que %{HTTPS} nunca es on y la regla entra en bucle con ERR_TOO_MANY_REDIRECTS. En su lugar, evalúa RewriteCond %{HTTP:X-Forwarded-Proto} !https, que lee la cabecera que establece el proxy para reportar el protocolo original del visitante.