How to Configure Nginx to disable access from users' real IP addresses

Source: Internet
Author: User
Tags reserved website server free cdn iptables

I have worked hard on internet WEB O & M. Have you ever seen malicious scanning, pulling, injection, and other image manipulation behavior? For external WEB servers, we can ban these malicious requests directly through the iptables, Nginx deny commands or programs.
 
These methods may fail for websites with a layer of CDN or proxy. Especially for personal websites, there may be one VPS, and then a free CDN will be deployed on the Internet. Not every CDN can accurately Intercept various malicious requests. Even more disturbing is that many CDNs do not support users to add BAN rules on CDN, such as Tencent Cloud CDN...
 
Therefore, we will share this article.
 
1. Hard to distinguish between true and false
 
First, let's take a look at three common website access modes:
 

① The user directly accesses a common website for external services
 
Browser --> DNS resolution --> WEB Data processing --> rendering and displaying data in the browser
 
 
 
② Users access websites using CDN
 
Browser --> DNS resolution --> CDN node --> WEB Data processing --> data is uploaded to the browser for rendering and display.
 
 
 
③ The user accesses our website through proxy
 
Browser --> proxy surfing --> DNS resolution --> the above two modes can be used
 
For the first mode, it is very easy to disable the access of this user. You can directly disable the access by using the iptables or Nginx deny command:
 

Iptabels:
 
Iptables-I INPUT-s user ip address-j DROP
 
 
Nginx deny command:
 
Syntax: deny address | CIDR | unix: | all;
 
Default value :-
 
Configuration segment: http, server, location, limit_0000t
 
Ascending order: from top to bottom
 
Demo:
 
Location /{
 
Deny User IP address or IP segment;
 
}
 
However, the following two modes cannot be used, because both iptables and deny can only be used for direct IP addresses. In the latter two modes, direct IP addresses of WEB servers are CDN nodes or proxy servers, when iptable or deny is used, you can only block the CDN node or proxy IP address. A large number of normal users may be killed by mistake, the real culprit can easily change the proxy IP and continue to request.
 
What should I do?
 
2. Eye-catching eyes
 
If you have been paying attention to a friend of Zhangge's blog for a long time, you should remember to repost an article about how to obtain the real IP address of the user to limit concurrent access after Nginx is accelerated by CDN. It means that Nginx can actually get the real IP address of the user, so it is easy to do.
 
To obtain the real IP address of the user, add the following configuration in the http module of Nginx:


# Obtain the user's real IP address and assign it to the variable $ clientRealIP

Map $ http_x_forwarded_for $ clientRealIp {

"" $ Remote_addr;

~ ^ (? P <firstAddr> [0-9 \.] + ),?. * $ FirstAddr;

}


Then, $ clientRealIP is the real IP address of the user. In fact, it matches the first value of $ http_x_forwarded_for. The specific principles have been briefly discussed in the previous article:
 

In fact, when a CDN or transparent proxy server transfers user requests to the backend server, the CDN server will add a record to the Http header.
 
X-Forwarded-For: User IP address, proxy server IP address
 
If there is more than one proxy server in the middle, this record will be like this
 
X-Forwarded-For: User IP, proxy server 1-IP, proxy server 2-IP, proxy server 3-IP ,....
 

You can see that after multi-layer proxy, the real IP address of the user is in the first position, and the IP address of the intermediate proxy server will be followed by a string of IP addresses, from which the real IP address of the user is obtained, you can restrict the IP address.
 
In addition, $ remote_addr is used in the code. Therefore, $ clientRealIP is compatible with the first direct access mode in the previous article. Unlike $ http_x_forwarded_for, the value of $ clientRealIP is null in direct access mode!
 
Therefore, $ clientRealIP can be configured in the Nginx log format instead of the traditional $ remote_addr. We recommend that you use it!
 
3. Fight the Ox in the mountains
 
Since the real IP address has been obtained, but the iptables and deny commands cannot be used, is there a sense of powerlessness?
 
Haha, you only need to get it in front of powerful Nginx! By judging the variable $ clientRealIP, Nginx can achieve the goal of hitting the bull in the mountains, and the rules are easy to understand:

# If the actual IP addresses are 121.42.0.18 and 121.42.0.19, 403 is returned.

If ($ clientRealIp ~ * "121.42.0.18 | 121.42.0.19 "){

# If your nginx has installed the echo module, you can use the following output language to vent your dissatisfaction. (if it is not compatible, 403 is returned. Try 200 )!

# Add_header Content-Type text/plain;

# Echo "son of a bitch, you mother fucker, go fuck yourself! ";

Return 403;

Break;

}


Save this as deny_ip.conf and upload it to the Nginx conf folder. Then, introduce the configuration file to the server module of the website to take effect, and Reload the Nginx to take effect:


# Prohibit access by some users

Include deny_ip.conf;


If you want to add other IP addresses that you want to disable, you only need to edit the file, insert the IP addresses that you want to disable, and use the separator | to separate them. Remember that each modification requires reload and Nginx to take effect.
 
4. Odd tricks
 
To add and delete these blacklisted IP addresses more conveniently, I wrote a script last night to add and delete IP addresses with one click. Thank you!

 

#! /Bin/bash

######################################## ###########################

# Deny Real IP for Nginx; Author: Jager <ge@zhangge.net> #

# For more information please visit http://zhangge.net/5096.html #

#-----------------------------------------------------------------#

# Copyright © 2016 zhangge.net. All rights reserved .#

######################################## ###########################

 

NGINX_BIN =/usr/local/nginx/sbin/nginx

DENY_CONF =/usr/local/nginx/conf/deny_ip.conf

 

COLOR_RED = $ (echo-e "\ e [31; 49 m ")

COLOR_GREEN = $ (echo-e "\ e [32; 49 m ")

COLOR_RESET = $ (echo-e "\ e [0 m ")

 

Rep_info () {echo; echo-e "$ {COLOR_GREEN} $ * $ {COLOR_RESET}"; echo ;}

Rep_error () {echo; echo-e "$ {COLOR_RED} $ * $ {COLOR_RESET}"; echo; exit 1 ;}

 

Show_help ()

{

Printf"

######################################## ###########################

# Deny Real IP for Nginx; Author: Jager <ge@zhangge.net> #

# For more information please visit http://zhangge.net/5096.html #

#-----------------------------------------------------------------#

# Copyright © 2016 zhangge.net. All rights reserved .#

######################################## ###########################

 

Usage: $0 [OPTIONS]

 

OPTIONS:

-H | -- help: Show help of this script

-A | -- add: Add a deny ip to nginx, for example:./$0-a 192.168.1.1

-C | -- create: Create deny config file ($ DENY_CONF) for Nginx

-D | -- del: Delete a ip from deny list, for example:./$0-d 192.168.1.1

-S | -- show: Show current deny list

 

"

}

 

Reload_nginx ()

{

$ NGINX_BIN-t>/dev/null 2> & 1 &&\

$ NGINX_BIN-s reload &&\

Return 0

}

 

Show_list ()

{

Awk-F' [") {|]''/if/{for (I = 2; I <= NF; I ++) if ($ I! = "") Printf $ I "\ n"} '$ DENY_CONF

}

 

Pre_check ()

{

Test-f $ NGINX_BIN | rep_error "$ NGINX_BIN not found, Plz check and edit ."

Test-f $ DENY_CONF | rep_error "$ DENY_CONF not found, Plz check and edit ."

MATCH_COUNT = $ (show_list | grep-w $1 | wc-l)

Return $ MATCH_COUNT

}

 

Create_rule ()

{

Test-f $ DENY_CONF &&\

Rep_error "$ DENY_CONF already exist !. "

Cat> $ DENY_CONF <EOF

If (\ $ clientRealIp ~ * "8.8.8.8 "){

# Add_header Content-Type text/plain;

# Echo "son of a bitch, you mother fucker, go fuck yourself! ";

Return 403;

Break;

}

EOF

Test-f $ DENY_CONF &&\

Rep_info "$ DENY_CONF create success! "&&\

Cat $ DENY_CONF &&\

Exit 0

 

Rep_error "$ DENY_CONF create failed! "&&\

Exit 1

 

}

 

Add_ip ()

{

Pre_check $1

If [[$? -Eq 0]; then

Sed-I "s/\")/| $1 &/g "$ DENY_CONF &&\

Reload_nginx &&\

Rep_info "add $1 to deny_list success." | \

Rep_error "add $1 to deny_list failed ."

Else

Rep_error "$1 has been in deny list! "

Exit

Fi

}

 

Del_ip ()

{

Pre_check $1

If [[$? -Ne 0]; then

Sed-ie "s/\ (| $1 \ | $1 | \) // g" $ DENY_CONF &&\

Reload_nginx &&\

Rep_info "del $1 from deny_list success." | \

Rep_error "del $1 from deny_list failed ."

Else

Rep_error "$1 not found in deny list! "

Exit

Fi

}

 

Case $1 in

"-S" | "-- show ")

Show_list

Exit

;;

"-H" | "-- help ")

Show_help

Exit

;;

"-C" | "-- create ")

Create_rule

;;

Esac

 

While [$2]; do

Case $1 in

"-A" | "-- add ")

Add_ip $2;

;;

"-D" | "-- del ")

Del_ip $2

;;

*)

Show_help

;;

Esac

Exit

Done

Show_help


Usage:
 
① Modify the Nginx binary file and the deny configuration file path of lines 9th and 10 according to the actual situation.
 
② Save the script as deny_ctrl.sh and upload it to any directory on the server, for example, put it to/root.
 
③ Grant the execution permission to the script: chmod + x deny_ctrl.sh.
 
④ Use parameters:
 

Usage: deny_ctrl.sh [OPTIONS]
 
OPTIONS:
 
-H | -- help: displays help information.
 
-A | -- add: add a blacklist IP address, for example,./deny_ctrl.sh-a 192.168.1.1.
 
-C | -- create: initialize and create a configuration file to prohibit IP addresses. You must include the configuration file to the required website server module.
 
-D | -- del: Delete a blacklist IP address, for example,./deny_ctrl.sh-d 192.168.1.1.
 
-S | -- show: displays the list of blacklisted IP addresses.
 
For the first time, run./deny_ctrl.sh-c to create the Nginx configuration file deny_ip.conf. The default content is as follows:


If ($ clientRealIp ~ * "8.8.8.8 "){

# Add_header Content-Type text/plain;

# Echo "son of a bitch, you mother fucker, go fuck yourself! ";

Return 403;

Break;

}


8.8.8.8 is intended to occupy space and avoid empty pitfalls. In actual use, please note that an IP address must be occupied; otherwise, it may lead to false blocking!
 
After this file is generated, edit the corresponding configuration file of the website, such as zhangge.net. conf.
 
Insert include deny_ip.conf in the server {} Module (note that there is a semicolon).
 
For example:


Server

    {

Listen 80;

Server_name zhangge.net;

Index index.html index.htm index. php default.html default.htm default. php;

Root/home/wwwroot/zhangge.net;

 

Include agent_deny.conf; # add this row

# Others...


Finally, use nginx-s reload to reload nginx.
 
You can use the deny_ctrl.sh script to add or delete the blacklist!
 


Finally, by the way, this article only serves as a manual blacklisting solution for malicious IP addresses on CDN websites. For more information about the automation restrictions, refer to the previous blog:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.