配置 NGINX 拒绝恶意访问 / 爬取网站

最近有点忙, 一段时间没管博客了, 今天上来看了一下 access.log, 多了一些牛鬼蛇神, 之前因为博客访问量少, 没怎么弄, 看来是时候带一波节奏了

之前的做法

以前就已经陆续发现一些恶意用户访问了, 比如:

  • 认为后端是 java 对 tomcat 的 /manager 进行访问的,
  • 认为后端是 php 做一些 eval 或者爆破操作的,
  • 一些独狼 / 个人蜘蛛用户不分时段对网站进行大规模爬取的

由于都是一些零散的访问, 针对这些行为 在 nginx.conf 同目录下创建了一个 denyIpList.conf 配置文件, 内容形式如下:


# 针对单个ip的形式
deny 171.94.171.205;
deny 115.29.166.101;
deny 182.247.251.48;
deny 61.147.89.17;
# 针对网段的形式
deny 66.249.227.0/24;

然后在 nginx.conf 合适的位置引入此配置文件:


http {
    include       mime.types;
    include       denyIpList.conf;

    default_type  application/octet-stream;
...以下省略

重启 nginx 后生效, 这样, 当这些 ip/ 网段发起访问后, 直接返回 403;

现在的做法

现象

今早上来看了一下访问记录后, 发现了几组丧心病狂的内容:

  1. user-agent 为 Baidu-YunGuanCe-SLABot(ce.baidu.com) 的访问;
  2. 来自美国 66.249..网段的访问;
  3. user-agent 为 Mozilla/5.0 (compatible; MJ12bot/v1.4.7; ... 的访问
  4. user-agent 为空 (正常浏览器访问不会为空的)

分析

其中第一个我刚开始以为是我配的百度云观测网站定期健康检查的访问记录, 但是简单统计了一下, 数量也太大了, 而且不分时段都有, 初步怀疑是有人闲着无聊借用百度云观测提供的工具对本站进行了友 e 情 yi 压测... 即便不是, 我也不需要云观测提供的特殊服务, 准备直接 ban 掉;
第二个, 应该是谷歌的爬虫 (ua 判断), 以前也看到过访问记录, 频率比较低, 直接 deny 访问地址的, 但是最近访问的 ip 也太多了, 根本 ban 不过来;
第三个,MJ12bot 比较常用的爬虫工具, 访问 ip 也是来自世界各地;

解决方案

根据以上分析, 发现大部分恶意请求可以通过 user-agent 来判断, 因此, 考虑通过 nginx 提供的一些内置变量进行配置:

  • 首先我们还是新建一个文件 denyUaList.conf 在 nginx.conf 同目录下;
  • 编写 denyUaList.conf 规则内容:

#禁止常用工具的抓取  
if ($http_user_agent ~* (Scrapy|Curl|HttpClient|Java)) {  
  return 403;  
}  
#禁止指定UA及UA为空的访问  
if ($http_user_agent ~* "Baidu-YunGuanCe|FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Feedly|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|YisouSpider|MJ12bot|heritrix|EasouSpider|LinkpadBot|Ezooms|^$" )  
{  
  return 403;  
}

tips: 注意书写格式 if 和 ( 之间有空格,|Ezooms| 最后面有个 | 破折号, 用于禁止空 ua 访问

  • 在 nginx.conf 中合适的位置引入 denyUaList.conf

...以上省略
    server {                                                                      
        listen         443 ssl;                                                  
        server_name    example.com;#你的域名     

        ...ssl配置省略...

        include        denyUaList.conf;
...以下省略

tips: 注意因为 denyUaList.conf 包含 if 等控制语句, 因此不能和 denyIpList.conf 一样放在根节点, 需要自行根据需要放在 server 节点中

以上就是目前的配置方案, 如果后续有优化升级, 会在本帖更新, 如果有朋友有更合适的方案, 请在留言中回复!

测试

在 Baidu-YunGuanCe 前增加 chrome|, 然后使用谷歌浏览器访问博客地址, 返回 403forbidden, 切换为 ie 访问, 正常进入 ( 不过d 大 @88250竟然给了一个超 low 的提示 (/ □)), 测试通过, 去掉 chrome|, 重启 nginx, 收工!