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: