一、排查流程

步骤 1:开启 CUPS 调试日志,确认脚本是否被触发

修改 /etc/cups/cupsd.conf:

重启 CUPS:

打印一张测试页后,查看日志:

判断点

日志里出现 [Job XXX] /usr/local/sbin/lims_cups_pdf.sh: … → 脚本已触发,问题在脚本内部
日志里完全没出现脚本路径 → CUPS 流程没走到 PostProcessing,需检查 cups-pdf.conf

步骤 2:识别”权限不够”类报错

典型报错样例(关键证据):

判断点:脚本本身能执行,但内部命令/文件被拒 → 几乎 100% 是 AppArmor 拦截

步骤 3:核对 AppArmor 内核审计日志

典型 DENIED 日志样例:

判断点:profile= 后面是 /usr/lib/cups/backend/cups-pdf 即坐实是该 profile 拦的。

步骤 4:查看 AppArmor 状态

如果命令不存在:

确认 cups-pdf profile 是否处于 enforce 模式:

出现在 enforce mode 列表里 = 强制拦截中。

步骤 5:检查是否存在 profile 重复定义


警示信号:如果出现两个文件都包含 /usr/lib/cups/backend/cups-pdf { … },例如:

/etc/apparmor.d/usr.sbin.cupsd(系统默认)
/etc/apparmor.d/lims-cups-pdf(自定义)
执行 aa-complain 时会报错:

ERROR: Conflicting profiles for /usr/lib/cups/backend/cups-pdf defined in two files
必须先消除冲突,否则规则加载行为不可预期。

二、解决方案

2.1 处理原则

1. 同名 profile 只允许一个定义源
2. 不要直接修改系统默认 profile(升级会被覆盖)
3. 自定义规则放到 local/ 覆盖文件(系统 profile 末尾通常已有 #include if exists <local/…>)
4. 复杂脚本依赖建议走 complain 模式收集 + 最小放行,不要直接关闭 AppArmor

2.2 处理步骤

第 1 步:消除 profile 重复定义

如果存在自定义同名 profile 文件,先备份并移走:

确认 /etc/apparmor.d/usr.sbin.cupsd 末尾包含:

第 2 步:在 local 覆盖文件中加最小权限规则

编辑(不存在则新建):

写入合并去重后的规则:

第 3 步:重新加载 AppArmor 规则

第 4 步:验证

打印一张测试页,然后:

预期结果

error_log 不再出现 权限不够
内核审计日志不再出现 DENIED 关于 cups-pdf 的条目
业务逻辑(PDF 归档、MySQL 写入等)正常完成

三、辅助命令速查

3.1 AppArmor 模式切换(仅排障用)

complain 模式只用于排障:会降低安全性,相当于临时拆掉防护,定位完缺失规则后必须切回 enforce。

3.2 查看 profile 加载情况

3.3 重新加载某个 profile

4.4 CUPS 调试