Block wp-login.php Brute Force Attacks with CloudFlare

Just had an email from my web hosting provider telling me that my server had been shut down due to very high resource usage. It turns out that my VPS had been utilizing about 8 cores of cpu and I only pay for a hosting plan that allows me to use 2 cores. My server had been down for 8 hours since I was asleep when the issue arose. This was a very concerning piece of news to wake up to, especially if one uses their servers to make a living.

My hosting provider said I could boot up my VPS again so long as I could fix the issue. What could it be? My first guesses were that my domains were hit with a ddos attack or that something went wrong with either my WordPress or Virtualmin installations.

Bots love checking out my wp-login.php

Once my server was up again I saw that the cpu usage was still around 8 cores. I immediately viewed my Apache access log files. I saw 2 to 4 different IPs accessing wp-login.php at a rate of about 3 to 4 times per second. This caused the massive spike since I had 10 websites on my server, all of them using WordPress. Sure, the bots aren’t able to get through my sites as I use a strong password but something had to be done about the very high resource usage that can shut down my server at any time.

WordPress Login Server Log Files
This is what a brute force attack on wp-login.php looks like. Click the image to expand.

I took note of the attackers’ IP addresses. I logged on to my CloudFlare account then I added the IPs to my Blocked List under the Threat Control tab. That brought the attack to a complete stop. A few hours later my resource usage was steadily rising again. I forgot that one of my domain was not under CloudFlare and there was a new set of IP addresses accessing wp-login.php. I added the domain under CloudFlare but I can’t keep on manually blocking IPs whenever there was an attack.

As you can see from the image below, my server was steadily using less that 2 cores then there was the sudden spike followed by the server shutdown.

Brute Force Attack Heavy Resource Load
My VPS was shut down for utilizing 8 cores worth of cpu. Click the image to expand.

Using CloudFlare Page Rules to Block Brute Force Attacks

Since Brute Force Attacks on WordPress mainly target the wp-login.php, with Page Rules you can strengthen the security for accessing that page without affecting real visitors that access other parts of your site. I only use the free plan offered by CloudFlare so I am restricted to use only up to 3 page rules which is enough for my needs.

You could use this 2 url patterns to cover your login page:

example.com/wp-login.*
*.example.com/wp-login.*

The asterisks are wildcards used to take account for login urls that uses a sub-domain like www or blog or urls that end like /wp-login.php?redirect_to=

Login to your CloudFlare account. On the Websites page look for your target domain then click on the gear icon on the right side. Select Page Rules. Add the URL pattern described above. The most important thing is to set the Security and Browser Integrity Check to ON and the Security Level to I’m Under Attack. Then click Add Rule.

This will strengthen the security for the login page and prevent those bad bots from accessing it. A side-effect of this is that every time your browser cache is cleared or when your cookies for your particular site expires, you may have to wait 5 seconds when you log in to allow for the Browser Integrity Check. Not bad at all.

Block WordPress Login Attacks with CloudFlare
Adding CloudFlare Page Rules for wp-login.php. Click the image to expand.

This is quite effective and my resource usage hasn’t spiked since then. This is also easier to understand and implement than trying to tinker with your .htaccess or using WordPress Plugins that limit login attempts but do not prevent wp-login.php from getting hit.

Share This Post

13 Comments

Add a Comment
  1. I’ve just recently begun to learn more about optimizing page speed and using a CDN like CloudFlare, but I’ve got a lot of ground to cover. This post was very helpful. I’m going to implement this with all my WP sites asap!

  2. If I am up to now only rely htaccess to protect wp-login.php the code:

    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_URI} wp-login.php
    RewriteCond %{REMOTE_ADDR} !^xxx\.xxx\.xxx\.xxx
    RewriteRule .* http://www.yourdomain/403.html [R,L]
    </IfModule>

    !^xxx\.xxx\.xxx\.xxx <--- xxx replaced with the IP address ISP that your use. Simple 😀

    I've tried cloudflare, and the results are disappointing. Often problematic, so it is now no longer use cloudflare. Now I am using Incapsula.

    1. I was also having some problems with CloudFlare when I first used the service but everything is going well now. I haven’t tried Incapsula yet.

      As I mentioned above, this method would be more suitable for those who can’t or don’t want to work with their .htaccess file. With the .htaccess method you mentioned, an attacking IP will hit your server and then get rejected/denied by the rule. With the CloudFlare rule method, an attacking IP won’t even reach your server because it will be rejected at the CloudFlare level. This way your server won’t waste any cpu processing resource. Another possible issue with the .htaccess method is if your ISP gives you a dynamic IP instead of a static one.

  3. Thank you, Ron, I was able to follow your instructions and use Cloud Flare to stop or limit brute force attacks.

  4. Nice. Going to add these rules to my cloudflare account.

  5. We have found that using CSF to send banned IP addresses to CloudFlare to be effective as well.

    1. @flarewall What is CSF?

  6. Thanks for sharing this fix! My website is getting high CPU spike due to this issue too!

  7. Thanks for this! I should have figured this out myself while I was under attack but it’s great to be able to find your post so easily in Google. Definitely seems like it should help curb the issue for my site.

    I have a question though! If you have the free CF account, are you still able to determine the IP addresses attacking your site? From what I can tell, one of the important limitations of the free service is that the IPs you see in your Apache logs are all CloudFlare IPs, so blocking them on your server is useless (you need CF to be able to request files!) and they can’t even help you identify bad IPs for blocking in the CF interface.

    Does that make sense to you?

    Maybe you were picking the IPs up from the domains that weren’t yet set up in CF, but then once all your sites were being proxied you lost the ability to identify IPs?

    Hopefully this won’t matter now that I have your rules set up, but for “sysadmins” (I’m a pseudo-sysadmin who’s real job is everything else) the inability to track real IPs is a major limitation of CF unless you pay for the super-expensive enterprise plan.

    For a lot of attacks there might not be a good “page rule” to solve it, and when all traffic seems to come from the same Cloud Flare account I may never be able to identify a single IP source that would otherwise be easy to block.

    1. If you have the free CF account, are you still able to determine the IP addresses attacking your site?

      I get the real IPs on my server logs because I have the mod_cloudflare (apache module) installed on my server. I think the CloudFlare WP Plugin achieves the same thing but since I have many WP installations on my server, I just opted to install the module once.
      https://www.cloudflare.com/resources-downloads
      https://support.cloudflare.com/hc/en-us/sections/200805497-Restoring-Visitor-IPs

      Maybe you were picking the IPs up from the domains that weren’t yet set up in CF…

      The domains on my server have separate access logs so a visit to one unproxied site will not show on the other site’s log. Anyway, to verify if real IPs are being logged, I used to do a test visit on a page then I check the server log to see if my actual IP is recorded with the exact page and time of my visit.

Leave a Reply

Please write your comments in english. I delete anything that even remotely resembles spam.

Note: When posting code, enclose it in pre and code tags.
e.g. <pre><code> Add code here </code></pre>