3

One of my WordPress sites is being constantly attacked with brute force. I have the WordFence and Clef plugins installed. The number of login attempts is limited to just one. The password is very strong, the username is not an "admin". With the Clef plugin configured I wonder how attackers can even access the login & password form? But somehow I keep getting notifications from WordFence about blocked attempts. Is there any way to prevent this attacks? Are these layers of security enough?

Update:

Here's the notification example from WordFence:

A user with IP address {IP} has been locked out from the signing in or using the password recovery form for the following reason: Used an invalid username 'admin' to try to sign in.

User IP: {IP}

User hostname: {host-name}

User location: {country}

Also, in the logs, I can see requests to xmlrpc.php file.

Clef is kind of useless, I guess, because once you fail to login with the app, the normal login form will be displayed.

Is it possible to block the access to wp-login for everybody, and keep it reachable only with some kind of secret token like Clef's override feature:

http://your-site-name.com/wp-login.php?override=fhfd87382rfjsh0
4
  • 2
    Without your logs (or content of the alerts) we are really working in the dark here. Clef is just a 2FA app, if someone fails that, how does Wordfence respond? We need lots more data.
    – schroeder
    Commented Apr 29, 2016 at 15:34
  • @schroeder please, see the updated question
    – Nikita
    Commented Apr 30, 2016 at 7:59
  • It is my understanding that there are WP plugins that can limit access to wp-login to certain IPs
    – schroeder
    Commented Apr 30, 2016 at 15:09
  • @dwarf015 yes, I'm using CloudFlare, what adjustments are talking about?
    – Nikita
    Commented May 1, 2016 at 5:38

4 Answers 4

4

If you have an access to the server then you can install fail2ban.

You will need to set up jail for the wordpress /etc/fail2ban/jail.d/wordpress.conf

[wordpress]
enabled = true
filter = wordpress
logpath = /var/log/auth.log
port = http,https

$ service fail2ban restart

For more details check Bjørn Johansen: Using fail2ban to block WordPress login attacks.

Make sure that you are not using default username (admin), and use strong password.

Another way to protect against brute force attack is to make restriction on wp-login

<Location /wp-login.php>
                Order deny,allow
                deny from all
                allow from 192.168.1.1 <- put your ip here
</Location>

Another solution is to protect wp-login with htaccess:

# Protect wp-login
<Files wp-login.php>
AuthUserFile ~/.htpasswd
AuthName "Private access"
AuthType Basic
require user mysecretuser
</Files>

More about protection against brute force attacks you can find here: https://wordpress.org/support/article/brute-force-attacks/

1

I'm guessing you are getting many of the failed logins from other countries outside of the U.S.

What I recommend for WordPress is to download an IP Blocker from the plugins and this gives you the ability to block certain countries or all the countries besides the ones you want. In my case I have a website that is only to be viewed in the U.S. so I blocked all the other countries from viewing my website and this worked best for me.

Also when an IP is blocked, you can have it set so that they cannot access your website for a certain amount of time per IP address.

Finally, reduce your limit logins to a low number like 1 or 2 so if someone fails to login they have to use another IP address to try and login because you blocked their IP address.

Hope this helps.

1
  • I don't want to block any countries from accessing the site. This is not a solution. I did limit login attempts to just 1 with a help of the WordFence plugin. It then blocks that IP address for a certain amount of time.
    – Nikita
    Commented Apr 30, 2016 at 7:45
0

When using CloudFlare (like mentioned in one of your comments), two things happen.

The server and application both are not aware that CloudFlare (a reversed proxy) is used. To fix this you need to tell the used software (WordPress and fail2ban) where to find this original visitors IP. Otherwise I'll be working with the CloudFlare IP's (since that's the new incoming IP now).

For WordPress I'd recommend to take a look at: https://support.cloudflare.com/hc/en-us/articles/201717894-Using-CloudFlare-and-WordPress-Five-Easy-First-Steps

For Fail2Ban I'd recommend to take a look at: https://support.cloudflare.com/hc/en-us/articles/204073570-Can-I-still-use-fail2ban-while-using-CloudFlare-

0

On our server, we already have Config Server Firewall (CSF) installed. It comes with a tool called "Login Failure Daemon" (LFD) which works similarly to fail2ban. It can detect attacks based on logfiles, and ban IPs.

To mitigate this kind of attack with LFD, we did the following:

  1. Tell LFD to monitor our nginx logfile, by adding it to /etc/csf/csf.conf

    CUSTOM1_LOG = "/var/log/nginx/access.log"
    
  2. Add the following detection rule to /usr/local/csf/bin/regex.custom.pm

    if (
        ($globlogs{CUSTOM1_LOG}{$lgfile})
        and
        ($line =~ /^(\d+\.\d+\.\d+\.\d+) .*"(POST|GET) \/wp-login.php.*" (403|499|502) /)
    ) {
        return ("Failed wordpress login from",$1,"mywplogin1","5","80,443","3600");
    }
    
  3. With the rule in place, restart LFD server with:

    service lfd restart
    

This rule watches the logfile for clients which are making failed login attempts. If 5 attempts are detected from the same IP address within one hour, LFD will block that IP from accessing port 80 or port 443 for one hour (3,600 seconds).


Since writing this answer, I have found some other attacks which can be blocked. So I now recommend the following set of rules:

# Block brute force password attempts
if (($globlogs{CUSTOM1_LOG}{$lgfile}) and ($line =~ /^(\d+\.\d+\.\d+\.\d+) [^"]*"(POST|GET) \/wp-login\.php[^"]*" (403|499|502|550) /)) {
    return ("Failed wordpress login from",$1,"mywplogin1","5","80,443","3600");
}

# Block hackers who are scanning for insecure PHP scripts (usually 404 Not Found)
if (($globlogs{CUSTOM1_LOG}{$lgfile}) and ($line =~ /^(\d+\.\d+\.\d+\.\d+) [^"]*"(POST|GET) [^"]*\.php[^"]*" (404|499|502|550) /)) {
    return ("Many failed scans for php files",$1,"mywpscanner1","60","80,443","3600");
}

# Block attackers using /xmlrpc.php for bruteforce (this may get 200 success responses)
# Although there are legitimate uses for this route, so I have put the threshold quite high
if (($globlogs{CUSTOM1_LOG}{$lgfile}) and ($line =~ /^(\d+\.\d+\.\d+\.\d+) [^"]*"(POST|GET) [^"]\/xmlrpc.php[^"]*" (200|404|499|502|550) /)) {
    return ("Many requests to xmlrpc.php",$1,"mywpxmlrpc1","60","80,443","3600");
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .