Ubuntu 20.04 使用 systemd 管理服务出现 Permission denied 报错,最常见原因是执行命令时缺少 sudo 权限,其次是 AppArmor 安全策略拦截或单位文件权限配置错误。普通用户无法直接控制系统服务,必须在 root 权限下操作或修正安全策略。
先说结论:绝大多数 Permission denied 报错是因为当前用户缺乏 root 权限,需在命令前加 sudo 解决。
- 先确认:检查执行命令前是否添加了 sudo 前缀
- 先处理:修正单位文件权限或调整 AppArmor 安全策略
- 再验证:通过 systemctl status 和 journalctl 确认服务状态
命令速用版
遇到权限报错时,优先尝试在命令前添加 sudo 提权执行。
sudo systemctl start 服务名 sudo systemctl status 服务名
如果添加 sudo 后仍然报错,查看系统日志定位具体拒绝原因。
sudo journalctl -xe
为什么会这样
systemd 管理操作默认需要 root 权限,普通用户直接执行会被内核拒绝。
Ubuntu 20.04 默认使用 systemd 作为初始化系统,其设计原则是服务管理涉及系统核心配置,必须经过权限认证。除了基础的用户权限控制,Ubuntu 默认启用的 AppArmor 安全模块也可能拦截未授权的二进制执行或文件访问,导致即使有 sudo 仍出现 Permission denied。
分步处理
按顺序排查权限问题,从最简单的命令提权到复杂的安全策略调整。
步骤 1:确认命令是否提权
检查终端提示符是否为 root,或命令前是否有 sudo。如果不是,加上 sudo 重试。
sudo systemctl restart nginx
步骤 2:检查单位文件权限
如果是自定义服务,检查 unit 文件归属和权限。文件应属于 root,权限通常为 644。
ls -l /etc/systemd/system/服务名.service sudo chmod 644 /etc/systemd/system/服务名.service sudo chown root:root /etc/systemd/system/服务名.service
步骤 3:排查 AppArmor 拦截
查看 syslog 中是否有 AppArmor 拒绝记录。如果有,需调整策略或将其设为 complain 模式测试。
sudo grep apparmor /var/log/syslog
怎么验证是否生效
执行状态查询命令,确认服务处于 active (running) 状态且无权限报错。
systemctl is-active 服务名
返回 active 表示成功。同时查看日志末尾是否有 Permission denied 字样。
sudo journalctl -u 服务名 -n 20
常见坑
- 不要直接修改/lib/systemd 下的文件,系统更新会覆盖,应放在/etc/systemd/system
- Ubuntu 默认使用 AppArmor 而非 SELinux,排查安全策略时方向不要搞错
- 脚本文件本身如果没有执行权限(chmod +x),systemd 启动时也会报权限错误
常见问题
为什么加了 sudo 还是 Permission denied
可能是 AppArmor 拦截或脚本文件缺少执行权限。
检查/var/log/syslog 中是否有 apparmor=DENIED 记录,同时确认服务 ExecStart 指向的脚本文件有 x 权限。
普通用户能否配置 sudo 免密管理特定服务
可以,通过配置/etc/sudoers 文件授权特定命令。
使用 visudo 命令添加规则,允许特定用户组无需密码执行特定 systemctl 命令,但需谨慎配置避免安全风险。
参考来源
- Ubuntu Official Documentation, "systemd"
- systemd man pages, "systemctl"