Ubuntu/Debian 安装 Nginx 后 AppArmor 默认策略权限过严,需根据自定义路径(网站根目录、PHP-FPM 套接字、SSL 证书、日志等)手动添加精确规则,并重载策略后重启服务;调试时可用 complain 模式配合 aa-logprof 生成规则,生产环境须保持 enforce 模式。

Ubuntu/Debian 系统通过 apt install nginx 安装 Nginx 后,默认已启用 AppArmor,并自带基础配置文件 /etc/apparmor.d/usr.sbin.nginx。但该配置默认仅允许最小权限(如仅读取配置、日志路径和静态文件),若你自定义了网站根目录、PHP-FPM 套接字路径、SSL 证书位置或使用了 Lua 模块等,AppArmor 很可能因拒绝访问而报错(operation not permitted 或 Permission denied),导致 Nginx 启动失败或服务异常。
确认 AppArmor 是否运行且 Nginx 已加载策略
执行以下命令检查状态:
-
sudo aa-status— 查看整体状态,确认apparmor module is enabled且/usr/sbin/nginx在“profiles are loaded”列表中 -
sudo aa-status | grep nginx— 快速确认 Nginx 进程是否处于 enforce 模式(非 complain) -
sudo journalctl -u nginx --since "1 hour ago" | grep -i denied— 检查近期是否有 AppArmor 拒绝日志
根据实际路径补充 AppArmor 规则
编辑主配置文件:sudo nano /etc/apparmor.d/usr.sbin.nginx,在 /usr/sbin/nginx PUx, 下方添加你需要的路径规则。常见需追加的条目包括:
- 自定义网站根目录(如
/var/www/myapp):/var/www/myapp/** r,(只读)或/var/www/myapp/** rwk,(读写创建+锁) - PHP-FPM Unix 套接字(如
/run/php/php8.1-fpm.sock):/run/php/php*.sock rw, - SSL 证书与密钥(如
/etc/ssl/private/mydomain.key):/etc/ssl/private/** r,(密钥建议仅 root 可读,AppArmor 中只需声明读权限) - 自定义日志路径(如
/var/log/nginx/myapp.access.log):/var/log/nginx/myapp.* log,(log是 AppArmor 特殊权限,等价于rw+ 自动处理日志轮转)
⚠️ 注意:路径末尾带 /** 表示递归;* 是通配符;避免使用过于宽泛的规则如 /var/**,应精确到具体子目录。
重新加载 AppArmor 并验证
保存配置后执行:
-
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx— 重载单个策略 -
sudo systemctl restart nginx— 重启 Nginx,观察是否启动成功 -
sudo aa-status --verbose | grep nginx— 确认策略已生效且无语法错误
若仍报错,可临时切换为 complain 模式收集完整拒绝事件:sudo aa-complain /usr/sbin/nginx,复现请求后再用 sudo aa-logprof 交互式生成建议规则。
调试技巧与安全提醒
AppArmor 日志默认输出到 /var/log/audit/audit.log(若 auditd 启用)或 /var/log/syslog(含 apparmor="DENIED" 字样)。建议:
- 生产环境保持 enforce 模式,勿长期使用 complain
- 每次修改后都用
sudo apparmor_parser -t /etc/apparmor.d/usr.sbin.nginx测试语法 - Nginx 主进程(master)和工作进程(worker)共用同一 profile,无需单独配置
- 若使用 Docker 或 systemd 服务封装 Nginx,AppArmor 策略需额外适配容器上下文或 service unit 的
AppArmorProfile=设置










