敏感文件泄露防护是 Web 安全中最容易被忽视的环节:攻击者通过批量扫描 /.git/config、/.env、/backup.zip 等常见路径,一旦命中即可获取完整源码或数据库凭据,进而实现接管。本文基于 Nginx 给出一套完整的敏感文件拦截配置,包含验证方法与泄露后的应急处理。
适用场景
- 站点目录由 Git 管理,部署时
.git目录随之发布到 Web 根目录 - 项目根目录残留
.env、config.php.bak、*.sql等开发调试文件 - 运维人员习惯将备份压缩包临时放在 Web 根目录下
- 网站上线前做安全基线检查,需统一收敛文件暴露面
前置条件
- Nginx 1.x,具备配置文件修改与重载权限
- 清楚站点的
server块配置文件位置 - 本地有 curl 或浏览器用于验证
原理说明
自动化扫描器会批量探测以下高危路径,命中任何一个都可能导致严重后果:
/.git/HEAD、/.git/config:使用 git-dumper 等工具可完整还原源码仓库,包括历史提交中误提交的密码与 API Key/.env:Laravel 等框架的环境配置文件,通常包含数据库、Redis、邮件服务凭据*.sql、*.bak、*.zip:数据库导出与代码备份,直接下载数据/.svn/entries:SVN 版本信息泄露/phpinfo.php:暴露服务器路径、扩展、环境变量等敏感信息
防护思路是在 Nginx 层直接拒绝访问,即使文件真实存在,攻击者也无法读取。返回 404 而非 403,可避免向扫描器确认目标存在。
操作步骤
1. 拦截隐藏目录与版本控制目录
在站点 server 块中加入以下配置。注意使用 (?!well-known) 负向断言保留 /.well-known/ 路径,否则会阻断 Let’s Encrypt 证书验证:
location ~ /\.(?!well-known) {
deny all;
return 404;
}
2. 拦截高危后缀与备份文件
location ~* \.(env|sql|bak|old|swp|conf|ini|tar|gz|tgz|zip|7z|rar)$ {
deny all;
return 404;
}
若站点存在正常的压缩包下载业务,将该规则改为仅拦截 Web 根目录下的文件,并对下载目录单独放行:
location ~* ^/downloads/.*\.(zip|tar\.gz)$ {
allow all;
}
location ~* \.(env|sql|bak|old|swp|conf|ini|tar|tgz|zip|7z|rar)$ {
deny all;
return 404;
}
Nginx 的 location 正则匹配按顺序生效,放行规则必须写在前面。
3. 关闭目录列举
确认未开启自动索引,防止目录结构直接暴露:
autoindex off;
4. 限制上传目录的 PHP 执行
顺手加固:上传目录不允许执行 PHP,阻断 WebShell 落地后的直接利用:
location ~* ^/(uploads|files)/.*\.php$ {
deny all;
}
5. 重载配置
nginx -t && systemctl reload nginx
配置验证
依次请求以下路径,预期全部返回 404:
curl -I https://www.example.com/.env
curl -I https://www.example.com/.git/config
curl -I https://www.example.com/db_backup.sql
curl -I https://www.example.com/site.zip
同时验证 /.well-known/ 未被误伤(证书续期依赖):
curl -I https://www.example.com/.well-known/acme-challenge/test
常见问题
FAQ 1:拦截 .zip 后影响正常下载怎么办?
按照步骤 2 的方式,用更精确的 location 将下载目录(如 /downloads/)单独放行,并确保放行规则写在拦截规则之前;或者拦截规则只匹配 ^(?!/downloads/) 开头的路径。业务文件建议存储到对象存储而非 Web 根目录,从根本上避免误伤。
FAQ 2:文件已经被扫描下载过,如何补救?
首先确认暴露时间:在访问日志中检索扫描痕迹:grep -E '\.(env|git|sql|bak)' /var/log/nginx/access.log。然后执行应急三步:① 立即轮换全部泄露凭据,包括数据库密码、Redis 密码、第三方 API Key、邮件授权码;② 若 .git 被访问,历史提交一律视为已泄露,使用 BFG Repo-Cleaner 清理敏感文件后重置所有凭据;③ 物理删除 Web 根目录中的 .env、备份包等文件,配置仅是兜底而非根治。
总结
敏感文件泄露属于典型的低成本高危漏洞:攻击成本几乎为零,命中后可直接接管站点。Nginx 层拦截配置一次部署长期有效,但必须配合源头治理——版本控制目录不发布到生产环境、备份文件不落 Web 根目录、凭据定期轮换。建议将上述 curl 验证命令纳入上线检查清单。