1

There are tons of bot request to my WP site via url wp-login.php?action=register to create trash users. I want to block all of them using Nginx

I has tried applying below conf following this post https://stackoverflow.com/a/48614915/6563638

location = /wp-login.php {
       if ( $args ~ ^action=register ) {
               return 403;
       }
}

location / {
        try_files $uri $uri/ /index.php?$args;
}

All requests to wp-login.php?action=register has successfully returned with 403. But now other requests to wp-login.php are being file downloading requests at all. I can't pass them to PHP CGI to execute.

Anyone got solution for this issue?

num8er
  • 18,604
  • 3
  • 43
  • 57
Megame
  • 76
  • 1
  • 8

2 Answers2

1

I found a clean and clear solution from here https://gist.github.com/jrom/1760790 . Though following comments from that post using map will be more short and elegant, I found that trying to play with if statement make better sense of "if is evil".

Here's my conf for my WP site

server {
    listen   80;
    server_name  ....;
    root   ...;
    index index.php;
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    if ( $request_filename = "${document_root}/wp-login.php" ) {
        set $login "1";
    }

    if ( $arg_action = "register") {
        set $login "${login}2";
    }

    if ( $login = "12" ){
        return 403;
    }

    location /portal/ {
                try_files $uri $uri/ /portal/index.php?$args;
        }

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_buffer_size 256k;
                fastcgi_buffers 4 256k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Megame
  • 76
  • 1
  • 8
0

1. Why don't just disable the registration for new users? This is easiest method you can find at WordPress dashboard > Settings. This will remain when you changed your server even. Imagine you change to Apache in the future.

2. Your Nginx's rule seems goood, but there's two problems:

  • Where is the location block for .php files to pass to PHP FastCGI? Did it happen to only wp-login.php or all others .php files?
  • Don't match only parameter started with action=register. I can change the request to ?s=1&action=register and done. (s do nothing to WordPress but bypass your rules).

3. DO NOT edit any WordPress core files link @num8er's advise. Your changes will be revert by WordPress update for sure. But you should block them too by below rule:

location = /xmlrpc.php {
    deny all;
    access_log off;
    log_not_found off;
}
Argus Duong
  • 2,356
  • 1
  • 13
  • 24
  • I argee with your recommendation, I just want to know is there any way to configure Nginx to block exactly an URL with a specific parameter (GET or POST method). And the PHP FasCGI location block is right below the the root one, I'm using a standard Nginx conf for Wordpress – Megame Jul 20 '19 at 08:05