disable_symlinks指令必须置于server或location块中且配合root/alias使用,用于在文件读取阶段校验路径是否越界,防止符号链接跳转至敏感目录,不支持http块配置。

disable_symlinks 是 Nginx 中用于防御符号链接越权访问的关键指令,但它**不能随意放置**——用错位置不仅无效,还会导致服务启动失败。它的核心作用是在文件读取阶段(如 alias、try_files、open_file_cache)实时校验路径是否始终落在可信目录内,从而阻断通过软链跳转到 /etc、/var/log 等敏感路径的攻击。
为什么不能写在 http 块里?
该指令依赖两个运行时上下文才能工作:一是当前请求解析出的 URI 路径,二是该 location 实际生效的 root 或 alias 目录。http 块是全局配置入口,不绑定任何具体路径或根目录,Nginx 无法在此阶段判断“越界”与否。若强行写入,启动时会报错:
"disable_symlinks" directive is not allowed here所以它只允许出现在 server 或 location 块中,且必须与 root/alias 配合使用。
正确配置方式与典型场景
最常见也最有效的用法是在使用 alias 的静态资源 location 中启用:
-
基础写法:
disable_symlinks on from=/var/www/static/; -
增强写法(推荐):
disable_symlinks on if_not_owner from=/var/www/static/;—— 在检查路径合法性的同时,还要求符号链接目标文件的所有者必须与 Nginx worker 进程用户一致,进一步收紧权限 - from 路径必须是绝对路径,末尾斜杠建议保留,尤其当目标是目录时(如 /var/www/static/),避免因路径拼接引发误判
例如,攻击者构造请求 /static/../etc/passwd,若该路径最终经软链解析后落在 /var/www/static/ 外,则 Nginx 直接返回 403 Forbidden,不进行后续文件读取。
它管什么、不管什么?
disable_symlinks 只干预 Nginx **自身发起的文件系统操作**,包括:
- 由
alias或root指令触发的路径解析 -
try_files对候选文件的检查 -
open_file_cache中对文件元信息的读取
但它对以下行为完全无效:
-
proxy_pass、fastcgi_pass等反向代理类指令 —— 这些请求由后端服务处理,Nginx 不参与其文件读取 - PHP 的
file_exists()、readfile()等函数调用 —— 属于应用层行为,需在代码中用realpath()+ 基目录比对来防护
实际部署注意事项
即使配置语法正确,也可能因环境限制失效:
- SELinux 或 AppArmor 启用时,可能拦截 symlink 检测所需的系统调用,需结合 error_log 查看 “Operation not permitted” 类错误
- 老旧 OpenSSL 版本或 overlayfs 等非标准文件系统下,部分符号链接解析逻辑可能异常
- 容器环境中,若挂载路径未对齐
from=指定的物理路径(如宿主机 /data 映射为容器内 /var/www/static),会导致检查失准
若 Nginx 版本低于 1.11.1(不支持该指令),应改用权限控制+chroot/容器隔离+应用层路径校验的组合策略。


















