Guía de configuración de redirecciones en Apache
Contenido
Las redirecciones en Apache se configuran principalmente a través de archivos .htaccess y el módulo mod_rewrite. Esto es especialmente útil en hosting compartido donde no tienes acceso a la configuración principal del servidor.
Conceptos básicos de .htaccess
.htaccess es el archivo de configuración por directorio de Apache. Colócalo en la raíz de tu sitio y Apache lo leerá automáticamente. El nombre del archivo comienza con un punto — es un archivo oculto en sistemas Unix.
Habilitar mod_rewrite
# Ubuntu/Debian
sudo a2enmod rewrite
sudo systemctl restart apache2
# CentOS/RHEL — descomentar en /etc/httpd/conf/httpd.conf:
LoadModule rewrite_module modules/mod_rewrite.so
Permitir sobreescrituras de .htaccess
<Directory /var/www/html>
AllowOverride All
</Directory>
Directiva Redirect
El enfoque más simple — no requiere regex:
# 301 permanente
Redirect 301 /old-page.html https://example.com/new-page.html
# 302 temporal
Redirect 302 /sale https://example.com/promo
# Redirección de todo el sitio a un nuevo dominio
Redirect 301 / https://new-domain.com/
💡 Limitaciones de Redirect
La directiva Redirect es simple pero no soporta regex ni lógica condicional. Usa RewriteRule para cualquier cosa más compleja.
RewriteRule
RewriteEngine On
# HTTP → HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
# sin www → www
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
Flags comunes
[R=301]— redirección 301 permanente[R=302]— redirección 302 temporal[L]— última regla, detener el procesamiento[NC]— coincidencia sin distinción de mayúsculas[QSA]— agregar el query string original
RewriteCond
Condiciones que deben cumplirse antes de que se ejecute la siguiente RewriteRule:
# Redirigir usuarios móviles
RewriteCond %{HTTP_USER_AGENT} "android|iphone|ipad" [NC]
RewriteRule ^(.*)$ https://m.example.com/$1 [R=302,L]
# Redirigir según query string
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteRule ^article$ /post/%1? [R=301,L]
Escenarios comunes
Forzar HTTPS + www
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
Eliminar extensión .html
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.+)$ $1.html [L]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /(.+)\.html
RewriteRule ^ /%1 [R=301,L]
Permalinks de WordPress
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Errores comunes
Error 500 Internal Server Error
Casi siempre es un error de sintaxis en .htaccess. Revisa el log de errores de Apache:
tail -f /var/log/apache2/error.log
Bucle de redirección
# ❌ Bucle — no hay condición para detener la coincidencia
RewriteRule ^(.*)$ https://example.com/ [R=301,L]
# ✅ Agregar condición HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://example.com/ [R=301,L]
Pérdida de query strings
# ❌ Se pierde el query string
RewriteRule ^old-page$ /new-page [R=301,L]
# ✅ Preservar con el flag QSA
RewriteRule ^old-page$ /new-page [R=301,L,QSA]
Depuración
# Habilitar log de rewrite (Apache 2.4)
LogLevel alert rewrite:trace3
# Probar con curl
curl -I http://example.com/old-page
curl -IL http://example.com/old-page
O usa 301check.com para visualizar la cadena completa de redirección.