Firewall con WAF for WordPress

Última revisión: 2 de octubre de 2021

Si queremos bloquear de forma automática algunos ataques podemos usar fail2ban, una herramienta que suele venir instalada en los sistemas Linux que bloquean peticiones múltiples.

Aprovechando la tecnología de fail2ban podemos aplicar una serie de reglas y, en caso de ataque, el firewall se encargará de añadir el bloqueo durante el tiempo que se establezca.

Para esto usaremos WAF for WordPress, que incluye varias funcionalidades de bloqueo; principalmente usaremos dos de ellas: la primera que analiza las peticiones HTTP que llegan por la URL, y la segunda que analiza peticiones al core.

IMPORTANTE: Un Firewall puede filtrar tráfico válido, por lo que es muy recomendable analizar con cuidado las excepciones o las configuraciones de plugins que podemos tener, ya que se pueden limitar funcionalidades.

Este tutorial ha sido creado en un VPS de Clouding.io. Puedes crear tu propio VPS desde 3€/mes.

Además, tienes la posibilidad de crear tu VPS con la imagen de WordPress en un clic.

COLABORACIÓN

Requisitos

  • WordPress
  • Fail2Ban

Configuración de Http_Analyzer

Instalación

La primera parte del Firewall es la que revisa las peticiones HTTP. En este caso deberemos analizar todas las peticiones justo cuando llegan y antes de que se cargue nada de WordPress.

Comenzaremos entrando en la carpeta donde tengamos el wp-config.php, donde descargaremos el fichero del Firewall.

wget https://raw.githubusercontent.com/szepeviktor/waf4wordpress/master/http-analyzer/waf4wordpress-http-analyzer.php -O waf4wordpress-http-analyzer.php

También se puede descargar de forma manual el ZIP con todos los ficheros y lo encontraremos dentro de la carpeta http-analyzer.

Configuración

Ahora que tenemos el fichero, lo deberemos configurar. Para ello añadiremos al inicio del fichero wp-config.php las siguientes líneas:

require_once __DIR__ . '/waf4wordpress-http-analyzer.php';
new \Waf4WordPress\Http_Analyzer();

Esto hará que el fichero quede algo tal que así:

<?php
require_once __DIR__ . '/waf4wordpress-http-analyzer.php';
new \Waf4WordPress\Http_Analyzer();
/**
The base configuration for WordPress
*
The wp-config.php creation script uses this file during the
installation. You don't have to use the web site, you can
copy this file to "wp-config.php" and fill in the values.
*
This file contains the following configurations:
*
* MySQL settings
* Secret keys
* Database table prefix
* ABSPATH
*
@link https://codex.wordpress.org/Editing_wp-config.php
*
@package WordPress
*/ 
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'labasededatos' );
/** MySQL database username */
define( 'DB_USER', 'elusuario' );

Qué revisa

El sistema analiza lo siguiente:

  • Custom CDN headers *
  • Request URI length (2500 bytes)
  • User Agent length (472 bytes)
  • HTTP methods
  • Two forward slashes in URI
  • URI encoding
  • URI blacklist
  • HTTP protocol
  • Request for non-existent PHP file
  • Request for robots.txt in a subdirectory
  • Request with author query field (author sniffing)
  • PHP and Shockwave Flash file upload
  • HTTP/POST without User Agent
  • Accept header
  • Content-Length header
  • Content-Type header
  • Accept-Language header
  • Referer header *
  • Request size for logins *
  • Login username blacklist (log POST variable) *
  • Accept-Encoding header
  • IE8 and modern browser (Mozilla/5.0) login
  • Test cookie (wordpress_test_cookie) *
  • Connection header *
  • Login from Tor exit nodes *

Configuraciones avanzadas

En el fichero de configuración podemos añadir algunas configuraciones según nuestras necesidades.

Por ejemplo, si queremos utilizar el Close en las peticiones en vez de un Keep-Alive, podemos usar esto:

define( 'W4WP_ALLOW_CONNECTION_CLOSE', true );

O por ejemplo, si queremos bloquear peticiones desde Amazon CloudFront que no sean estáticos, podemos usar esto:

define( 'W4WP_CDN_HEADERS', 'HTTP_X_FORWARDED_FOR:HTTP_X_AMZ_CF_ID:HTTP_VIA' );

La lista completa de opciones es esta:

  • (boolean) W4WP_POST_LOGGING permite el registro de todas las solicitudes POST, incluso las normales
  • (integer) W4WP_COUNT límite de activaciones para fail2ban, maxretry
  • (integer) W4WP_MAX_LOGIN_REQUEST_SIZE tamaño máximo de la solicitud de acceso
  • (string) W4WP_CDN_HEADERS una lista separada por dos puntos de cabeceras HTTP que sean reconocidos por la CDN
  • (boolean) W4WP_ALLOW_REG permite el registro en WordPress, deshabilita el referer y prueba los controles de las cookies
  • (boolean) W4WP_ALLOW_IE8 permite el acceso con Internet Explorer 8 también (IE8 no es un navegador de Mozilla/5.0)
  • (boolean) W4WP_ALLOW_OLD_PROXIES permite peticiones de login en HTTP/1.0
  • (boolean) W4WP_ALLOW_CONNECTION_EMPTY permite solicitudes sin encabezamiento de conexión HTTP
  • (boolean) W4WP_ALLOW_CONNECTION_CLOSE permiten otras cabeceras de conexión HTTP además de keep-alive
  • (boolean) W4WP_ALLOW_TWO_CAPS permiten nombres de usuario como JohnDoe (con dos mayúsculas)
  • (boolean) W4WP_DISALLOW_TOR_LOGIN para bloquear los inicios de sesión de los nodos de salida de Tor

Para detectar las IP de los usuarios / clientes:

  • HTTP_CF_CONNECTING_IP (Cloudflare)
  • HTTP_X_SUCURI_CLIENTIP (Sucuri)
  • HTTP_INCAP_CLIENT_IP (Incapsula)
  • HTTP_X_FORWARDED_FOR (Amazon CloudFront, puede ser una lista de direcciones IP separadas por coma)
  • HTTP_X_FORWARDED
  • HTTP_X_REAL_IP
  • HTTP_CLIENT_IP
  • HTTP_FORWARDED_FOR
  • HTTP_FORWARDED
  • REMOTE_ADDR

HTTP2 and SPDY

Todas las conexiones con HTTP2 y SPDY son conexiones persistentes, por lo que deberíamos activar:

define( 'W4WP_ALLOW_CONNECTION_EMPTY', true );

Configuración de Core_Events

Instalación

La segunda parte del Firewall es la que revisa los eventos del Core. Esto sólo revisa aquellas funcines que tienen que ver con accesos al panel y a usuarios registrados..

Este sistema funciona como un plugin Must-Use, por lo que deberemos comprobar que tenemos todo listo para ello.

Una vez estemos en la carpeta principal del WordPres accederemos a la de cntenidos, y una vez allí validaremos que tenemos la carpeta mu-plugins.

cd wp-content/
ls -la

En caso de no existir la carpeta, la crearemos.

mkdir mu-plugins

Y accederemos a ella.

cd mu-plugins

Ahora que estamos allí descargaremos el plugin. Se activará automáticamente y no se puede deshabilitar desde el panel.

wget https://raw.githubusercontent.com/szepeviktor/waf4wordpress/master/core-events/waf4wordpress-core-events.php -O waf4wordpress-core-events.php

También se puede descargar de forma manual el ZIP con todos los ficheros y lo encontraremos dentro de la carpeta core-events.

Porqué «Must Use»

  • Ejecución temprana: Los plugins Must-Use se ejecutan antes que los plugins normales, causando menos carga en el servidor en caso de un ataque DoS.
  • Seguridad: no puede ser desactivado, sólo manipulado por los administradores de WordPress.
  • Velocidad: porque es mucho más simple que el plugin normal con opciones.

Qué revisa

  • Evita que nadie acceda al sitio (desactivado por defecto).
  • Evita las redirecciones al /admin/ (inicia sesión sólo en /wp-admin/ o /wp-login.php).
  • Detiene los ataques de fuerza bruta (múltiples sondas de inicio de sesión y ataques de recordatorio de contraseña desde una dirección IP).
  • Detiene a los robots que escanean URLs inexistentes (404s, redirecciones, hackeo de URLs simples, protocolos relativos mal interpretados).
  • Responde con HTTP/403 Prohibido a los robots en solicitudes no frontales.
  • Deja de mostrar 404 páginas a los robots pero envía HTTP/404.
  • Prohíbe las solicitudes secuenciales 404 (desde la misma dirección IP).
  • Prohibición de cualquier autenticación basada en XMLRPC (incluso en las exitosas).
  • Prohibición de las peticiones inválidas de AJAX, XMLRPC y otras peticiones manejadas por wp_die().
  • Prohibición de acciones desconocidas de admin-ajax y admin-post.
  • Detiene a los spammers en cooperación con el plugin Contact Form 7 Robot Trap.
  • Registra los inicios de sesión y cierres de sesión de WordPress.

Configuraciones avanzadas

Impedir el acceso a sitios no mantenidos

Para denegar el acceso al usuario copie esto en el wp-config.php.

define( 'W4WP_DISABLE_LOGIN', true );

Permitir redirecciones ilimitadas para los sitios con enlaces no canonical

Para permitir redirecciones canonical ilimitadas, copia esto en el wp-config.php.

define( 'W4WP_ALLOW_REDIRECT', true );

Sobre este documento

Este documento está regulado por la licencia EUPL v1.2, publicado en WP SysAdmin y creado por Javier Casares. Por favor, si utilizas este contenido en tu sitio web, tu presentación o cualquier material que distribuyas, recuerda hacer una mención a este sitio o a su autor, y teniendo que poner el material que crees bajo licencia EUPL.