Tips .htaccess para WordPress – Vertegrande

Tips .htaccess para WordPress

A través del archivo .htaccess le damos “instrucciones” al servidor web sobre cómo tiene que comportarse, sin necesidad de realizar parametrizaciones sobre los archivos de configuración del propio servicio.


El .htaccess es uno de los archivos protagonistas en entornos web, un archivo original de Apache que también entienden otros servidores web.

A través del archivo .htaccess le damos “instrucciones” al servidor web sobre cómo tiene que comportarse, sin necesidad de realizar parametrizaciones sobre los archivos de configuración del propio servicio.

En este post vamos a hablar de algunas cosas que podemos configurar en el .htaccess de nuestro hosting y que van a influir en la forma de funcionar de nuestro WordPress.

Empecemos por el principio. Este es el .htaccess predeterminado de un WordPress recién instalado con los enlaces permanentes o URL amigables activos:

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
 
# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
 
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]

Nota. Algunos plugins que vamos instalando en nuestro WordPress van añadiendo cosas al .htaccess y parametrizando el funcionamiento del servidor web. Dato para tener en cuenta.

Activar la compresión GZIP / DEFLATE

Si el servidor Apache tiene mod_deflate activado y listo para usarse, podemos activar la compresión GZIP o Deflate simplemente utilizando el siguiente código en el .htaccess.


<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 month"
<FilesMatch "\.(txt|xml|js)$">
ExpiresDefault "access plus 1 month"
</FilesMatch>
<FilesMatch "\.(css)$">
ExpiresDefault "access plus 1 month"
</FilesMatch>
<FilesMatch "\.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav|mp4|m4v|ogg|webm|aac)$">
ExpiresDefault "access plus 1 month"
</FilesMatch>
<FilesMatch "\.(jpg|jpeg|png|gif|swf|webp)$">
ExpiresDefault "access plus 1 month"
</FilesMatch>
</IfModule>
<IfModule mod_headers.c>
  <FilesMatch "\.(txt|xml|js)$">
   Header set Cache-Control "max-age=2592000"
  </FilesMatch>
  <FilesMatch "\.(css)$">
   Header set Cache-Control "max-age=2592000"
  </FilesMatch>
  <FilesMatch "\.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav|mp4|m4v|ogg|webm|aac)$">
   Header set Cache-Control "max-age=2592000"
  </FilesMatch>
  <FilesMatch "\.(jpg|jpeg|png|gif|swf|webp)$">
   Header set Cache-Control "max-age=2592000"
  </FilesMatch>
</IfModule>
Activar Keep Alive en Apache

El parámetro Keep Alive permite que la conexión entre el servidor y el navegador del visitante no se cierre. Como resultado, si hay que realizar varias peticiones consecutivas, al mantener la conexión abierta se realizarán mucho más rápidamente. Es lo que comúnmente se llama “conexión persistente”.

Podemos activar Keep Alive siempre y cuando el servidor web lo tenga activo y utilizando este código:

# Activar Keep Alive
KeepAlive On

# Conexiones maximas persistentes por Keep Alive
MaxKeepAliveRequests 100

# Keep Alive Timeout de cada conexion
KeepAliveTimeout 100

¿Qué razones existen para tener Keep Alive desactivado? Pues el consumo de recursos en el servidor, ya que un servidor con Keep Alive consume bastantes más recursos que uno con la misma opción desactivada debido a la gran cantidad de peticiones que hay que mantener abiertas.

Solucionar “Specy a Vary: Accept-Encoding Header”

Este error suele aparecer en Pingdom Tools y en GTMetrix. Antes también aparecía en Google PageSpeed Insights, pero desde hace algún tiempo lo he dejado de ver.

Se trata de una cabecera que se envía desde el servidor al visitante. Se utiliza para que el servidor y el navegador del visitante se entiendan en cuanto a la codificación del contenido y la compresión.

En Apache puedes especificar esto en el .htaccess con el siguiente código:


<IfModule mod_headers.c>
	<FilesMatch ".(js|css|xml|gz|html)$">
		Header append Vary: Accept-Encoding
	</FilesMatch>
</IfModule>
Activar cache de navegador o browser cache

El browser cache nos permite ahorrar recursos en el servidor web y también ancho de banda en el hosting o servidor.

Puedes activar la cache de navegador para los tipos de archivos más comunes con este código en el .htaccess:

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  ExpiresByType image/x-icon "access plus 1 year"
  ExpiresByType video/mp4 "access plus 1 year"
  ExpiresByType video/mpeg "access plus 1 year"
  ExpiresByType text/css "access plus 1 month"
  ExpiresByType text/javascript "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"
  ExpiresByType application/pdf "access plus 1 month"
  ExpiresByType application/x-shockwave-flash "access plus 1 month"
</IfModule>

Deshabilitar el listado de carpetas

De forma predeterminada, en muchas ocasiones el servidor web envía un listado de carpetas y archivos al navegador del visitante si este introduce una URL que no está disponible.

Esto es un problema de seguridad, ya que permite que cualquier visitante vea todos los archivos subidos a nuestro hosting.

Options -Indexes

En principio, este snippet funciona solo en Apache.

Recuerda: esto es un básico para la seguridad de cualquier sitio web.

Desactivar el acceso a los tipos de archivos NO listados

Con este código mejoramos la seguridad, aunque de una forma bastante radical, ya que bloqueamos los accesos a todos los tipos de archivos menos los especificados en el .htaccess:

Order deny,allow
Deny from all
<Files ~ ".(xml|css|js|jpeg|png|gif|pdf|docx|rtf|odf|zip|rar)$">
Allow from all
</Files>
Desactivar la ejecución de PHP en Uploads

Este código es algo diferente. Debemos utilizarlo en un archivo .htaccess dentro de la carpeta UPLOADS de WordPress con el fin de que no se pueda ejecutar PHP dentro de esa carpeta.

¿Cuál es la razón para hacer esto? Pues que, en la práctica, no tiene por qué haber ningún archivo PHP dentro de UPLOADS. Con este código, evitamos que se pueda ejecutar uno en caso de que se use algún “exploit” para subirlo.

<Files *.php>
deny from all
</Files>

Recuerda: no lo utilices en el .htaccess principal del sitio web o lo que conseguirás es que falle.

Bloquear el acceso a los archivos importantes

Con este snippet en el .htaccess de un WordPress, mejoramos la seguridad de la instalación al bloquear el acceso externo a ciertos archivos importantes de WordPress que, en condiciones normales, no necesitan ser descargados nunca desde el navegador del visitante.

<FilesMatch "^.*(error_log|wp-config|install|wp-login|xmlrpc\.php|php.ini|\.[hH][tT][aApP].*)$">
Order deny,allow
Deny from all
</FilesMatch>

Una vez más, te recuerdo que para casos específicos debes personalizar este archivo y entenderlo. El motivo es que incluye comodines y, en ciertos casos, pueden llegar a dar problemas con algún plugin o componente de la instalación WordPress.

Bloquear el acceso a WP-INCLUDES de WordPress

La carpeta WP-INCLUDES de WordPress es una de las más importantes, ya que guarda librerías y componentes internos necesarios para que WordPress funcione.

Sin embargo, a la carpeta WP-INCLUDES no se tiene que acceder para nada desde fuera, es decir, desde el navegador del visitante. Por eso, podemos bloquear el acceso mediante el .htaccess con este código:

<IfModule mod_rewrite.c> 
RewriteEngine On 
RewriteBase / 
RewriteRule ^wp-admin/includes/ - [F,L] 
RewriteRule !^wp-includes/ - [S=3] 
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L] 
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L] 
RewriteRule ^wp-includes/theme-compat/ - [F,L] 
</IfModule>

Código para prevenir posibles inyecciones de código

Con este código en el .htaccess podemos llegar a bloquear algunas inyecciones de código básicas realizadas desde bots.

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]

Ten cuidado con el efecto de este código, ya que puede provocar problemas y conflictos con algunos plugins para WordPress. En teoría ayuda a solucionar problemas, pero es importante estar preparados para los fallos que pueda llegar a dar. Es posible que tengamos que personalizar el código para adaptarlo a nuestro sitio web.

Protección contra HOTLINKING en WordPress

El hotlink puede llegar a dar muchos problemas en sitios web pequeños, ya que si te enlazan una imagen desde un sitio web grande con mucho tráfico puede llegar a “reventarte” el tráfico o ancho de banda de tu hosting rápidamente.

Podemos protegernos del hotlinking de una forma bastante “rastrera” pero eficaz con el siguiente código en el .htaccess:

<IfModule mod_rewrite.c>
	RewriteEngine on
	RewriteCond %{HTTP_REFERER} !^$
	RewriteCond %{HTTP_REFERER} !^https://(www\.)?midominio\.com/.*$ [NC]
	RewriteRule .*\.(gif|jpg)$ https://midominio.com/bloqueo.jpe [R,NC,L]
</ifModule>

Si quieres protegerte contra esto de otra forma, también puedes configurar un CDN como CloudFlare para servir las imágenes y no tener que preocuparte por el tema del ancho de banda en el hosting.

Modificar configuración de PHP

En algunos entornos (no en todos), podemos modificar el comportamiento del intérprete PHP directamente desde el .htaccess. Eso quiere decir que podemos modificar los límites.

Como he dicho esto no siempre es así, pero por si lo necesitas y quieres probar, te dejo el código que tienes que poner en el .htaccess:

php_value upload_max_filesize 64M
php_value post_max_size 64M
php_value max_execution_time 300
php_value max_input_time 300

Pueden encontrar otros tips y trucos en https://alvarofontela.com/htaccess-para-wordpress-tips-trucos/