Debian CUPS脚本被 AppArmor 拦截问题
一、排查流程
步骤 1:开启 CUPS 调试日志,确认脚本是否被触发
修改 /etc/cups/cupsd.conf:
|
1 |
LogLevel debug2 |
重启 CUPS:
|
1 |
systemctl restart cups |
打印一张测试页后,查看日志:
|
1 |
tail -f /var/log/cups/error_log |
判断点:
日志里出现 [Job XXX] /usr/local/sbin/lims_cups_pdf.sh: … → 脚本已触发,问题在脚本内部
日志里完全没出现脚本路径 → CUPS 流程没走到 PostProcessing,需检查 cups-pdf.conf
步骤 2:识别”权限不够”类报错
典型报错样例(关键证据):
|
1 2 3 4 |
[Job 112601] /usr/local/sbin/lims_cups_pdf.sh: 行 5: /etc/openvpn/vpn.set: 权限不够 [Job 112601] /usr/local/sbin/lims_cups_pdf.sh: 行 24: /usr/bin/date: 权限不够 [Job 112601] /usr/local/sbin/lims_cups_pdf.sh: 行 29: /usr/bin/mkdir: 权限不够 [Job 112601] /usr/local/sbin/lims_cups_pdf.sh: 行 43: /usr/bin/mysql: 权限不够 |
判断点:脚本本身能执行,但内部命令/文件被拒 → 几乎 100% 是 AppArmor 拦截。
步骤 3:核对 AppArmor 内核审计日志
|
1 2 3 |
journalctl -k -g apparmor -n 200 --no-pager dmesg | grep -i apparmor grep -i denied /var/log/syslog |
典型 DENIED 日志样例:
|
1 2 3 |
apparmor="DENIED" operation="exec" profile="/usr/lib/cups/backend/cups-pdf" name="/usr/bin/date" apparmor="DENIED" operation="open" profile="/usr/lib/cups/backend/cups-pdf" name="/etc/openvpn/vpn.set" apparmor="DENIED" operation="open" profile="/usr/lib/cups/backend/cups-pdf" name="/dev/tty" |
判断点:profile= 后面是 /usr/lib/cups/backend/cups-pdf 即坐实是该 profile 拦的。
步骤 4:查看 AppArmor 状态
|
1 |
aa-status |
如果命令不存在:
|
1 2 |
apt update apt install apparmor-utils |
确认 cups-pdf profile 是否处于 enforce 模式:
|
1 |
/usr/lib/cups/backend/cups-pdf |
出现在 enforce mode 列表里 = 强制拦截中。
步骤 5:检查是否存在 profile 重复定义
二、解决方案
2.1 处理原则
1. 同名 profile 只允许一个定义源
2. 不要直接修改系统默认 profile(升级会被覆盖)
3. 自定义规则放到 local/ 覆盖文件(系统 profile 末尾通常已有 #include if exists <local/…>)
4. 复杂脚本依赖建议走 complain 模式收集 + 最小放行,不要直接关闭 AppArmor
2.2 处理步骤
第 1 步:消除 profile 重复定义
如果存在自定义同名 profile 文件,先备份并移走:
|
1 |
mv /etc/apparmor.d/lims-cups-pdf /etc/apparmor.d/lims-cups-pdf.bak |
确认 /etc/apparmor.d/usr.sbin.cupsd 末尾包含:
|
1 |
#include if exists <local/usr.lib.cups.backend.cups-pdf> |
第 2 步:在 local 覆盖文件中加最小权限规则
编辑(不存在则新建):
|
1 |
vim /etc/apparmor.d/local/usr.lib.cups.backend.cups-pdf |
写入合并去重后的规则:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# 允许执行常用命令 /{usr/,}bin/* ixr, /usr/local/sbin/* ixr, # 业务输出目录 /home/files/** rw, # PDF 输出目录 @{HOME}/PDF/ rw, @{HOME}/PDF/* rw, # 业务依赖配置文件 /etc/openvpn/vpn.set r, /etc/papersize r, /etc/magic r, /etc/mysql/** r, /etc/cups/cups-pdf.conf r, /etc/cups/ppd/*.ppd r, # Ghostscript 与 cups-pdf 相关 /usr/bin/gs ixr, /usr/lib/cups/backend/cups-pdf mr, /usr/lib/ghostscript/** mr, /usr/share/** r, # 日志与队列目录 /var/log/cups/cups-pdf*_log w, /var/spool/cups/** r, /var/spool/cups-pdf/** rw, # 兼容脚本对 tty 的访问(不推荐,建议改脚本去依赖) /dev/tty rw, |
第 3 步:重新加载 AppArmor 规则
|
1 2 |
apparmor_parser -r /etc/apparmor.d/usr.sbin.cupsd systemctl restart cups |
第 4 步:验证
打印一张测试页,然后:
|
1 2 |
tail -n 200 /var/log/cups/error_log journalctl -k -g apparmor -n 100 --no-pager |
预期结果:
error_log 不再出现 权限不够
内核审计日志不再出现 DENIED 关于 cups-pdf 的条目
业务逻辑(PDF 归档、MySQL 写入等)正常完成
三、辅助命令速查
3.1 AppArmor 模式切换(仅排障用)
|
1 2 3 4 5 |
# 切换到 complain(不拦截,仅记录) sudo aa-complain /usr/lib/cups/backend/cups-pdf # 切换回 enforce(强制拦截) sudo aa-enforce /usr/lib/cups/backend/cups-pdf |
complain 模式只用于排障:会降低安全性,相当于临时拆掉防护,定位完缺失规则后必须切回 enforce。
3.2 查看 profile 加载情况
|
1 2 |
aa-status apparmor_parser -p /etc/apparmor.d/usr.sbin.cupsd |
3.3 重新加载某个 profile
|
1 |
apparmor_parser -r /etc/apparmor.d/usr.sbin.cupsd |
4.4 CUPS 调试
|
1 2 3 4 5 6 7 8 |
# 查看打印任务列表 lpstat -o # 查看打印机列表 lpstat -p # 查看错误日志 tail -f /var/log/cups/error_log # 重启 CUPS systemctl restart cups |