最有效方式是用location ~* .(conf|log|env|bak|swp|yml|yaml|htaccess|gitignore)$ { return 404; },需锚定结尾、正确分隔扩展名、置于server末尾,并配合location ^~ /.git/ { deny all; }等前缀规则及try_files $uri =404防护php文件泄露。

在 Nginx 中,用 location 块禁止特定文件后缀访问,核心是“正则匹配 + 拒绝响应”,但必须注意匹配精度、大小写、规则顺序和 PHP 类文件的特殊性,否则容易失效。
用 ~* 正则匹配后缀并 deny all 或 return 404
这是最常用方式,适用于 .conf、.log、.env、.bak 等静态敏感文件:
-
必须加
~*:表示大小写不敏感,否则.ENV或.Log仍可访问 -
扩展名之间用
|分隔,括号包裹,例如(conf|log|env);写成(conflog)就变成匹配字面字符串,无效 -
结尾加
$锚定,防止误伤路径(如/api.phpinfo不应被\.php匹配) - 推荐返回
return 404或deny all,语义清晰,避免暴露服务细节
示例配置:
return 404;
}
规则位置必须放在所有功能性 location 之后
Nginx 的匹配优先级是:精确匹配 > ^~ 前缀匹配 > 正则匹配。如果禁止规则写在 location ~ \.php$ 或 location / 前面,就可能被后续更宽泛的块覆盖或绕过。
- 把后缀拦截块放在
server块末尾,确保它不被其他正则 location 覆盖 - 尤其要避开宝塔等面板自动引入的
enable-php-*.conf——那些文件里的 location 可能悄悄覆盖你的规则 - 若站点启用了 PHP,且未做
try_files $uri =404校验,直接请求/config.php可能走静态文件逻辑,导致deny all完全不触发
PHP 文件需额外防护,不能只靠后缀拦截
单纯用 location ~ \.php$ { deny all; } 会直接阻断所有 PHP 执行,不可取。正确做法是双层防护:
- 加一条高优先级前缀匹配:
location ^~ /.php { return 404; },拦截扫描器常构造的畸形路径(如/.phpinfo、/.php?x=1) - 主 PHP 块保持 fastcgi 配置,但开头加上:
try_files $uri =404;,确保只有真实存在的 PHP 文件才进入执行流程 - 避免使用
location ~ \.php$ { deny all; }这类全局屏蔽,它会破坏正常业务
隐藏目录和点开头文件要单独封禁
location ~* \.(env|log)$ 只能拦 /a.env,拦不住 /.git/config 或 /wp-content/.env —— 因为点号不在路径末尾,而是中间字符。
- 显式封禁常见隐藏目录:
location ^~ /.git/ { deny all; }、location ^~ /.svn/ { deny all; } - 通用兜底(慎用):
location ~ /\. { deny all; },匹配路径中含/.的请求(注意不是^/\.,否则会误杀根路径) - 对上传目录等高风险区域,建议嵌套防护,例如在
location ^~ /uploads/内再加一层后缀拦截和脚本禁用











