documentroot 本身不参与沙箱隔离,需将其路径显式纳入 apparmor 策略(如 /srv/www/example.com/public/** r,)并配合 systemd sandbox(如 readwritepaths=、protectsystem=strict)限定访问边界,避免指向 /tmp 或家目录等沙箱盲区。

DocumentRoot 本身不参与进程沙箱或内核级隔离,它只是 Apache 配置里的一个路径声明。要真正用 AppArmor 或其他安全沙箱(如 systemd service sandboxing、seccomp)隔离站点目录,必须把 DocumentRoot 路径作为**受控资源纳入策略范围**,而不是只改配置文件就完事。
AppArmor 策略中显式约束 DocumentRoot 路径
AppArmor 是基于路径的强制访问控制机制,对 DocumentRoot 的保护必须体现在 profile 中:
- DocumentRoot 所在目录(如 /srv/www/example.com/public)必须在 profile 里用 read 权限明确声明;若需执行 PHP 脚本,还要加 ix(继承执行)或 px(profile 换入)权限
- 禁止递归允许上级路径,比如不能写 /srv/** rw,,而应精确到 /srv/www/example.com/public/** r,
- 上传目录(如 /srv/www/example.com/uploads/)必须单独限制:只允许 w,禁止 ix 和 link,防止上传恶意脚本被执行或符号链接逃逸
- 确保 Apache 进程运行用户(如 www-data)被 profile 绑定,且该 profile 在服务启动时已加载:sudo aa-status | grep apache2
配合 systemd 沙箱强化 DocumentRoot 访问边界
Ubuntu 18.04+ 默认使用 systemd 管理 Apache,可利用其 sandboxing 选项进一步收紧 DocumentRoot 所在文件系统的访问:
- 编辑 /etc/systemd/system/multi-user.target.wants/apache2.service 或创建 drop-in 文件,在 [Service] 下添加:
ProtectSystem=strict(禁止写 /usr、/boot、/etc)
ProtectHome=true(屏蔽 /home、/root)
ReadWritePaths=/srv/www/example.com/public /srv/www/example.com/uploads(仅放行 DocumentRoot 及必要子目录) - 禁用危险能力:CapabilityBoundingSet=CAP_NET_BIND_SERVICE(只保留绑定端口能力),移除 CAP_SYS_ADMIN、CAP_DAC_OVERRIDE 等
- 重启生效:sudo systemctl daemon-reload && sudo systemctl restart apache2
避免常见误配导致沙箱失效
即使启用了 AppArmor 和 systemd sandbox,以下配置错误会让 DocumentRoot 实际处于“裸奔”状态:
- DocumentRoot 指向 /tmp、/var/tmp 或用户家目录(如 /home/deploy/app)——这些路径通常不在 AppArmor 默认 profile 覆盖范围内,也容易被 systemd 的 Protect* 选项忽略
- Apache 配置中启用 FollowSymLinks 且目标指向沙箱外路径(如 /home/shared/assets),会绕过路径级限制
- PHP 应用通过 include() 或 file_get_contents() 动态拼接路径,读取了未在 AppArmor profile 中声明的配置文件(如 /etc/myapp/config.yaml),触发拒绝日志但不报错,造成隐蔽越权
- 忘记为 mod_security 或自定义模块的规则目录(如 /etc/modsecurity)添加 AppArmor 读权限,导致 WAF 失效,间接放大 DocumentRoot 暴露风险











