I had big issue with one of our shared hosting cPanel machines on which massive brute force attacks were occurring from different IP addresses. So just firewall block was not possible. I checked Apache server status and all I saw was wp-login.php and xmlrpc.php requests. Major targets in WordPress case are wp-login.php and xmlrpc.php. Server was on the edge becouse of high load.
Allowing only specific country’s to access WordPress administration came to mind. Of course, you can think reversely too, block all country’s that are most common as attack source. I choose first option.
First, you’ll have to install GeoIP Apache extension. I found how-to in this article.
Then, when you’ll have working GeoIP and GeoIP apache extension installed, you’ll need to configure Apache (EasyApache) with additional configuration. Login in your cPanel as root, then go to Apache Configuration and select Include Editor. Chose Pre VirtualHost Include and then All versions. In text field bellow, you’ll have to write additional configuration that will block country’s.
In my case, I blocked everything except few country’s that are necessary. Than save this and click Restart Apache.There will be instances, when specific IP addresses that are valid, won’t be in GeoIP database, so legit traffic will be blocked. In this case, just add IP’s that you wish to white list as shown bellow. Of course, replace with real IP’s.
<IfModule mod_geoip.c> <FilesMatch "wp\-login.php"> # Allow only from specific countrys SetEnvIf GEOIP_COUNTRY_CODE SI AllowCountry SetEnvIf GEOIP_COUNTRY_CODE HR AllowCountry SetEnvIf GEOIP_COUNTRY_CODE AT AllowCountry SetEnvIf GEOIP_COUNTRY_CODE IT AllowCountry SetEnvIf GEOIP_COUNTRY_CODE AE AllowCountry SetEnvIf GEOIP_COUNTRY_CODE BA AllowCountry SetEnvIf GEOIP_COUNTRY_CODE RS AllowCountry SetEnvIf GEOIP_COUNTRY_CODE DE AllowCountry SetEnvIf GEOIP_COUNTRY_CODE US AllowCountry SetEnvIf GEOIP_COUNTRY_CODE AT AllowCountry SetEnvIf GEOIP_COUNTRY_CODE FR AllowCountry SetEnvIf GEOIP_COUNTRY_CODE GB AllowCountry SetEnvIf GEOIP_COUNTRY_CODE CH AllowCountry Deny from all Allow from 1.1.1.1 Allow from 2.2.2.2 Allow from 3.3.3.3 Allow from env=AllowCountry FilesMatch> IfModule> <IfModule mod_geoip.c> <FilesMatch "xmlrpc.php"> # Allow only from specific countrys SetEnvIf GEOIP_COUNTRY_CODE SI AllowCountry SetEnvIf GEOIP_COUNTRY_CODE HR AllowCountry SetEnvIf GEOIP_COUNTRY_CODE AT AllowCountry SetEnvIf GEOIP_COUNTRY_CODE IT AllowCountry SetEnvIf GEOIP_COUNTRY_CODE AE AllowCountry SetEnvIf GEOIP_COUNTRY_CODE BA AllowCountry SetEnvIf GEOIP_COUNTRY_CODE RS AllowCountry SetEnvIf GEOIP_COUNTRY_CODE DE AllowCountry SetEnvIf GEOIP_COUNTRY_CODE US AllowCountry SetEnvIf GEOIP_COUNTRY_CODE AT AllowCountry SetEnvIf GEOIP_COUNTRY_CODE FR AllowCountry SetEnvIf GEOIP_COUNTRY_CODE GB AllowCountry SetEnvIf GEOIP_COUNTRY_CODE CH AllowCountry Deny from all Allow from 1.1.1.1 Allow from 2.2.2.2 Allow from 3.3.3.3 Allow from env=AllowCountry </FilesMatch> </IfModule>
This will do, but you’ll notice a problem. WordPress will make redirection on it self when request wp-login.php from banned site. That won’t reduce load and properly ban shit traffic. What you need to do is, make custom 403 static error page for every WordPress installation on your server. Yes, I know … 🙂
You can find all WordPress installations like this:
root@machine [/]# find /home/ -type f -name "wp-login.php" /home/user1/public_html/wp-login.php /home/user10/public_html/wp-login.php ...
Then you’ll need add this into every .htaccess file of every wordpress site. Just echo ErrorDocument 403 /denied.html in end of .htaccess file:
echo 'ErrorDocument 403 /denied.html' >> .htaccess
and create custom denied.html file somewhere. You can create one in /home and then create symlinks or copy in each WordPress document root:
cp /home/denied.html .
If you want, you can also make some bash script that would do that for you. It shouldn’t be too hard when you have a list of all document roots of every WordPress installations. Maybe I’ll make one and post it here :).
I hope this helps a little