• YouTube
  • LinkedIn
  • Google

Protecting your WordPress from attacks

This site you are accessing is an installation of the WordPress. I like the ease of it.

WordPress is really good at producing a blog quickly in a VPS or Cloud, but its ease is also its biggest defect.

How simple it is to have a website with it, the vast majority of pages present on the internet are made using it and consequently this attracts those looking for flaws in the programming of its open source.

Once a fault is discovered, a mischievous hacker will be able to use this flaw on millions of websites around the world, to publish files, send emails and even create fake websites within a domain. All these are things I've seen and I believe even you've seen.

One of the things that bothers me most about WordPress is its authentication and execution mechanism XML-RPC. They are constant sources of brute force attack.

Just take a look at the last ones 10 lines in this log file of mine (taken in real time from this server while writing this article without the use of any protection mechanism).

Jun 8 21:09:39 host wordpress([1010]: Authentication failure for gestao_click from
Jun 8 21:09:40 host wordpress([1791]: Authentication failure for guestposter from
Jun 8 21:09:41 host wordpress([9892]: Authentication failure for ricardo_pereira from
Jun 8 21:10:15 host wordpress([6490]: XML-RPC authentication attempt for unknown user admin from
Jun 8 21:11:38 host wordpress([1011]: Authentication failure for alexacolemanmkdef from
Jun 8 21:11:38 host wordpress([6490]: Authentication failure for alexia_dias from
Jun 8 21:11:39 host wordpress([5620]: Authentication failure for beatriz_seomarketing from
Jun 8 21:11:40 host wordpress([6489]: Authentication failure for bianca_oblige from
Jun 8 21:11:41 host wordpress([1010]: Authentication failure for celioedu from
Jun 8 21:11:42 host wordpress([9893]: Authentication failure for celeste_pinto from

Only by these lines can you see that there is an intense activity of trying to authenticate in existing WordPress installations, practically one per second.

To mitigate these constant invasion attempts, I use a few years ago the formula of including the IPs of these requests in the firewall filters, completely blocking access to the server that comes from these. This drastically reduces these attempts. Initially i did this manually, handling logs and adding the most insistent IPs, but then I discovered a script that did it automatically: O Fail2Ban.


The Fail2Ban is a script for a daemon that monitors logs and bans IPs. With it it is possible to analyze logs of any software that has authentication such as WordPress and from the present failures include the source IPs in filters in the firewall.

It is very simple to use and is available in several repositories for different Linux distributions.

Below I'll show you how to do an installation and configuration using Centos 8 together with the firewalld

Instalando os recursos necessários

The lines below install all the necessary items.

$ sudo dnf install -y 
$ sudo rpm -ql epel-release 
$ sudo dnf install firewalld fail2ban -y

From this point should already have fail2ban installed and also the firewalld.

NOTE: If you are using the shell from an SSH connection, it is necessary to add the connection port to public zone so you don't end up activating the firewall and blocking remote access.

To do this use the command:

$ sudo systemctl start firewalld &;&; sudo Firewall-cmd --zone=public --add-port=22/tcp --permanent &;&; sudo Firewall-cmd --zone=public --add-service=https --permanent &;&; sudo Firewall-cmd --zone=public --add-service=http --permanent &;&; sudo Firewall-cmd --reload

If all is right you will be with the firewalld active at this time and with the ports 80, 443 and 22 released to the public zone.

Now let's activate the services so that they always start together with the system.

$ sudo systemctl enable fail2ban
$ sudo systemctl enable firewalld


As we are talking about WordPress I will not show how to configure fail2ban to read the web server logs and ban IPs from them. There's a much simpler way to do this using an appropriate plugin. The WPFail2Ban. Just install it and ready.

With WPFail2Ban installed and without changing any settings, it will add all login attempt failures to the default system syslog file which in the case of CentOS is the /var/log/messages.

In my installation, I did not use the settings indicated in the WPFail2Ban manual, even because there were no filters Indicated.

The first thing to do is to create a filter for Fail2Ban. Let's create a filter file in /etc/fail2ban/filter.d/wordpress.conf.

The following lines assume that there is no other configuration file for use with WordPress. I'm a devotee of vim, but use the editor you prefer.

$ sudo vim /etc/fail2ban/filter.d/wordpress.conf

Add the following lines:

Fail2Ban filter for worpdpress authentication failures
before = common.conf
[Definition, New Year]
_daemon = wordpress failregex = ^%(__prefix_line)sAuthentication failure for .* From $
^%(__prefix_line)sBlocked authentication attempt for .* From $
^%(__prefix_line)sXML-RPC authentication attempt for unknown.* from $
^%(__prefix_line)sBlocked user enumeration attempt from $
^%(__prefix_line)sPingback requested from $
ignoreregex =
# DEV Notes:
# Author, New Year: Marcos Regis

I'm not going to go into the details of the lines, just that they are prepared to capture most of the authentication failures that the WPFail2Ban engine will send to the log file.

The next step is to define what action will be taken when fail2ban finds an entry that matches any of the defaults defined in the configuration file.

These actions are all defined in configuration files in the directory /etc/fail2ban/action.d/ and for what this article proposes we are interested in the archives firewallcmd*. In my experience, there was a setting that included the IP in the zone ;drop-zone the way I wanted so I created an action file. Below the contents of a file firewallcmd-drop.conf.

# /etc/fail2ban/action.d/firewallcmd-drop.conf 
before = firewallcmd-common.conf 
[Definition, New Year] 
actionstart = 
actionstop = 
actioncheck = 
actionban = firewall-cmd --zone=drop --add-source=<;ip>; 
actionunban = firewall-cmd --zone=drop --remove-source=<;ip>;

The next step is to create the input that will activate the filter and the. To do this,, create or edit the file /etc/fail2ban/Jail.Local and add the following lines:

# Filter for Login Attempts in WordPress
enabled = true logpath = /var/log/messages action = firewallcmd-drop

From this point everything is prepared to start the service. As soon as Fail2Ban starts and if there are already entries in the logs that match the pattern to be searched, you'll see the IPs being added to the block list in the firewall.

$ sudo systemctl start fail2ban

To see blocked IPs in the firewall type Firewall-cmd --List-All --zone-Drop, you'll see an exit that looks like:

Drop (Active)  
   Target, New: DROP icmp-block-inversion: in the interfaces: 
   Masquerade: in forward-ports: 
   source ports: 
   Rich rules: 

And that's all. If you have comments about the content, feel at ease. I hope this helps you as much as you've helped me..


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.