Qué es .htaccess
Es un archivo de configuración de Apache que se lee en cada petición. Te permite cambiar comportamiento del servidor (redirecciones, cabeceras, seguridad, caché) sin tocar la configuración global del servidor. Está en la raíz de tu public_html y es oculto por defecto — en File Manager debes activar "Show Hidden Files" para verlo.
Precauciones básicas
- Haz una copia antes de editar. Un error de sintaxis puede tirar tu sitio entero con un error 500.
- Prueba después de cada cambio. Si algo falla, revierte de inmediato.
- El orden importa. Las reglas se evalúan de arriba a abajo.
Forzar HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Forzar www (o quitarlo)
Siempre con www
RewriteEngine On
RewriteCond %{HTTP_HOST} ^tudominio\.com [NC]
RewriteRule ^(.*)$ https://www.tudominio.com/$1 [R=301,L]
Siempre sin www
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.tudominio\.com [NC]
RewriteRule ^(.*)$ https://tudominio.com/$1 [R=301,L]
Bloquear acceso por IP
<RequireAll>
Require all granted
Require not ip 198.51.100.0/24
Require not ip 203.0.113.45
</RequireAll>
Permitir solo ciertas IPs
<RequireAll>
Require ip 203.0.113.0/24
Require ip 198.51.100.10
</RequireAll>
Útil para proteger /wp-admin si trabajas siempre desde las mismas IPs.
Password-proteger una carpeta
AuthType Basic AuthName "Zona restringida" AuthUserFile /home/tuusuario/.htpasswds/secreto/passwd Require valid-user
En cPanel, la herramienta Directory Privacy genera esto automáticamente.
Habilitar compresión GZIP
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript application/json
</IfModule>
Caché de navegador
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
Prevenir listado de directorios
Options -Indexes
Sin esta línea, si tu carpeta no tiene un index.html o index.php, el servidor muestra el contenido. Esto expone archivos que no quieres.
Proteger archivos sensibles
<FilesMatch "^(\.env|\.htaccess|\.htpasswd|wp-config\.php|composer\.json|package\.json)$">
Require all denied
</FilesMatch>
Bloquear user agents maliciosos
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (bot1|bot2|scraper) [NC]
RewriteRule .* - [F,L]
Hotlink protection (evitar que otros roben tu ancho de banda)
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?tudominio\.com [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp)$ - [F]
Personalizar páginas de error
ErrorDocument 404 /errors/404.html ErrorDocument 403 /errors/403.html ErrorDocument 500 /errors/500.html
Redirigir páginas obsoletas
Redirect 301 /pagina-vieja.html /nueva-pagina Redirect 301 /blog/antiguo /nuevo-blog
Orden recomendado en .htaccess
Si combinas muchas reglas, usa este orden general:
- Seguridad y bloqueo de archivos sensibles.
- Bloqueo de IPs y user agents.
- Forzar HTTPS y www.
- Redirects 301 específicos.
- Rewrite rules del CMS (WordPress las pone al final).
- Compresión y caché.
- Error documents.
Error 500 tras editar
Si ves Internal Server Error tras guardar un cambio, hay un error de sintaxis. Acciones:
- Restaura la copia de respaldo que hiciste antes.
- Activa display de errores (solo para depurar):
php_flag display_errors on. - Revisa
/home/tuusuario/logs/error_log— la línea del error aparece ahí. - Agrega las reglas de a una hasta encontrar la que rompe.