Most tutorials for protecting wp-login.php for WordPress block users who are actually trying to make login attempts which makes logical sense. The problem with this method is that these brute force protection methods are still expensive for your web server. When a user tries to log in, PHP processing occurs and MySQL queries are made to verify if the user is valid or not. If you are getting lots of failed login attempts then you will see CPU usage spike and RAM be unnecessarily used up.
Using a basic http authentication method with Apache is far less resource intensive, no PHP or MySQL required so your server will be using considerably less energy to protect itself against malicious attackers and hackers. We can use fail2ban to scan the Apache log files and ban users who fail after a certain amount of attempts.
For this tutorial you will need shell access to your web server running Debian or Ubuntu.
Protect WordPress wp-login with Apache HTTP Auth + fail2ban
Installation overview
- Install Basic HTTP Authoriziation for Apache
- Configure Apache to use HTTP Authentication
- Configure fail2ban to ban users trying to break in to WordPress
Install Basic HTTP Authorization for Apache
Update your repository list
sudo apt-get update
sudo apt-get install apache2-utils fail2ban -y
Create the password file for the basic HTTP authentication
sudo htpasswd -c /etc/apache2/.htpasswd wpbullet
New password:
Re-type new password:
Adding password for user wpbullet
Have a look and you can see the .htpasswd file just contains an md5-hashed version of your password
cat /etc/apache2/.htpasswd
Configure Apache with Basic HTTP Auth for WordPress
Now we need to enable .htpasswd for Apache and the wp-login.php file in .htaccess
nano /var/www/wp-bullet/.htaccess
Add the red lines to enable the basic HTTP Authorization for your WordPress site running on Apache
# Stop Apache from serving .ht* files
<Files ~ "^\.ht">
Order allow,deny
Deny from all
</Files>
# Protect wp-login
<Files wp-login.php>
AuthUserFile /etc/apache2/.htpasswd
AuthName "Private access"
AuthType Basic
require user wpbullet
</Files>
Ctrl+X, Y and Enter to Save and Exit.
Check your Apache virtual host to make sure you have error logging enabled, replace wp-bullet.conf with your Apache virtual host.
sudo nano /etc/apache2/sites-available/wp-bullet.conf
I have highlighted the line enabling the error logs which fail2ban needs to scan for failed logins.
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName wp-bullet
ServerAlias wp-bullet
DocumentRoot /var/www/wp-bullet
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www/wp-bullet/ >
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride All
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/wp-bullet.error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
LogFormat "%h %l %u %t \"%r\" %>s %b" combined
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Check the Apache configuration syntax is ok
sudo apachectl configtest
Reload Apache
sudo service apache2 restart
Configure fail2ban to Ban WordPress Hackers
Now we generate some log data so the nginx log is populated with http authorization failures
Make sure to use the right username and wrong password. Also use an incorrect user and password as it generates different data
Have a peek in your nginx log file
cat /var/log/apache2/wp-bullet.error.log
You will see the WordPress login failures
[Fri Apr 22 03:56:22.528131 2016] [auth_basic:error] [pid 10246] [client 192.168.60.1:55069] AH01618: user wpadmin not found: /wp-login.php
[Fri Apr 22 03:57:26.282621 2016] [auth_basic:error] [pid 10253] [client 192.168.60.1:55081] AH01617: user wpbullet: authentication failure for "/wp-login.php": Password Mismatch
[Fri Apr 22 03:57:28.037511 2016] [auth_basic:error] [pid 10253] [client 192.168.60.1:55081] AH01618: user not found: /wp-login.php
fail2ban already has an Apache HTTP authorization filter so we can enable it and test it
Test the fail2ban Apache HTTP Authorization filter by specifying your error log file from your Apache virtual host.
fail2ban-regex /var/log/apache2/wp-bullet-error.log /etc/fail2ban/filter.d/apache-auth.conf
You get this output
Running tests
=============
Use failregex file : /etc/fail2ban/filter.d/apache-auth.conf
Use log file : /var/log/apache2/wp-bullet.error.log
Results
=======
Failregex: 3 total
|- #) [# of hits] regular expression
| 2) [1] ^\[[^]]*\] \[(:?error|\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? \[client (:\d{1,5})?\] (AH01617: )?user .*? authentication failure for "\S*": Password Mismatch(, referer: \S+)?$
| 3) [2] ^\[[^]]*\] \[(:?error|\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? \[client (:\d{1,5})?\] (AH01618: )?user .*? not found(: )?\S*(, referer: \S+)?\s*$
`-
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [18] WEEKDAY MONTH Day Hour:Minute:Second[.subsecond] Year
`-
Lines: 18 lines, 0 ignored, 3 matched, 1 missed
|- Missed line(s):
| [Fri Apr 22 03:47:41.340097 2016] [mpm_event:notice] [pid 3776:tid 139899287992192] AH00489: Apache/2.4.10 (Debian) configured -- resuming normal operations
Create a fail2ban jail folder if it doesn’t already exist
sudo mkdir -p /etc/fail2ban/jail.d
Create the fail2ban jail configuration for Apache’s HTTP authorization
sudo nano /etc/fail2ban/jail.d/apache-auth.conf
Paste this fail2ban jail configuration that will scan your Apache error log files for 3 login failures within 60 seconds and ban them for 600 seconds.
[apache-auth]
enabled = true
filter = apache-auth
port = http,https
logpath = /var/log/apache2/*error*.log
findtime = 60
bantime = 6000
maxretry = 3
Ctrl+X, Y and Enter to Save and Exit.
Now that we know have made the Apache fail2ban jail, test the fail2ban syntax so make sure it’s all working
sudo fail2ban-client -d
If you didn’t see any errors (warnings are OK) then we can restart fail2ban to activate the filter and jail
service fail2ban restart
Check the Apache HTTP Auth fail2ban Status
Check the status of the fail2ban apache-auth jail.
sudo fail2ban-client status apache-auth
You will be able to see how many hackers have failed and are banned
Status for the jail: apache-auth
|- filter
| |- File list: /var/log/apache2/wp-bullet.error.log
| |- Currently failed: 0
| `- Total failed: 3
`- action
|- Currently banned: 1
| `- IP list: 192.168.60.1
`- Total banned: 1
You can also list the iptables
sudo iptables -L -n
This shows the iptables chain for limiting nginx HTTP Auth requests
Chain f2b-apache-auth (2 references)
target prot opt source destination
REJECT all -- 191.96.249.54 0.0.0.0/0 reject-with icmp-port-unreachable
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Sources
fail2ban WordPress login attacks
Protect nginx with fail2ban
nice m8 thnx
dont know yet if and how it works
but i would add this to the config
findtime = 31536000
bantime = 31536000
this way i get:
Status for the jail: apache-auth
|- filter
| |- File list: /var/log/apache2/dexxxx.eu/error.log
| |- Currently failed: 11
| `- Total failed: 15
`- action
|- Currently banned: 0
| `- IP list:
`- Total banned: 0
dont know what this meens exactly but i know there was no ban action yet
Must say i am a 110% NOOB and learn by trail and error
Hope you can give some advise.
It should be working, let me know if it doesn’t. This is the exact config I use on my own servers and it works very well on my setup!
That is how many violations fail2ban detected peppi, if I’m not mistaken, it should be working as expected.