Last Revised: October 2, 2021
If we want to automatically block some attacks we can use fail2ban, a tool that is usually installed on Linux systems that block multiple requests.
Taking advantage of the fail2ban technology we can apply a series of rules and, in case of attack, the firewall will be responsible for adding the block for as long as it is established.
For this we will use WAF for WordPress, which includes several blocking functionalities; mainly we will use two of them: the first that analyzes the HTTP requests that arrive by the URL, and the second that analyzes requests to the core.
IMPORTANT: A firewall can filter valid traffic, so it is highly recommended to carefully analyze the exceptions or plugin configurations that we may have, since functionalities can be limited.
This tutorial has been created on a Clouding.io VPS. You can create your own VPS from 3€/month.
In addition, you have the possibility to create your VPS with the WordPress image in one click.
PARTNERSHIP
Requirements
- WordPress
- Fail2Ban
Configuring Http_Analyzer
Installation
The first part of the Firewall is the one that reviews HTTP requests. In this case we will have to analyze all the requests just when they arrive and before anything from WordPress is loaded.
We will start by entering the folder where we have the wp-config.php
, where we will download the Firewall file.
wget https://raw.githubusercontent.com/szepeviktor/waf4wordpress/master/http-analyzer/waf4wordpress-http-analyzer.php -O waf4wordpress-http-analyzer.php
You can also manually download the ZIP with all the files and we will find it inside the folder http-analyzer
.
Configuration
Now that we have the file, we must configure it. To do this we will add the following lines at the beginning of the file wp-config.php
:
require_once __DIR__ . '/waf4wordpress-http-analyzer.php';
new Waf4WordPressHttp_Analyzer();
This will make the file look something like this:
<?php
require_once __DIR__ . '/waf4wordpress-http-analyzer.php';
new Waf4WordPressHttp_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' );
What you review
The system analyzes the following:
- Custom CDN headers
*
- Request URI length (2500 bytes)
- User Agent length (472 bytes)
- HTTP methods
- Two forward slashes in URI
- Encoding URI
- Blacklist URI
- 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
- Cookie test (
wordpress_test_cookie
)*
- Connection header
*
- Login from Tor exit nodes
*
Advanced settings
In the configuration file we can add some configurations according to our needs.
For example, if we want to use the Close in requests instead of a Keep-Alive, we can use this:
define( 'W4WP_ALLOW_CONNECTION_CLOSE', true );
Or for example, if we want to block requests from Amazon CloudFront that are not static, we can use this:
define( 'W4WP_CDN_HEADERS', 'HTTP_X_FORWARDED_FOR:HTTP_X_AMZ_CF_ID:HTTP_VIA' );
The full list of options is this:
- (boolean)
W4WP_POST_LOGGING
allows the registration of all POST requests, even normal ones - (integer)
W4WP_COUNT
activation limit for fail2ban,maxretry
- (integer)
W4WP_MAX_LOGIN_REQUEST_SIZE
maximum size of the access request - (string)
W4WP_CDN_HEADERS
a list separated by two HTTP header points that are recognized by the CDN - (boolean)
W4WP_ALLOW_REG
allows logging in WordPress, disables the referer and tests cookie controls - (boolean)
W4WP_ALLOW_IE8
allows access with Internet Explorer 8 as well (IE8 is not a Mozilla/5.0 browser) - (boolean)
W4WP_ALLOW_OLD_PROXIES
allows login requests inHTTP/1.0
- (boolean)
W4WP_ALLOW_CONNECTION_EMPTY
allows requests without HTTP connection header - (boolean)
W4WP_ALLOW_CONNECTION_CLOSE
allow other HTTP connection headers in addition tokeep-alive
- (boolean)
W4WP_ALLOW_TWO_CAPS
allow usernames such asJohnDoe
(with two capital letters) - (boolean)
W4WP_DISALLOW_TOR_LOGIN
to block logins from Tor exit nodes
To detect the IPs of users/clients:
HTTP_CF_CONNECTING_IP
(Cloudflare)HTTP_X_SUCURI_CLIENTIP
(Sucuri)HTTP_INCAP_CLIENT_IP
(Incapsula)HTTP_X_FORWARDED_FOR
(Amazon CloudFront, can be a comma-separated list of IP addresses)HTTP_X_FORWARDED
HTTP_X_REAL_IP
HTTP_CLIENT_IP
HTTP_FORWARDED_FOR
HTTP_FORWARDED
REMOTE_ADDR
HTTP2 and SPDY
All connections with HTTP2 and SPDY are persistent connections, so we should activate:
define( 'W4WP_ALLOW_CONNECTION_EMPTY', true );
Configuring Core_Events
Installation
The second part of the Firewall is the one that reviews the events of the Core. This only reviews those functions that have to do with access to the panel and registered users.
This system works as a Must-Use plugin, so we must check that we have everything ready for it.
Once we are in the main folder of WordPres we will access the one of cntenidos, and once there we will validate that we have the folder mu-plugins
.
cd wp-content/
ls -la
If the folder does not exist, we will create it.
mkdir mu-plugins
And we will access it.
cd mu-plugins
Now that we are there we will download the plugin. It will be activated automatically and cannot be disabled from the dashboard.
wget https://raw.githubusercontent.com/szepeviktor/waf4wordpress/master/core-events/waf4wordpress-core-events.php -O waf4wordpress-core-events.php
You can also manually download the ZIP with all the files and we will find it inside the folder core-events
.
Why “Must Use”
- Early execution: Must-Use plugins run earlier than regular plugins, causing less load on the server in the event of a DoS attack.
- Security: Cannot be disabled, only manipulated by WordPress administrators.
- Speed: because it is much simpler than the normal plugin with options.
What you review
- Prevents anyone from accessing the site (disabled by default).
- Avoid redirects to (log in only to
/admin/
/wp-admin/
or/wp-login.php
). - Stops brute force attacks (multiple login probes and password reminder attacks from an IP address).
- It stops robots scanning non-existent URLs (404s, redirects, hacking simple URLs, misinterpreted relative protocols).
- Responds with HTTP/403 Prohibits robots on non-frontal requests.
- Stops showing 404 pages to robots but sends HTTP/404.
- Prohibits 404 sequential requests (from the same IP address).
- Prohibition of any XMLRPC-based authentication (even successful ones).
- Prohibition of invalid requests from AJAX, XMLRPC and other requests handled by
wp_die()
. - Prohibition of unknown actions of
admin-ajax
andadmin-post
. - Stops spammers in cooperation with the Contact Form 7 Robot Trap plugin.
- Records WordPress logins and logouts.
Advanced settings
Prevent access to unmaintained sites
To deny access to the user copy this to .wp-config.php
define( 'W4WP_DISABLE_LOGIN', true );
Allow unlimited redirects for sites with non-canonical links
To allow unlimited canonical redirects, copy this to the wp-config.php
.
define( 'W4WP_ALLOW_REDIRECT', true );
About this document
This document is regulated by the EUPL v1.2 license, published in WP SysAdmin and created by Javier Casares. Please, if you use this content in your website, your presentation or any material you distribute, remember to mention this site or its author, and having to put the material you create under EUPL license.