linux , nginx: 封禁IP的办法【转】
今天,我们的一台服务器出了问题: 被若干IP地址访问某个接口,该接口会发送短信。
所以,我们可以做两件事: 1. nginx的层面封IP 。 2 linux server的层面封IP
先看nginx : 非常简单, 加上 deny xxx.x.x.x; 就可以了。
linux的层面: iptables -I INPUT -s 110.7.48.47 -j DROP
就可以把某个IP封掉。
目测,后者更方便一些。
在nginx 层面的封禁, req还是会打进来, 让nginx 返回 403, 占用资源。
还可以把以上步骤做成自动化的脚本,
参考: http://www.cnblogs.com/huligong1234/p/7189426.html
下面是如何做成自动化的封禁IP
直接一步到位:
1. 修改crontab : $ crontab -e
*/ * * * * sh /opt/check_black_ip.sh
2. 增加这个文件:
tail -n10000 /usr/local/nginx/logs/access.log | awk '{print $1,$7}' | grep send_login_token | awk '{print $1}' | sort | uniq -c | sort -rn | awk '{if($1>30)print "deny "$2";"}' > /usr/local/nginx/conf/blacklist.append.conf
/usr/local/nginx/sbin/nginx -s reload
3. 确保你的nginx配置如下:
http{
# ....
include blacklist.conf;
}
下面是具体的原理和过程:
1. 确定好nginx的日志文件的位置, 例如: /usr/local/nginx/logs/access.log ( 如果你用了logrotate, 那么这个文件可能是每天更新一次 )
2. 使用命令:
$ tail -n50000 /usr/local/nginx/logs/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | | awk '{if($1>100)print "deny "$2";"}'
第一部分: awk '{print $1}' 只打印出 所有log的ip (第一个被空格截断的内容)
sort 是排序(按照字母顺序)
uniq -c 是对所有内容进行去重,并且计数
sort -rn 是反向排序。 根据计数的结果。
所以,上面的命令,会给出如下结果:
182.84.132.13
117.82.174.128
182.150.146.215
182.148.58.231
116.7.219.28
182.150.28.110
36.7.122.26
最后一部分的: awk '{if($1>100) .... }'是一个bash脚本,会找到所有出现过100次的ip, 然后输出一段deny这样的文本:
deny 182.84.132.13;
deny 117.82.174.128;
deny 182.150.146.215;
deny 182.148.58.231;
deny 116.7.219.28;
deny 182.150.28.110;
deny 36.7.122.26;
deny 110.7.48.47;
deny 124.127.182.6;
deny 110.188.153.219;
最后的最后,把上数的结果, 使用 ">" (覆盖文件) 或者 ">>" (追加文件) 操作符到blacklist.conf文件中。 完整命令为:
$ tail -n50000 /usr/local/nginx/logs/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | awk '{if($1>100)print "deny "$2";"}' >> /usr/local/nginx/conf/blacklist.conf
nginx中的配置如下:
http{
# ....
include blacklist.conf;
}
进一步的,我们可以只针对某个url的访问进行统计, 代码如下:
$ tail -n10000 /usr/local/nginx/logs/access.log | awk '{print $1,$7}' | grep send_login_token | awk '{print $1}' | sort | uniq -c | sort -rn | awk '{if($1>30)print "deny "$2";"}' >> /usr/local/nginx/conf/blacklist.conf
上面代码,会查看过去10000行nginx记录,找到对于访问 "/interface/..../send_login_token " 的request, 进行ip的计数,对于超过30次访问的,直接封ip
根据当前时刻的ip访问, 自动封禁ip 的脚本.
列出当前时刻, 所有的请求数大于10的ip地址: netstat -an | grep ^tcp.*:80 | egrep -v 'LISTEN|127.0.0.1' | awk -F"[ ]+|[:]" '{print $6}' | sort | uniq -c |sort -rn | awk '{ if ($1>10){print $2}}'
解释:
1. netstat -an -a 表示列出所有, -n 表示列出来的都是 数字(例如 3.3.3.4 , 而不是名称) 例如:
# netstat -an
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 127.0.0.1: 0.0.0.0:* LISTEN
tcp 0.0.0.0: 0.0.0.0:* LISTEN
tcp 0.0.0.0: 0.0.0.0:* LISTEN
tcp 0.0.0.0: 0.0.0.0:* LISTEN
tcp 0.0.0.0: 0.0.0.0:* LISTEN
tcp 0.0.0.0: 0.0.0.0:* LISTEN
tcp 0.0.0.0: 0.0.0.0:* LISTEN
tcp 0.0.0.0: 0.0.0.0:* LISTEN
tcp 0.0.0.0: 0.0.0.0:* LISTEN
tcp 0.0.0.0: 0.0.0.0:* LISTEN
tcp 0.0.0.0: 0.0.0.0:* LISTEN
tcp 0.0.0.0: 0.0.0.0:* LISTEN
tcp 172.18.230.209: 118.112.56.229: TIME_WAIT
tcp 172.18.230.209: 218.5.173.146: ESTABLISHED
tcp 172.18.230.209: 182.84.139.53: ESTABLISHED
tcp 172.18.230.209: 218.5.173.146: ESTABLISHED
tcp 172.18.230.209: 140.205.140.205: CLOSE_WAIT
2. $ netstat -an |grep ^tcp.*:80 是对当前的链接中,找到所有的要访问80端口的请求. 例如:
# netstat -an | grep ^tcp.*:
tcp 0.0.0.0: 0.0.0.0:* LISTEN
tcp 172.18.230.209: 118.112.56.229: TIME_WAIT
tcp 172.18.230.209: 118.112.56.229: ESTABLISHED
tcp 172.18.230.209: 140.205.140.205: CLOSE_WAIT
tcp 172.18.230.209: 182.84.139.53: TIME_WAIT
tcp 172.18.230.209: 180.108.11.25: TIME_WAIT
3. $ netstat -an |grep ^tcp.*:80 | egrep -v 'LISTEN|127.0.0.1' , 这句话是对 "127.0.0.1' 或者 LISTEN 做个排除. 去掉本地的请求, 去掉 正在 LISTEN的接口
4. awk -F"[ ]+|[:]" '{print $6}' 这里是对结果做个处理, 把某一行的结果, 按照 空格或者 ':' 冒号来分割,取得第六个.(起始的是第一个), 例如:
tcp 172.18.230.209: 118.112.56.229: TIME_WAIT
按照空格或者: 来分割的话,第六个就是 118.112.56.229, 这个就是正在请求的IP
5. sort: 按照字母顺序排序. uniq -c 表示 去重,并且加上 出现的次数. sort -r 表示 翻转排序. -n 表示按照数字的大小排序.
6. awk '{if ($1>$num){print $2}} 处理结果, 找到满足条件的, 然后打印出来.
完整版, 根据每秒ip的访问上线,来自动封禁的脚本 :
#!/bin/bash
num= # 每秒某个ip的访问上限
list=`netstat -an |grep ^tcp.*:|egrep -v 'LISTEN|127.0.0.1'|awk -F"[ ]+|[:]" '{print $6}'|sort|uniq -c|sort -rn|awk '{if ($1>$num){print $2}}'`
for i in $list
do
iptables -I INPUT -s $i --dport -j DROP
done
解封IP的方法
先用这个命令看到所有被封禁的IP $ iptables -L -n -v --line-numbers
iptables -L -n -v --line-numbers
Chain INPUT (policy ACCEPT packets, bytes)
num pkts bytes target prot opt in out source destination
DROP all -- * * 45.77.183.135 0.0.0.0/
DROP all -- * * 120.239.199.152 0.0.0.0/
DROP all -- * * 47.52.132.105 0.0.0.0/
然后用这个命令恢复: iptables -D INPUT ( 例如:iptables -D INPUT 1 就是删掉上面的第一条 45.77.183.135 )
转自
linux , nginx: 封禁IP的办法 (自动化脚本封ip, 根据瞬时的请求总量,或者根据日志 - 为程序员服务 http://ju.outofmemory.cn/entry/343736
最新文章
- MySQL学习笔记十五:优化(2)
- sublime3 集成angularJs插件
- segments&;cache
- jquery.validate.js插件使用
- Linux设置环境变量小结:设置永久变量&;临时变量 全局变量&;局部变量
- 美女程序员是如何将QQ转换成题目中那串数字的--读博文《找女神要QQ号码》
- 《zw版·Halcon-delphi系列原创教程》 邮票艺术品自动分类脚本
- fx-experience-tools
- Linux系统上安装软件(JDK以及tomcat服务器)
- SpringBoot接口服务处理Whitelabel Error Page(转)
- QQ登陆接口
- Algorithms code
- nodejs版本更新问题:express不是内部或外部命令
- 设置Firefox自动清除缓存,无需手动清除
- 【Teradata】块压缩(ferret工具)
- Multi-View Region Adaptive Multi-temporal DMM and RGB Action Recognition
- transition的用法以及animation的用法
- leveldb skiplist的改编非并发去除内存池版本 代码练习
- 恶意代码技术第一二部分——P201421410029
- 编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本]