最近无意中查了一下网站日志,结果发现受到了大量非法拉取、大量漏洞攻击,好家伙!为了减少这些恶意行为,打算直接屏蔽其IP(通过对日志的相应编辑,看到部分IP能重复上千次!),由于我的网站套了Cloudflare,在nginx.conf
中屏蔽某一IP并不能生效(我自己用手机测试的),上网搜了一些解决办法,选一种简单有效的方法记录一下。
说到获取真实IP,我们不难想到nginx的http realip module,就是当遇到IP是设定范围内的地址时,就逆向递归获取源目标的真实IP。对于Cloudflare CDN而言,也是遵从行业标准的,即使用X-Forwarded-For header 和 CF-Connecting-IP header 。Cloudflare的真实IP地址可以从这里获取Cloudflare IP addresses,当然我们也可以查看文本格式的Cloudflare的IP段:
https://www.cloudflare.com/ips-v4
https://www.cloudflare.com/ips-v6Copy
官方建议还是要定期更新这个IP范围的,以免范围改动影响使用效果。
一、自动更新脚本
#!/bin/bash
CLOUDFLARE_FILE_PATH=/etc/nginx/cloudflare_IP.conf
SH_SAVE_PATH=/root/shfiles
echo "#Cloudflare" > $CLOUDFLARE_FILE_PATH;
echo "" >> $CLOUDFLARE_FILE_PATH;
echo "# - IPv4" >> $CLOUDFLARE_FILE_PATH;
for i in `curl https://www.cloudflare.com/ips-v4`; do
echo "set_real_ip_from $i;" >> $CLOUDFLARE_FILE_PATH;
done
echo "" >> $CLOUDFLARE_FILE_PATH;
echo "# - IPv6" >> $CLOUDFLARE_FILE_PATH;
for i in `curl https://www.cloudflare.com/ips-v6`; do
echo "set_real_ip_from $i;" >> $CLOUDFLARE_FILE_PATH;
done
echo "" >> $CLOUDFLARE_FILE_PATH;
echo "real_ip_header CF-Connecting-IP;" >> $CLOUDFLARE_FILE_PATH;
# 方便打印时间到日志中
echo
echo `date +"%Y-%m-%d %H:%M:%S"`
# 更新cloudflare_IP.conf后要重新启动下Nginx,使其生效
cd $SH_SAVE_PATH
nginx -t && /etc/init.d/nginx restart
exit 0
将以上脚本保存到/root/shfiles/
下,并测试下。输出文件内容如下:
#Cloudflare
# - IPv4
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
# - IPv6
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP;
real_ip_recursive on;
二、选出恶意IP
将网站日志(一般是access.log
)中的内容按照IP出现的次序排序,并输出到文本中:
awk '{print $1}' /www/wwwlogs/access.log |sort |uniq -c|sort -n 2>&1 | tee -a /www/wwwlogs/blockip.conf
按照下图的格式调整blockip.conf
文件。
三、配置nginx.conf
找到网站的nginx.conf
文件,在server
中插入include /path/blockip.conf;
,这里/path/
就是blockip.conf
的绝对路径。然后再执行下
nginx -t
/etc/init.d/nginx restart
没报错的话,就用手机测试下效果(可能需要清理下浏览器缓存),如果手机浏览器界面出现403
等常见HTTP错误代码则表示没问题了。注意这里不要用电脑IP测试,否则很可能会导致无法通过Xshell等工具连接到服务器。我在测试时在站点的配置文件(如eonegh.com.conf
)里面也加入include /path/blockip.conf;
(如果没效果,可以考虑也在站点文件的server
中加入。)
四、自动执行
crontab -e
# 每月28号的凌晨1点1分时候执行一次,并将结果输入到日志中
1 1 28 * * /root/shfiles/cf_realIP_update.sh 2>&1 | tee -a /www/wwwlogs/cf_realIP_update.sh.log
五、屏蔽蜘蛛爬虫
分析日志还可以看到大量的恶意搜索引擎蜘蛛爬虫大量访问网站,其实对服务器的影响不大,但对于一些服务器资源比较紧张的站点,还是把这些访问禁止掉吧,以减少服务器消耗。
#禁垃圾蜘蛛
if ($http_user_agent ~* "CheckMarkNetwork|Synapse|Nimbostratus-Bot|Dark|scraper|LMAO|Hakai|Gemini|Wappalyzer|masscan|crawler4j|Mappy|Center|eright|aiohttp|MauiBot|Crawler|researchscan|Dispatch|AlphaBot|Census|ips-agent|NetcraftSurveyAgent|ToutiaoSpider|EasyHttp|Iframely|sysscan|fasthttp|muhstik|DeuSu|mstshash|HTTP_Request|ExtLinksBot|package|SafeDNSBot|CPython|SiteExplorer|SSH|MegaIndex|BUbiNG|CCBot|NetTrack|Digincore|aiHitBot|SurdotlyBot|null|SemrushBot|Test|Copied|ltx71|Nmap|DotBot|AdsBot|InetURL|Pcore-HTTP|PocketParser|Wotbox|newspaper|DnyzBot|redback|PiplBot|SMTBot|WinHTTP|Auto Spider 1.0|GrabNet|TurnitinBot|Go-Ahead-Got-It|Download Demon|Go!Zilla|GetWeb!|GetRight|libwww-perl|Cliqzbot|MailChimp|SMTBot|Dataprovider|XoviBot|linkdexbot|SeznamBot|Qwantify|spbot|evc-batch|zgrab|Go-http-client|FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Java|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|YisouSpider|HttpClient|MJ12bot|EasouSpider|LinkpadBot|Ezooms") {
return 400;
break;
}
#禁部分爬取工具
if ($http_user_agent ~* "crawl|curb|git|Wtrace|Scrapy" ) {
return 400;
break;
}
#UA 不全,十有八九不是正常访问,禁
if ($http_user_agent = "Mozilla") {
return 400;
break;
}
#UA 不全,十有八九不是正常访问,禁
if ($http_user_agent = "Mozilla/5\.0") {
return 400;
break;
}
#UA 不全,十有八九不是正常访问,禁
if ($http_user_agent = "Mozilla/4\.0") {
return 400;
break;
}
#禁IE6
if ($http_user_agent = "MSIE 6\.0") {
return 400;
break;
}
#禁止特殊请求方式
if ($request_method ~* "DELETE|OPTIONS" ) {
return 400;
break;
}
#禁特殊url,wp慎
location ~* (wp-login\.php|LICENSE|README\.md)$ {
return 400;
break;
}
#禁特殊url
location ~* ^/(cgi-bin|includes|plus|user|web|vendor|maccms|bitcoin|wallet|backup)/.*.(php|php5|html)$ {
return 400;
break;
}
#禁特殊后缀
location ~* \.(asp|aspx|htaccess|ini|sql|env|git|project|cgi)$ {
return 400;
break;
}
#禁压缩包
location ~* \.(tgz|bak|zip|rar|tar|gz|bz2|xz|tar.gz)$ {
return 400;
break;
}
#禁空 UA
if ($http_user_agent ~* ^$) {
return 400;
break;
}
#非 SSR 屏蔽
if ($http_user_agent ~* "python-requests" ) {
return 400;
break;
}
#禁特殊请求工具
if ($http_user_agent ~* "Wget|Curl" ) {
return 400;
break;
}
#禁特定请求方式
#if ($request_method ~* "POST|PUT" ) {
# return 400;
# break;
#}
复制以上内容,保存为kill_bots.conf
,并在nginx.conf
和eonegh.com.conf
中的server
中插入,类似于include /path/kill_bots.conf;
。再执行下:
nginx -t
/etc/init.d/nginx restart
这个无法立即看到效果,等一段时间后查看access.log
或者eonegh.com.log
,若看到部分蜘蛛爬虫访问后返回非200
的HTTP状态代码(一般是404
,403
之类),就表示以上配置是已经生效的。
实验环境:Ubuntu16.04,Nginx v1.18.0,Cloudflare,VPS
六、参考文件
1、CloudFlare CDN下Nginx正确获取真实IP教程 | 奶牛博客
2、GitHub - ergin/nginx-cloudflare-real-ip
3、NGINX,PHP获取Cloudflare传递的真实访客IP 配合宝塔面板防御CC攻击 防伪造IP
4、http协议的状态码——400,401,403,404,500,502,503,301,302等常见网页错误代码
好家伙,这么多日志文件
哈哈,不多不多,我这小破站没啥访问量