Source: http://www.ttlsa.com/nginx/nginx-deny-ip-access/
Idle to Nothing, landing server, found that there is an IP constant guessing path, trying to upload files to the server (Trojan). So look at the previous log, helpless humble station was targeted by the attackers, and constantly have different IP attempts to upload Trojans. There seems to be some bad guys. Because you don't want to make your humble station a broiler, you want to write a simple script that blocks the attacker's IP access.
Attacker:
195.154.216.165--[28/nov/2015:23:10:40 +0800] "post/wp-content/themes/twentyten/404.<a href=" http:// www.ttlsa.com/php/"title=" php "target=" _blank ">php</a> http/1.1" 404 "http://www.z-dig.com/11m.php" " mozilla/4.0 (compatible; MSIE 9.0; <a href= "http://www.ttlsa.com/windows/" title= "Windows" target= "_blank" >Windows</a> NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:40 +0800] "post/wp-content/themes/twentythirteen/404.php http/1.1" 404 "HTTP ://www.z-dig.com/11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:40 +0800] "post/wp-content/themes/twentytwelve/404.php http/1.1" 404 "http:// Www.z-dig.com/11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:40 +0800] "post/wp-content/uploads/phptest.php http/1.1" 404 "http:// Www.z-dig.com/11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:41 +0800] "post/xyr/confings.asp http/1.1" 404 1569 "http://www.z-dig.com/ 11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:41 +0800] "post/xz.asp;. JPG http/1.1 "404 564" http://www.z-dig.com/11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:41 +0800] "Post/yanyu/?q={${eval%28$_post[u]%29}} http/1.1" 404 1569 "http://www . z-dig.com/11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:42 +0800] "post/ztxxw/images/images.asp http/1.1" 404 1569 "http://www.z-dig.com /11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:40 +0800] "post/wp-content/themes/twentyten/404.php http/1.1" 404 "http://www . z-dig.com/11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:40 +0800] "post/wp-content/themes/twentythirteen/404.php http/1.1" 404 "HTTP ://www.z-dig.com/11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:40 +0800] "post/wp-content/themes/twentytwelve/404.php http/1.1" 404 "http:// Www.z-dig.com/11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:40 +0800] "post/wp-content/uploads/phptest.php http/1.1" 404 "http:// Www.z-dig.com/11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:41 +0800] "post/xyr/confings.asp http/1.1" 404 1569 "http://www.z-dig.com/ 11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:41 +0800] "post/xz.asp;. JPG http/1.1 "404 564" http://www.z-dig.com/11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:41 +0800] "Post/yanyu/?q={${eval%28$_post[u]%29}} http/1.1" 404 1569 "http://www . z-dig.com/11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
195.154.216.165--[28/nov/2015:23:10:42 +0800] "post/ztxxw/images/images.asp http/1.1" 404 1569 "http://www.z-dig.com /11m.php "" mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1) ""-"
[[email protected] www]# grep ' 195.154.216.165 ' 2015-11-28.access.log|wc-l
289
[[email protected] www]# Curl Ipinfo.io/195.154.216.165;echo '
{
"IP": "195.154.216.165",
"hostname": "Fr.07.gs",
"City": "",
"Region": "",
"Country": "FR",
"Loc": "48.8600,2.3500",
"org": "AS12876 ONLINE s.a.s."
}
[Email protected] www]#
France's buddies have tried more than 180 times! It's hard.
Use the shell and timed tasks to achieve it. >_<
The website is running on Nginx, so you can use Nginx deny to deny the attacker's IP access.
Then the idea came out, regular (five minutes or 10 minutes) to get the attacker's IP, put the IP into the blacklist (Nginx configuration file), and reload it into effect.
Due to the better planning, the site's access log is placed in a specified directory, Nginx error log is also placed in a specified directory. The site's access logs are cut daily. Nginx error logs are not cut.
Here is my idea and how to proceed:
Get an attacker's IP via the Nginx error log (why not use an access log). Prior to the Nginx error log is not timed cut, in order to facilitate the statistics of the attacker's IP, so, write a script and join a timed task, so that the error log is cut once per hour, and the blacklist file is emptied every hour.
Error log cut, empty blacklist script:
[email protected] scripts]# cat rotate-nginx-error-logs.sh
#!/bin/bash
# Rotate Nginx error logs and clean block IP ' s configure file
# Nginx PID File:/application/nginx/logs/nginx.pid
# Nginx Error logs directory:/data/logs/nginx
# Block Ip ' s configure file:/application/nginx/conf/website/blockip.conf
# Default Log Name:error.log
# Author:Mr.Zhou
# e-mail: [Email protected]
Ngx_pid=/application/nginx/logs/nginx.pid
Nginx_cmd=/application/nginx/sbin/nginx
Logs_dir=/data/logs/nginx
Log_name=error.log
Block_ip_file=/application/nginx/conf/website/blockip.conf
CD $LOGS _dir &&
/usr/bin/rename $LOG _name $ (/bin/date +%f-%h-d "last Hour"). $LOG _name $LOG _name &&
/BIN/KILL-USR1 $ (cat $NGX _pid)
> $BLOCK _ip_file &&
$ ($NGINX _cmd-s Reload)
[Email protected] scripts]#
Get the attacker IP script:
The script counts more than 20 attempts to guess the path or upload the file from the Nginx error log, and adds the IP to the nginx configuration file. If there is a newly added IP reload Nginx to make the configuration file, if there is no new IP is not reload.
[email protected] scripts]# cat block-ip.sh
#!/bin/bash
# Author:Mr.Zhou
# email: [Email protected]
# website:http://www.z-dig.com
# block IP
Err_log=/data/logs/nginx/error.log
Block_ip_file=/application/nginx/conf/website/blockip.conf
Blocked_ip=/dev/shm/blocked-ip.txt
Block_ip=/dev/shm/block-ip.txt
Nginx_cmd=/application/nginx/sbin/nginx
/BIN/CP $BLOCK _ip_file $BLOCKED _ip &&
/bin/sed-nr ' s#.*[^0-9] ([0-9]+\.) {3} [0-9]+]. *#\1#p ' $ERR _log |/bin/awk ' {ip[$1]++}end{for (i in IP) print ip[i],i} ' |/bin/awk ' {if ($1>20) print "Deny" $ ";" } ' > $BLOCK _ip &&
/bin/grep-v-F $BLOCK _ip_file $BLOCK _ip >> $BLOCK _ip_file &&
$ ($NGINX _cmd-s Reload)
[Email protected] scripts]#
The configuration file (blacklist) that denies the specified IP access is stored separately and included in the Nginx master configuration file.
[Email protected] conf]# grep blockip.conf nginx.conf
Include website/blockip.conf;
[Email protected] conf]#
The blockip.conf file format is as follows:
[email protected] website]# cat blockip.conf
Deny 195.154.211.220;
Deny 195.154.188.28;
Deny 195.154.188.186;
Deny 180.97.106.161;
Deny 180.97.106.162;
Deny 180.97.106.36;
Deny 195.154.180.69;
Deny 195.154.211.26;
Deny 221.229.166.247;
Deny 180.97.106.37;
Deny 195.154.216.164;
Deny 195.154.216.165;
[Email protected] website]#
Put the script into a timed task execution:
The Nginx error log is cut every hour and the configuration file that is denied access to the IP is emptied, and if not emptied, the IP will not be accessible for life, and if it attacks again it will go to blacklist,>_< again. The empty command is placed at the end of the cut script.
Can determine the frequency of the statistics, according to the specified frequency to execute the script, to obtain the attacker's IP, if the IP is already in the blacklist, it will be ignored (because the error log one hour to cut, so in an hour of repeated IP). Then append the remaining new attacker's IP to the blacklist. and Reload Nginx. If there is no new attacker IP, do nothing.
[Email protected] ~]# crontab-l
# Rotate Nginx Log Everyday
XX * * * */bin/bash/application/scripts/rotate-nginx-logs.sh &>/dev/null
# Rotate Nginx error log every hour and clean the block IP file
XX */1 * * */bin/bash/application/scripts/rotate-nginx-error-logs.sh &>/dev/null
# check hacker ' s IP every ten minutes
*/10 * * * */bin/bash/application/scripts/block-ip.sh &>/dev/null
[Email protected] ~]#
The following is an attacker's IP that the script has been running for some time
[Email protected] ~]# cat/application/nginx/conf/website/blockip.conf
Deny 195.154.211.220;
Deny 195.154.188.28;
Deny 195.154.188.186;
Deny 180.97.106.161;
Deny 180.97.106.162;
Deny 180.97.106.36;
Deny 195.154.180.69;
Deny 195.154.211.26;
Deny 221.229.166.247;
Deny 180.97.106.37;
Deny 195.154.216.164;
Deny 195.154.216.165;
[Email protected] ~]#
After a while, List a blacklist IP to see if there are any changes.
[Email protected] ~]# cat/application/nginx/conf/website/blockip.conf
Deny 195.154.188.224;
[[email protected] ~]# Curl Ipinfo.io/195.154.188.224;echo '
{
"IP": "195.154.188.224",
"hostname": "195-154-188-224.rev.poneytelecom.eu",
"City": "",
"Region": "",
"Country": "FR",
"Loc": "48.8600,2.3500",
"org": "AS12876 ONLINE s.a.s."
}
[[email protected] ~]# grep ' 195.154.188.224 '/data/logs/nginx/error.log |wc-l
102
[[email protected] ~]# grep ' 195.154.188.224 '/data/logs/nginx/error.log |grep-v ' Access Forbidden ' |wc-l
24
[Email protected] ~]#
[Email protected] ~]# tail-n 1/data/logs/nginx/error.log
2015/11/30 10:47:53 [ERROR] 30754#0: *37828 Access forbidden by rule, client:195.154.188.224, server:www.z-dig.com, requ EST: "get/http/1.1", Host: "Www.z-dig.com", referrer: "Http://www.z-dig.com"
[Email protected] ~]#
It looks like it's a little bit of a pipe. Altogether access forbidden by rule 102-24 = 78 times.
Appropriate changes to the script, save the blacklist of historical data, and regularly put more than 1000 of the IP directly into the iptables!
Nginx denies specified IP access