批量扫描攻击从来不是碰运气,而是攻击者用自动化工具对全网IP段、域名列表进行无差别探测。扫描器会在几分钟内对一个站点发起数千次请求,专门寻找备份文件、管理后台、测试页面、已知漏洞路径和配置泄露。这类攻击不挑目标,只要你的站点暴露在公网,就一定会被扫到。很多人以为小网站没人关注,实际上批量扫描恰恰最喜欢防护薄弱的小站点,因为拿下之后可以作为跳板、挖矿节点或者SEO黑链的宿主。
要抵御批量扫描,首先要理解扫描器的行为特征。绝大多数扫描器会请求一些根本不存在的路径,观察返回码和响应时间,以此判断服务器类型、语言环境和WAF是否存在。它们会携带明显的特征:短时间内大量404请求、请求路径包含常见敏感文件名、User-Agent带有脚本标识、请求间隔极短且来源IP分散。识别这些特征之后,就可以从多个层面建立拦截机制。
第一步:关闭服务器信息泄露,让扫描器无法快速识别环境扫描器发起探测时,首先会收集HTTP响应头中的Server、X-Powered-By、X-AspNet-Version等信息。这些字段直接告诉攻击者你的Web服务器版本、语言版本和框架信息。例如Apache默认返回Server: Apache/2.4.41,Nginx返回Server: nginx,PHP会返回X-Powered-By: PHP/7.4.3。扫描器拿到这些信息后,会立即匹配对应的已知漏洞库,大幅提高攻击效率。
在Nginx中,可以在主配置文件的http块中添加以下配置来隐藏版本号:
http {
server_tokens off;
more_clear_headers "Server";
more_clear_headers "X-Powered-By";
}
如果使用Apache,需要在httpd.conf或apache2.conf中设置:
ServerTokens Prod ServerSignature Off Header unset X-Powered-By Header unset X-Runtime Header unset X-Version
隐藏这些信息不会阻止扫描器继续探测,但会显著增加它们识别环境的成本。很多自动化扫描工具在无法确认服务器类型时,会降低攻击强度或者直接跳过目标,因为盲目尝试漏洞会触发更多告警。
第二步:部署针对扫描行为的动态封禁策略批量扫描最显著的特征是请求频率异常和404错误率极高。正常用户访问网站,404请求占比通常低于5%,而扫描器发起的请求中,404占比往往超过50%甚至80%。基于这个特征,可以在Nginx层面配置访问限制。
以下配置会限制单IP的请求频率,并对连续产生404的IP进行封禁:
http {
limit_req_zone $binary_remote_addr zone=scan_limit:10m rate=5r/s;
limit_req_status 429;
map $status $is_404 {
404 1;
default 0;
}
limit_req_zone $binary_remote_addr zone=notfound_limit:10m rate=2r/s;
}
在server块中应用这些规则:
server {
limit_req zone=scan_limit burst=10 nodelay;
if ($is_404) {
limit_req zone=notfound_limit burst=5 nodelay;
}
}
更有效的做法是使用fail2ban这类工具,实时分析访问日志,当某个IP在短时间内产生大量404或请求敏感路径时,直接在防火墙层面封禁。fail2ban的过滤规则可以这样定义:
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD).*" 404
^<HOST> -.*"(GET|POST|HEAD).*(wp-admin|phpmyadmin|\.env|\.git).*"
ignoreregex =
这种动态封禁的优势在于,它不依赖固定的IP黑名单,而是根据实际行为实时判断。扫描器使用的IP池再大,只要行为模式不变,就会被持续封禁。
第三步:拦截已知的恶意路径和敏感文件请求批量扫描器通常会携带一个庞大的路径字典,里面包含了数万个常见敏感路径,例如/.git/config、/.env、/backup.zip、/phpinfo.php、/admin/login.php、/wp-login.php等。这些路径在正常业务中几乎不会被访问,因此可以直接在Web服务器层面进行拦截。
Nginx中可以使用location规则直接返回444(关闭连接不返回任何内容):
location ~* ^/(\.git|\.svn|\.env|\.htaccess|backup|phpmyadmin|wp-admin|adminer|config\.php|phpinfo\.php) {
return 444;
}
location ~* \.(sql|tar|gz|zip|bak|old|swp|save)$ {
return 444;
}
Apache中可以使用mod_rewrite实现类似效果:
RewriteEngine On RewriteRule ^(\.git|\.svn|\.env|backup|phpmyadmin|wp-admin) - [F,L] RewriteRule \.(sql|tar|gz|zip|bak|old)$ - [F,L]
这种拦截方式非常直接,扫描器请求这些路径时不会得到任何有效响应,也就无法判断文件是否存在。需要注意的是,如果你的业务确实使用了某些路径,例如/admin,那么需要根据实际情况调整规则,避免误伤正常访问。
第四步:限制管理后台的访问来源管理后台是批量扫描攻击的重点目标。攻击者会尝试常见的管理路径,然后使用弱口令字典进行暴力破解。即使你的后台路径不是默认的/admin,扫描器也能通过字典枚举出来。因此,管理后台必须做访问来源限制。
最有效的做法是只允许特定IP访问后台。在Nginx中:
location /admin {
allow 203.0.113.5;
allow 203.0.113.10;
deny all;
}
如果管理员使用动态IP,无法固定IP白名单,可以使用跳板机或者VPN(此处不展开)来获得固定出口IP。另外,后台必须启用强密码策略和双因素认证。即使扫描器绕过了IP限制,也无法仅凭密码字典进入后台。
第五步:对异常User-Agent和请求方法进行过滤扫描器通常使用脚本语言编写,其User-Agent往往带有明显的自动化特征,例如python-requests、curl、wget、masscan、nmap、sqlmap等。正常浏览器不会使用这些标识。在Nginx中可以直接拦截:
if ($http_user_agent ~* (python-requests|curl|wget|masscan|nmap|sqlmap|nikto|dirbuster|gobuster|zgrab|libwww-perl)) {
return 444;
}
同时,扫描器还会发送一些非标准的HTTP方法,例如TRACE、TRACK、DEBUG、OPTIONS等。除了GET、POST、HEAD之外的方法,如果业务不需要,可以直接拒绝:
if ($request_method !~ ^(GET|POST|HEAD)$) {
return 444;
}
这种过滤方式简单有效,但需要注意某些合法的API调用可能使用PUT、DELETE等方法,需要根据实际业务调整。
第六步:利用WAF进行深度行为分析对于有条件的站点,部署Web应用防火墙(WAF)是抵御批量扫描的重要手段。WAF不仅能够拦截已知的攻击载荷,还能通过行为分析识别扫描器的特征。例如,一个IP在短时间内请求了多个不存在的路径,WAF可以自动将该IP加入黑名单。WAF还可以识别扫描器使用的特定参数组合,例如在URL中注入大量特殊字符、尝试路径遍历、SQL注入探测等。
开源WAF如ModSecurity可以配置核心规则集(OWASP CRS),其中包含了大量针对扫描行为的检测规则。ModSecurity的配置示例如下:
SecRuleEngine On SecRequestBodyAccess On SecResponseBodyAccess On SecRule REQUEST_URI "@contains /wp-admin" "id:100001,phase:1,deny,status:403,msg:'WordPress admin access blocked'" SecRule REQUEST_URI "@rx /(\.git|\.env|\.svn)/" "id:100002,phase:1,deny,status:403,msg:'Sensitive file access blocked'"
WAF的另一个优势是能够记录详细的攻击日志,帮助安全团队分析扫描器的来源、目标和手法,从而进一步优化防护策略。
第七步:定期审计网站文件和目录权限批量扫描攻击的最终目的是找到可被利用的漏洞或敏感文件。如果网站本身的文件权限配置不当,即使扫描器找到了文件路径,也可能直接读取到敏感内容。例如,配置文件、数据库备份文件、日志文件如果存放在Web可访问目录下,并且权限设置过于宽松,攻击者就能直接下载。
必须确保Web根目录下不存在任何不必要的备份文件、压缩包、数据库导出文件。所有敏感文件应存放在Web根目录之外,并通过程序代码引用。对于必须放在Web目录下的配置文件,应设置严格的文件权限,例如600或640,确保Web服务器进程之外的用户无法读取。
同时,定期使用工具扫描自己的站点,检查是否存在敏感文件暴露。可以使用开源工具如Nikto、WPScan等对自己的站点进行模拟扫描,提前发现可能被攻击者利用的路径。
第八步:监控和分析访问日志,建立告警机制抵御批量扫描攻击不是一次性的配置工作,而是一个持续的过程。攻击者会不断更换IP、调整扫描策略,因此必须建立持续的监控机制。访问日志是发现扫描行为的第一手数据。通过分析日志中的404请求、异常User-Agent、异常请求频率,可以及时发现正在进行的扫描攻击。
可以使用Logwatch、GoAccess等工具定期生成访问报告,重点关注404请求的分布情况。如果某个IP在短时间内产生了大量404请求,或者某个路径被反复请求但返回404,就需要进一步分析。同时,设置告警规则,当检测到异常扫描行为时,通过邮件或消息通知管理员。
对于大型站点,可以考虑使用ELK(Elasticsearch、Logstash、Kibana)或类似方案集中收集和分析日志。通过可视化仪表盘,可以直观地看到扫描攻击的趋势和来源,为后续的防护策略调整提供依据。
批量扫描攻击的防护核心在于提高攻击者的成本。当你的站点对扫描器返回的信息足够少、对异常行为的封禁足够快、对敏感路径的拦截足够彻底时,绝大多数自动化扫描工具会在探测阶段就放弃目标。安全加固不是一劳永逸的事情,需要根据扫描手法的变化持续调整策略,但上述措施已经能够抵御市面上绝大部分批量扫描攻击。
