真正防住文件系统越权访问的关键是早期拦截与权限隔离双保险:在location匹配阶段就用^~或正则拒绝高危路径(如/..、.env、/etc/),严格限定root/alias指向,禁用不安全rewrite,并配合系统级权限最小化加固。

直接用 rewrite 拦截非法请求本身就不安全——它不终止请求,只改路径。真正防住文件系统越权访问(比如 ../etc/passwd、/var/www/.env),关键不是“重写”,而是“不放行”。要靠早期拦截 + 权限隔离双保险。
在 location 匹配阶段就堵死高危路径模式
把最危险的 URI 特征(如路径遍历、敏感文件名)放在 location 块里用 ^~ 或正则直接拒绝,不进后续处理流程:
-
location ^~ /.. { return 403; }—— 所有以/..开头的请求立即 403 -
location ~* \.(env|gitignore|htaccess|log|sql)$ { return 403; }—— 禁止直接访问常见敏感后缀 -
location ~* "/\.\./|/etc/|/proc/|/root/" { return 403; }—— 正则匹配典型越权路径片段
用 root 和 alias 严格限定静态资源根目录
rewrite 后若落到静态文件服务,必须确保 root 或 alias 指向的路径不会被外部路径绕过:
-
root /var/www/public;→ 请求/static/js/app.js映射为/var/www/public/static/js/app.js,但注意:如果 rewrite 生成了/../etc/shadow,Nginx 默认会自动规范化路径,但仍需配合上一条规则双重防护 -
location /files/ { alias /var/www/uploads/; }→ 使用alias更安全,因为它是完整替换,不拼接;而root是追加,易被../突破 - 永远不要写
root /;或root /var/;这类宽泛路径
禁用 rewrite 中可能触发文件探测的操作
某些看似无害的 rewrite 写法,实际会间接暴露文件系统结构或触发不安全判断:
- 避免在
if中用-f $request_filename或-d $request_filename判断文件存在性——Nginx 官方明确不推荐,且变量值可能被恶意构造影响判断逻辑 - 不要用
rewrite ... last把请求导向一个未设权限限制的location /,否则可能绕过前面的保护 - 若需“文件不存在时 fallback”,优先用
try_files $uri $uri/ /index.html =404;,它比if (!-e)+rewrite更高效、更安全
配合系统级权限最小化加固
Nginx 进程本身也要受限,不能靠配置 alone 拦住所有越权:
- 运行 Nginx 的 worker 进程用户(如
www-data)应仅对/var/www/public等必要目录有读取权限,对/etc、/root、项目配置目录等完全无权限 - 上传目录(如
/var/www/uploads)禁用执行权限:chmod -R a-x /var/www/uploads - 敏感配置文件(
.env、nginx.conf)设为600,属主为 root,Nginx 工作用户不可读











