标题纯属开玩笑哈,不要介意,更多nginx内容请访问从今天开始种树
前言
恶意请求实属烦人,几分钟都能请求几百次,对于小站而言无疑增加了大量负担,辛辛苦苦原创的内容,几分钟被这些恶意请求白嫖个干干净净,泪目。所以针对性的搜集实验了一些方法来尽可能避免这些恶意请求的访问,希望能帮助各位需要的懂懂们。
直接开整
作为一个爬虫小手,对毫不限制的请求次数是深恶痛绝,而且大部分人应对基本反爬还会伪造个请求头什么的,但是下面这个ip真是把流氓精神体现得淋漓尽致。
它的访问次数没有截全,一秒钟大概请求了100多个网页,这个请求头Scrapy/1.7.3 (+https://scrapy.org)
是不是很熟悉,没错它就是大名鼎鼎的Scrapy
爬取的。
测试
首先编写了一段python
代码来伪造这个请求头请求:
import requests header = { "User-Agent":"Scrapy/1.7.3 (+https://scrapy.org)" } url = "http://www.happyhong.cn" resp = requests.get(url,headers=header) print(resp.status_code) >>200 #返回的是200
可以看出访问是成功的,因为返回码时200
。
对付这种特有的请求头,可以在配置文件中添加这个试试,我测试了一下是可以的:
server{ listen 80; server_name www.happyhong.cn ; ..... 省略 ..... if ($http_user_agent = 'Scrapy/1.7.3 (+https://scrapy.org)' ) { return 403; } }
返回了403,与我们配置的一样。这种方法对于小站来说是可以一试的,不过对于大站来说貌似很少用,包括我自己运维的系统也没用这种方式,下面是更直接的方式,封禁恶意IP。
封禁恶意请求IP
只要在网上一搜nginx封禁恶意IP其实就有很多文章,这里还是提一下,毕竟是个比较重要的方法。类似于防火墙,nginx也可以设置黑白名单,可以选择让哪些IP访问不了,前提是根据你的需求获得一些恶意请求IP
。
需求1:获取各个IP访问次数
cat /usr/local/nginx/logs/access.log|awk '{print $1}' |sort |uniq -c|sort -n
需求2:根据特定URL获取IP访问次数
cat /usr/local/nginx/logs/access.log|awk '{print $1,$7}' |grep -i -E "happyhong.cn" |sort |uniq -c|sort -n
因为要以定时任务方式采集,所以最好弄成shell
脚本形式。
vi get_blacklist.sh
#针对需求1 cat /usr/local/nginx/logs/access.log|awk '{print $1}' |sort |uniq -c|sort -n>>blacklist.conf #针对需求2,注意使用>> 表示追加 cat /usr/local/nginx/logs/access.log|awk '{print $1,$7}' |grep -i -E "happyhong.cn" |sort |uniq -c|sort -n>>blacklist.conf
crontab -e # 10分钟采集一次,自己定时间了 */10 * * * * /usr/local/nginx/get_blacklist.sh
找到配置文件
find / -name nginx.conf
可以添加在http, server, location, limit_except
语句块中,这里添加在server
块location
下面:
location / { ... include blacklist.conf; }
/usr/local/nginx/sbin/nginx -t #检测一下配置文件语法是否正确 /usr/local/nginx/sbin/nginx -s reload
只允许特定请求
比如我的博客,根本就没有使用PUT、DELETE这样的方法,不过看了日志有很多请求是使用这两种方式,很明显就不是正常人类行为,直接限定死请求方式。
server{ listen 80; server_name www.happyhong.cn ; ..... 省略 ..... if ($request_method !~* GET|POST) { return 405; } }
限制同一个ip的访问频率方法
http{ ... #定义一个名为happy的limit_req_zone用来存储session,大小是10M内存, #以$binary_remote_addr 为key,限制平均每秒的请求为20个, #1M能存储16000个状态,rete的值必须为整数, #如果限制两秒钟一个请求,可以设置成30r/m limit_req_zone $binary_remote_addr zone=happy:10m rate=20r/s; ... server{ ... location { ... #限制每ip每秒不超过20个请求,漏桶数burst为5 #brust的意思就是当每秒超过20个请求时,5个以内的请求会被延迟访问,超过5个的直接返回503 #nodelay,设置该选项,将严格使用平均速率限制请求数,超过请求频率的直接返回503 limit_req zone=happy burst=5 nodelay; ... } ... } ... }
$binary_remote_addr
是限制同一客户端ip地址;
$server_name
是限制同一server最大并发数;
limit_conn
为限制并发连接数;
limit_rate
为限制下载速度;
拓展
这个方式倒是没尝试过,有兴趣的可以试一试。直接从服务器层面禁止比nginx层面禁止要好很多,这样不会再接受到该IP的请求。
单个IP的命令是 iptables -I INPUT -s 10.235.65.103 -j DROP 封IP段的命令是 iptables -I INPUT -s 10.235.65.0/16 -j DROP 封整个段的命令是 iptables -I INPUT -s 112.36.1.0/8 -j DROP 解封 iptables -F 清空 iptables -D INPUT 数字 service iptables save service iptables restart iptables -L -n
#!/bin/bash num=100 #上限 list=`netstat -an |grep ^tcp.*:80|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 80 -j DROP done
结束
本文就关于nginx恶意访问提供了一些解决思路,可能适用于你,如果有帮助请帮忙点个赞。更多内容请访问从今天开始种树,关注下面的公众号,当然不关注也无所谓。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论