我承认这标题有点夸大了,但对于小站长而言,在没有网站收入的情况下,每天还要不断支出费用确实让人心疼。原本一天几毛钱,现在涨了10倍,照这趋势可不早晚得关网站嘛~
从去年年底开始,服务器就一直不稳定,最严重的时候一天当中有半天CPU都被干到100%,网站基本上无法打开,搜索引擎的点击量直线下降。
好不容易把服务器更新完毕并且重装了MediaWiki,现在倒是不死机了,但每天的流量费用“噌噌噌”地往上涨(服务器是按照流量付费)。打开日志文件,一堆的爬虫记录,当初的死机和现在的流量费超支妥妥跟它们有关了。
防御一 robots.txt
在网站根目录下新建文件robots.txt
,然后在其中加入如下语句(以百度蜘蛛为例):
User-agent: baiduspider
Disallow: /
也可以禁止爬虫访问某些特定页面,比如MediaWiki常用的特殊页面和模板页面等:
Disallow: /index.php?diff=
Disallow: /index.php?oldid=
Disallow: /index.php?title=Help
Disallow: /index.php?title=Image
Disallow: /index.php?title=MediaWiki
Disallow: /index.php?title=Special:
Disallow: /index.php?title=Template
Disallow: /skins/
但这种防君子不防小人的防御手段在那些不讲武德的爬虫面前简直毫无作用。
防御二 配置Nginx
如果使用Nginx的话,$http_user_agent变量可以获取到用户的UA,匹配到我们指定的关键词,直接返回 403无权访问。
server {
# 禁止Scrapy等工具的抓取
if ($http_user_agent ~* (Scrapy|HttpClient|PostmanRuntime|ApacheBench|Java||python-requests|Python-urllib|node-fetch)) {
return 403;
}
# 禁止指定的 user agent 以及为空的访问
if ($http_user_agent ~ "Nimbostratus|MJ12bot|MegaIndex|YisouSpider|^$" ) {
return 403;
}
}
上面仅列出来了部分爬虫的UA关键词,更多的可以去网上搜索“垃圾爬虫”。
当然也可以通过禁止某些ip访问。
location / {
deny 108.179.194.35; # 扫描 wordpress
deny 159.203.31.171; # 扫描 wp-login
deny 158.69.243.0/24; # MJ12bot
deny 46.229.168.0/24; # SemRush
deny 54.36.148.0/24; # AhrefsBot
deny 54.36.149.0/24; # AhrefsBot
}
通过这样的方式基本上能防御大部分常见的恶意爬虫,比如消耗我大量流量的神马搜索(YisouSpider)。这些爬虫既不贡献点击量反倒是拖累了整个网站。而且爬文字也就算了,还把网站上的图片都爬一遍,流量费不超才怪呢。
防御三 安装Nginx Ultimate Bad Bot Blocker
第二种方法虽然不错,但有没有更加方便和强大的工具呢?
Nginx Ultimate Bad Bot Blocker由Mitchell Krog开发,用于Nginx服务器,在Github上拥有四千多星的好评。
该程序列表全局可用,执行“sudo service nginx reload” 之后,任何更改都会立即应用于所有站点。列表定期更新,几乎每天都有新内容。而且它使用的是444响应,即服务器没有返回信息给客户端却关闭了连接。
更多功能和优点就不过多介绍了,有兴趣的可以去它的Github页面上看一下。
下面记录一下它的安装方法。
第1步 – 下载Nginx Ultimate Bad Bot Blocker
使用以下命令将其下载到 Linux 系统上:
### With wget
sudo wget https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/install-ngxblocker -O /usr/local/sbin/install-ngxblocker
### With curl
curl -sL https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/install-ngxblocker -o /usr/local/sbin/install-ngxblocker
下载文件后,使其可执行。
sudo chmod +x /usr/local/sbin/install-ngxblocker
第2步 – 下载所需文件。
运行install-ngxblocker
会下载所有必需的文件,包括设置和更新脚本。
cd /usr/local/sbin
sudo ./install-ngxblocker
执行后(上述方式只是一种DRY-MODE,并不会进行任何更改)会有如下输出:
Checking url: https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/include_filelist.txt
** Dry Run ** | not updating files | run as 'install-ngxblocker -x' to install files.
Creating directory: /etc/nginx/bots.d
REPO = https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master
Downloading [FROM]=> [REPO]/conf.d/globalblacklist.conf [TO]=> /etc/nginx/conf.d/globalblacklist.conf
Downloading [FROM]=> [REPO]/conf.d/botblocker-nginx-settings.conf [TO]=> /etc/nginx/conf.d/botblocker-nginx-settings.conf
REPO = https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master
Downloading [FROM]=> [REPO]/bots.d/blockbots.conf [TO]=> /etc/nginx/bots.d/blockbots.conf
Downloading [FROM]=> [REPO]/bots.d/ddos.conf [TO]=> /etc/nginx/bots.d/ddos.conf
Downloading [FROM]=> [REPO]/bots.d/whitelist-ips.conf [TO]=> /etc/nginx/bots.d/whitelist-ips.conf
Downloading [FROM]=> [REPO]/bots.d/whitelist-domains.conf [TO]=> /etc/nginx/bots.d/whitelist-domains.conf
Downloading [FROM]=> [REPO]/bots.d/blacklist-user-agents.conf [TO]=> /etc/nginx/bots.d/blacklist-user-agents.conf
Downloading [FROM]=> [REPO]/bots.d/blacklist-ips.conf [TO]=> /etc/nginx/bots.d/blacklist-ips.conf
Downloading [FROM]=> [REPO]/bots.d/bad-referrer-words.conf [TO]=> /etc/nginx/bots.d/bad-referrer-words.conf
Downloading [FROM]=> [REPO]/bots.d/custom-bad-referrers.conf [TO]=> /etc/nginx/bots.d/custom-bad-referrers.conf
REPO = https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master
Downloading [FROM]=> [REPO]/setup-ngxblocker [TO]=> /usr/local/sbin/setup-ngxblocker
Downloading [FROM]=> [REPO]/update-ngxblocker [TO]=> /usr/local/sbin/update-ngxblocker
上面的命令列出了将要下载的包,现在使用带有-x
参数的命令下载所有必要的文件。
cd /usr/local/sbin/
sudo ./install-ngxblocker -x
输出如下所示:
Checking url: https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/include_filelist.txt
Nothing to update for directory: /etc/nginx/conf.d
REPO = https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master
Downloading [FROM]=> [REPO]/bots.d/ddos.conf [TO]=> /etc/nginx/bots.d/ddos.conf...OK
Downloading [FROM]=> [REPO]/bots.d/custom-bad-referrers.conf [TO]=> /etc/nginx/bots.d/custom-bad-referrers.conf...OK
Downloading [FROM]=> [REPO]/bots.d/bad-referrer-words.conf [TO]=> /etc/nginx/bots.d/bad-referrer-words.conf...OK
Downloading [FROM]=> [REPO]/bots.d/blacklist-ips.conf [TO]=> /etc/nginx/bots.d/blacklist-ips.conf...OK
Downloading [FROM]=> [REPO]/bots.d/blacklist-user-agents.conf [TO]=> /etc/nginx/bots.d/blacklist-user-agents.conf...OK
Downloading [FROM]=> [REPO]/bots.d/whitelist-domains.conf [TO]=> /etc/nginx/bots.d/whitelist-domains.conf...OK
Downloading [FROM]=> [REPO]/bots.d/whitelist-ips.conf [TO]=> /etc/nginx/bots.d/whitelist-ips.conf...OK
REPO = https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master
Downloading [FROM]=> [REPO]/setup-ngxblocker [TO]=> /usr/local/sbin/setup-ngxblocker...OK
Downloading [FROM]=> [REPO]/update-ngxblocker [TO]=> /usr/local/sbin/update-ngxblocker...OK
Setting mode: 700 => /usr/local/sbin/install-ngxblocker
Setting mode: 700 => /usr/local/sbin/setup-ngxblocker
Setting mode: 700 => /usr/local/sbin/update-ngxblocker
将所需文件下载到Nginx的正确文件夹后,通过运行以下两个命令将设置和更新脚本设置为可执行。
sudo chmod +x /usr/local/sbin/setup-ngxblocker
sudo chmod +x /usr/local/sbin/update-ngxblocker
第3布 – 安装 Nginx Bad Bot Blocker
要安装Nginx Bad Bot Blocker,我们将运行setup-ngxblocker
脚本。该脚本可以在DRY-MODE下运行,以显示它将进行的更改以及它将下载的文件,如下所示。
cd /usr/local/sbin/
sudo ./setup-ngxblocker
正确输出:
Configure every file above as a vhost ? [Y/N] : y
Checking url: https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/include_filelist.txt
** Dry Run ** | not updating files | run as 'setup-ngxblocker -x' to setup files.
INFO: /etc/nginx/conf.d/* detected => /etc/nginx/nginx.conf
Checking for missing includes:
Checking url: https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/include_filelist.txt
Nothing to update for directory: /etc/nginx/conf.d
Nothing to update for directory: /etc/nginx/bots.d
Nothing to update for directory: /usr/local/sbin
Setting mode: 700 => /usr/local/sbin/install-ngxblocker
Setting mode: 700 => /usr/local/sbin/setup-ngxblocker
Setting mode: 700 => /usr/local/sbin/update-ngxblocker
如果像我一样,安装Nginx没有生成sites-available
和sites-available
的话,系统会提示找不到目录。
find: ‘/etc/nginx/sites-available’: No such file or directory
find: ‘/etc/nginx/sites-available’: No such file or directory
Configure every file above as a vhost ? [Y/N] : y
find: ‘/etc/nginx/sites-available’: No such file or directory
using a file extension for vhost files allows multiple domains to be included with a single directive in nginx.conf:
include /etc/nginx/sites-enabled/*.vhost;
see command line switches below: -e to customise the vhost file extension
no vhost files in: [ /etc/nginx/sites-available/*.vhost ] => exiting.
setup-ngxblocker: SETUP Nginx Bad Bot Blocker configuration in [ /etc/nginx/nginx.conf ] [ /etc/nginx/sites-available/* ]
新建缺少的两个目录即可(记得把原来的配置文件复制到sites-available
,并通软链接到sites-enabled
中)。
注意:如果使用的Oneinstack之类的一键安装脚本,因为其配置不同于Nginx的默认安装,所以可以使用安装到非标准文件夹方式(见下文)。
现在运行带有-x
参数的设置脚本,对nginx.conf
进行所有必要的更改(如果需要)。默认所有虚拟主机配置文件都以扩展名.vhost
结尾,并且作者也建议最好使用vhost。如果你习惯将虚拟主机文件以.conf
结尾,可以使用额外的命令行参数进行更改此,如下所示:
sudo ./setup-ngxblocker -x -e conf
现在按照默认方式运行脚本:
sudo ./setup-ngxblocker -x
示例输出:
Configure every file above as a vhost ? [Y/N] : y
Checking url: https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/include_filelist.txt
Checking url: https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/include_filelist.txt
INFO: /etc/nginx/conf.d/* detected => /etc/nginx/nginx.conf
inserting: include /etc/nginx/bots.d/blockbots.conf; => /etc/nginx/sites-available/mydomain2.com.vhost
inserting: include /etc/nginx/bots.d/ddos.conf; => /etc/nginx/sites-available/mydomain2.com.vhost
inserting: include /etc/nginx/bots.d/blockbots.conf; => /etc/nginx/sites-available/mydomain1.com.vhost
inserting: include /etc/nginx/bots.d/ddos.conf; => /etc/nginx/sites-available/mydomain1.com.vhost
Whitelisting ip: x.x.x.x => /etc/nginx/bots.d/whitelist-ips.conf
上面的命令包含服务器上的所有Nginx虚拟主机文件,并将你的Ip地址列入Whitelist-ips.conf
中。你可以通过编辑文件/etc/nginx/bots.d/whitelist-ips.conf
进行所需的更改。
这个设置脚本所做的只是为你的.vhost
(或者是.conf
)文件中添加了以下 include
语句,它还将通过include
方式将/etc/nginx/conf.d/*
添加到nginx.conf
中。
# Bad Bot Blocker
include /etc/nginx/bots.d/ddos.conf;
include /etc/nginx/bots.d/blockbots.conf;
conf.d
目录下会新增加几个新的配置文件,主要是供用户自定义(见下文)。
完成后,检查Nginx配置的语法,运行如下命令:
$ sudo nginx -t
系统将返回如下信息:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
此时可以重新加载或重新启动Nginx以使更改生效:
sudo nginx -s reload
或
sudo systemctl restart nginx
第4步 – 配置自动更新
我们将配置一个Cron作业,以便自动更新到最新版本。
打开文件进行编辑:
sudo crontab -e
在文件中添加以下行,并替换成自己的电子邮件地址。
00 22 * * * sudo /usr/local/sbin/update-ngxblocker -e yourname@youremail.com
该命令将在每晚10点自动更新。你还可以通过将Cron任务设置为每8小时运行一次,以确保每天推送3次(虽然每天一次就足够了),如下所示:
00 */8 * * * sudo /usr/local/sbin/update-ngxblocker -e yourname@youremail.com
你还可以使用以下命令禁用电子邮件更新(但可能在重载错误时无法收到任何邮件通知):
00 */8 * * * sudo /usr/local/sbin/update-ngxblocker -n
通过上述方法,拦截器会自动保持最新状态,并在下载最新版本的globalblacklist.conf
文件后重新加载Nginx。
第5步 – 自定义Nginx Ultimate Bad Bot Blocker
可以通过编辑“include”文件来自定义Nginx Ultimate Bad Bot Blocker以适合服务器环境。好处是这些文件不会被更新覆盖。
可供编辑的文件有:
/etc/nginx/bots.d/whitelist-ips.conf
/etc/nginx/bots.d/whitelist-domains.conf
/etc/nginx/bots.d/blockbots.conf
/etc/nginx/bots.d/blacklist-domains.conf
/etc/nginx/bots.d/blacklist-user-agents.conf
/etc/nginx/bots.d/blacklist-ips.conf
/etc/nginx/bots.d/bad-referrer-words.conf
/etc/nginx/bots.d/custom-bad-referrers.conf
/etc/nginx/bots.d/ddos.conf
例如,如果你想阻止GoogleBot
访问你的网站,可以编辑/etc/nginx/bots.d/blacklist-user-agents.conf
文件,它会覆盖 GoogleBot
的默认白名单。当然,也可以对任何其他列入白名单的爬虫执行此操作。
第6步 – 测试Nginx Ultimate Bad Bot Blocker
可以从另一台 Linux 计算机上的终端针对自己的域名逐个运行以下命令:
curl -A "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" -I http://yourdomain.com
或者还可以使用:
curl -A "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)" -I http://yourdomain.com
示例输出:
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Wed, 27 Apr 2022 08:57:12 GMT
Content-Type: text/html
Content-Length: 3429
Last-Modified: Thu, 10 Jun 2021 09:09:03 GMT
Connection: keep-alive
ETag: "60c1d6af-d65"
Accept-Ranges: bytes
以下测试应返回以下错误:
curl:(52)服务器的空回复
curl: (56) TCP 连接被对等方重置
curl: (92) HTTP/2 流 0 未完全关闭: PROTOCOL_ERROR (err 1)
使用以下命令进行测试:
curl -I http://yourdomain.com -e http://100dollars-seo.com
curl -I http://yourdomain.com -e http://zx6.ru
可选 – 将程序安装到非标准Nginx目录中
如果你希望可以通过指定文件夹将程序安装到非标准Nginx目录中,则可以运行如下命令:
sudo ./install-ngxblocker -x -c /usr/local/nginx/conf.d -b /usr/local/nginx/bots.d
sudo ./setup-ngxblocker -x -c /usr/local/nginx/conf.d -b /usr/local/nginx/bots.d
sudo ./update-ngxblocker -c /usr/local/nginx/conf.d -b /usr/local/nginx/bots.d -e yourname@youremail.com
这会自动将文件放入上述指定的位置,并使用自定义位置将包含到你的虚拟主机中,当update-ngxblocker
拉取新的更新时,它现在也会自动重写 globalblacklist.conf
文件中的 “Include” 部分。
关于警告
重新加载或重启Nginx可能会收到Duplicate network reports的警告信息,但这不是错误,也无法修复,这是阻止程序的理想行为。IP黑名单的每日更新会导致一些众所周知的IP和范围被列入黑名单,旧值设定为“1”,然后在globalblocklist
的末尾调用白名单,一些好的IP设置会被设置“0”的新值,并利用加载顺序从而将它们将它们恢复正常。从该程序的第1天开始就一直如此,并将保持这种状态。这些是简单的[WARN]消息,而不是[EMERG]消息,它们不会对Nginx的运行产生任何影响。
写在最后
用上Nginx Ultimate Bad Bot Blocker,并且自定义了部分IP之后,流量费用减少了70%左右。搞笑的是,用力过猛竟然把自己的IP也给封了,搞得自己都连不上网站。