关键在于确保nginx能读取软链接指向的真实文件且防逃逸:优先用alias(末尾带斜杠)替代root,location内配置disable_symlinks on from=绝对路径或off,nginx用户需对软链所在目录、目标路径及所有父目录具备r-x权限,并规避selinux/apparmor拦截与恶意软链注入。

要让 Nginx 安全地访问软链接指向的静态资源目录,关键不是“让 Nginx 解析软链接”,而是确保它最终能读取到真实文件,同时防止路径逃逸。这需要指令选择、权限配置和安全策略三者配合。
优先用 alias + 软链接,避免 root 拼接风险
alias 更适合软链接场景,因为它直接替换匹配的 URI 路径,不拼接,语义清晰:
- 例如:location /static/ { alias /data/releases/current/; },其中 /data/releases/current 是软链接 → /data/releases/v2.3.1,请求 /static/js/app.js 就映射到 /data/releases/current/js/app.js,再由系统解析为真实路径
- 而 root 会把完整 URI 追加过去,比如 root /data/releases; + 请求 /static/,会去找 /data/releases/static/ —— 若该路径是软链接,就容易失控,还可能意外暴露上级目录
- alias 路径末尾必须加斜杠(如 /data/releases/current/),否则解析错误;root 则无此限制
必须显式启用或禁用 disable_symlinks
该指令不能写在 http 或 server 块,只能放在 location 内,且行为取决于你想要的安全模型:
- 若需允许软链接访问(如发布版本切换),必须加:disable_symlinks off;
- 若要防止越权访问(如禁止跳转到 /etc/),应启用拦截:disable_symlinks on from=/var/www/static/; —— Nginx 会逐级检查软链接目标是否全部落在 /var/www/static/ 内,超出即返回 403
- 注意:它只对 root/alias/try_files 等本地文件读取生效,对 proxy_pass 无效
权限必须覆盖软链接本身及其所有父目录
Nginx worker 进程(如 www-data)需对以下三类路径都具备 r-x 权限:
- 软链接所在目录(如 /data/releases)
- 软链接指向的目标路径(如 /data/releases/v2.3.1)
- 目标路径的所有上级目录(/data、/ 等),尤其是 /home/user 类目录默认无执行权,常导致 403
警惕 SELinux/AppArmor 和恶意软链接注入
即使权限正确,强制访问控制机制仍可能拦截:
- SELinux 策略(如 httpd_can_network_connect)或 AppArmor 配置可能限制文件读取,需检查 audit.log 并调整策略
- 生产环境应禁用用户在静态目录中创建软链接的能力,例如设置 chmod o-w /var/www/static 或 chattr +a(仅追加)
- 避免使用相对路径软链接(如 ln -s ../data/uploads ./uploads),Nginx 解析时以 worker 工作目录为基准,极易引发路径失控











