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

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.