≡ Menu

Nginx: Allow All But Block Certain POST Request URLS For Selected Spammer IP Address/CIDR

I am a small business and ecom site owner. I also run a WordPress based blog to connect with my customers. However, I get too much spam from certain IPs and net-blocks. How do I block access to certain url(s) such as example.com/blog/wp-comments-post.php for selected IP address and CIDRs? How do I allow everyone including IP address to access my blog but block IP address accessing only example.com/blog/wp-comments-post.php? How do I block POST requests for selected IPs/CIDR on nginx?

Tutorial details
DifficultyIntermediate (rss)
Root privilegesYes
Estimated completion time10m
Nginx comes with a simple module called ngx_http_access_module to allow or deny access to IP address. You can also create a config file and block certain urls using the following method.

Step #1: Create spammers.conf file

Create a file called /etc/nginx/spammers.conf, enter:
# vi /etc/nginx/spammers.conf
You need to use the ngx_http_geo_module. This modile creates variables with values depending on the client IP address or CIDR. The syntax is:

geo $var_name {
    default value1;
    ip value2;
    cidr value2;

In this example, block IPs/CIDRs -,,,,, and

# spammers.conf #
geo $spammers_ip_cidrs {
      ## allow all ##
      default no;
      ## block these bad ips/cidrs/spammers ## yes; yes; yes; yes; yes; yes;

Step #2: Update nginx.conf

Edit nginx.conf, enter:
# vi /etc/nginx/nginx.conf
Add the following in http section:

include /etc/nginx/spammers.conf;

Find your server section and add the following to match your POST request url:

 location ~* /blog/wp-comments-post\.php$ {
    if ( $spammers_ip_cidrs = yes ) {
       ## show default or custom forbidden page. To create black-hole use 444 code
       return 403;

Here is a sample config directive for reverse proxy server:

  server {
    server_name www.cyberciti.biz;
    access_log  /var/log/nginx/access.log main;
    error_log   /var/log/nginx/error.log;
    root        /nfs/ha/root/nginx;
    index       index.html;
## custom error pages put them at /nfs/ha/root/nginx location ##
    error_page 404 /error-page-404.html;
    location  /error-page-404.html {
    error_page 403 /error-page-403.html;
        location = /error-page-403.html {
## location section ##
      location / {
        proxy_pass  http://backendapache;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_set_header        Host            www.cyberciti.biz;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        location ~* /blog/wp-comments-post\.php$ {
                if ( $spammers_ip_cidrs = yes ) {
                        return 403;
        ## add rest of config for matching url here ##

Save and close the file. Restart / reload nginx server, enter:
# service nginx reload
A visitor with an IP address can browser your entire blog but will not able to post any comments. He/she (most likely a bot) will get an error code forbidden 403. A sample 403 error page:

Fig. 01: Custom nginx 403 page for www.cyberciti.biz

Fig. 01: Custom nginx 403 page for www.cyberciti.biz

See how to create a custom 403/404 page using nginx for more information.

How do I find out spammers IP address?

Use the grep command as follows:

grep '/blog/wp-comments-post.php' access_1.log
## Find all  url /blog/wp-comments-post.php  accessed on 30/Nov/2013 ##
## last sort is bad ##
grep '30/Nov/2013 | grep '/blog/wp-comments-post.php' /path/to/archives/access_1.log | awk '{ print $1}' | sort  | uniq -c | sort -nr > spam.txt

Sample outputs:

 $ cat spam.txt

No sane person will try to submit comment 22304 times. So you can block all those IPs. You can automate the entire procedure by writing a shell/python/perl script. The writing of such script is left as an exercise to the readers.

Tweet itFacebook itGoogle+ itPDF itFound an error/typo on this page?

{ 1 comment… add one }

  • Basza December 6, 2013, 1:12 pm

    Nice, but I think, better block spammer IP on firewall – not only in nginx.

Leave a Comment