直接看 error.log 中反复出现的 “open() ... failed (2: no such file or directory)” 记录,尤其是针对 /.git/config、.env 等敏感路径的错误,是识别恶意目录扫描最直接、最可靠的信号;需结合客户端 ip、请求时间、路径语义及高频关键词综合研判。

直接看 error.log 里反复出现的 “No such file or directory” 错误,尤其是针对敏感路径的 404 类错误在 error.log 中的显式记录,是识别恶意目录扫描最直接、最可靠的信号。
盯住 error.log 中的 open() 失败记录
Nginx 在尝试读取不存在的文件或目录时,会在 error.log 中写入明确的 open() ... failed (2: No such file or directory) 行。攻击者扫描常见敏感路径(如 /.git/config、/wp-admin/、/backup.zip、/etc/passwd)时,只要这些路径实际不存在,Nginx 就会留下这类日志。
- 典型日志行示例:
2025/09/11 18:25:17 [error] 14212#0:*1953 open() "/usr/local/nginx/html/.git/config" failed (2: No such file or directory), client: 16.112.26.214, request: "GET /.git/config HTTP/1.1" - 关键字段:错误类型
[error]、系统错误码(2: No such file or directory)、失败路径(含.git、.env、phpmyadmin等)、客户端 IP 和完整请求行。
筛选高频敏感路径与异常 IP
单条错误不说明问题,但同一路径被多个不同 IP 反复请求,或同一 IP 在数小时内持续探测多个敏感路径,就构成强扫描特征。
- 快速提取所有含敏感关键词的 error.log 记录:
grep -i '\.git\|\.env\|phpmyadmin\|wp-admin\|backup\.\|robots\.txt\|/etc/passwd' /var/log/nginx/error.log - 统计哪些 IP 最常触发此类错误:
awk '/No such file or directory/ && /(\.git|\.env|phpmyadmin)/ {print $12}' /var/log/nginx/error.log | sort | uniq -c | sort -nr | head -10
(注意:$12 是 client IP 字段,具体位置需根据你的 error.log 格式确认,常见为第12或第13列) - 查看某 IP 扫描了哪些路径:
grep 'client: 16.112.26.214' /var/log/nginx/error.log | grep 'No such file'
结合时间窗口与路径语义判断意图
真正的扫描行为具有明显的时间规律和路径逻辑,不是随机乱访。
- 检查是否集中在短时间(如10分钟内)爆发大量同类错误;
- 观察路径是否成组出现——例如连续访问
/.git/config、/.git/HEAD、/.git/index,或依次试探/admin/、/administrator/、/wp-login.php; - 留意请求中是否含编码绕过痕迹,如
%2e%2e%2f(即../)、//、空格 URL 编码等,这往往是自动化工具的标志。
不要只依赖 access.log 的 404 统计
access.log 中的 404 状态码本身很常见,可能来自死链、用户误输或搜索引擎爬虫。而 error.log 中的 open() failed 记录更“硬”:它表明 Nginx 确实去磁盘上找过这个路径,且没找到——这对目录扫描来说是更精准的行为证据。尤其当多个 IP 都在扫同一个非业务路径(比如所有人在扫 /.git/config),基本可判定为恶意探测。











