综合 systemd 服务起不来但权限看着都对?先看 SELinux AVC 日志,再查沙盒指令

2026-09-18 21:04:37

systemd 服务启动被拒:从 SELinux AVC 日志到沙盒指令的排查顺序

来源:Linux systemd 服务权限深度排查:从 SELinux 到沙盒配置的完整指南

这类问题跳出了「用户-组-其他」rwx 权限检查的思路。systemd 是深度集成的系统与服务管理器,安全边界比一条 shell 命令复杂:表象是执行命令被拒绝,根源可能藏在文件系统属性、安全模块或路径解析里。

排查维度一:强制访问控制(MAC)的拦截

SELinux(多见于 RHEL/CentOS/Fedora)与 AppArmor(多见于 Ubuntu/Debian)定义了进程能访问哪些资源。传统权限允许的操作,它们同样可以拒绝。

  1. 确认 SELinux 状态:sudo sestatus。状态为 enforcing 时,它很可能就是原因。
  2. 查看实时拒绝日志:
sudo ausearch -m avc -ts recent

也可以直接看审计日志:

sudo grep "avc:.*denied" /var/log/audit/audit.log | tail -20

日志会记录哪个进程(scontext)试图访问哪个资源(tcontext)、被拒绝了什么操作(tclass)。

  1. 解读与修复。假设日志中有一行:
type=AVC msg=… scontext=system_u:system_r:init_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file { read }

含义是运行在 init_t 域的进程试图读取一个标记为 default_t 类型的文件,被拒绝。

  • 临时验证(生产环境慎用):把 SELinux 切到宽容模式确认问题来源:sudo setenforce 0。服务能启动,基本可以确定是 SELinux 问题,但不要把它当永久方案。
  • 正确做法:修改文件安全上下文,用 semanage fcontext 配合 restorecon。应用文件在 /opt/myapp/ 下时,为它设置合适的上下文(如 bin_t):
sudo semanage fcontext -a -t bin_t "/opt/myapp(/.*)?"
sudo restorecon -Rv /opt/myapp

排查维度二:systemd 沙盒指令

systemd 提供了一批以 ProtectPrivateRestrict 开头的沙盒指令来限制服务的运行环境。配置不当,服务会被关在笼子里,访问不到必要资源。

  • ReadWritePathsReadOnlyPaths:显式指定服务可写与只读的路径。服务需要写入的目录不在列表里就会失败。
  • PrivateTmp=yes:服务拥有私有的 /tmp/var/tmp。服务脚本若期望使用系统共享的临时文件,就会出问题。
  • ProtectSystem=strict / ProtectHome=yes:严格保护系统目录与家目录,使其只读或不可访问。
  • NoNewPrivileges=yes:阻止服务进程提升权限。
  • CapabilityBoundingSet:限制服务可用的 Linux 能力(Capabilities)。服务需要绑定 1024 以下端口(如 80),但没有 CAP_NET_BIND_SERVICE、又不是以 root 运行时,在 ProtectSystem=yes 下启动就会失败。

沙盒配置原则

  1. 按服务实际需求放宽限制,而不是全部关闭。服务只需要写 /var/log/myapp,就设置 ReadWritePaths=/var/log/myapp,不必关掉所有保护。
  2. 服务需要特定能力时(例如绑定低端口),可添加:
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=~CAP_NET_BIND_SERVICE

波浪号表示保留该能力。

  1. 临时诊断方法是:在服务文件的 [Service] 段注释掉(或设置为 no)所有 Protect*Private*Restrict* 指令,重载后尝试启动服务。启动成功再逐一加回指令,定位具体是哪条限制导致的问题。改动 unit 文件后可用 systemd-analyze verify 检查语法与指令拼写,再 systemctl daemon-reload 生效。
复制全文 生成海报 Linux systemd 运维 SELinux 故障排查

推荐文章

程序员茄子在线接单