【SELinux】解决 systemd 服务因权限问题无法启动(203/EXEC)的完整方案
【SELinux】解决 systemd 服务因权限问题无法启动(203/EXEC)的完整方案
这个问题本人花了一天才解决
在 Linux(CentOS / RHEL / Fedora / OpenEuler 等)启用 SELinux 时,有时我们会遇到这样的问题:
你写了一个自定义 systemd 服务(例如 demo.service
):
[Service]
ExecStart=/home/rytec/anaconda3/envs/demo/bin/python3.8 /home/demo.py
❌ 问题现象
✅ 手动运行脚本一切正常
✅ 执行
setenforce 0
(关闭 SELinux)后能启动❌ 但启用 SELinux (
setenforce 1
) 时,systemctl start demo.service
报错:
Main process exited, code=exited, status=203/EXEC
原因:SELinux 默认阻止 systemd 执行 /home
目录下的程序或脚本。
✅ 解决步骤
步骤 1:安装 SELinux 工具
如果系统还没有 semanage
命令,需要安装:
sudo yum install -y policycoreutils-python-utils
步骤 2:为 conda 环境的 bin 目录设置执行权限类型
sudo semanage fcontext -a -t bin_t "/home/rytec/anaconda3/envs/demo/bin(/.*)?"
步骤 3:应用新的上下文
sudo restorecon -R /home/rytec/anaconda3/envs/demo/bin
步骤 4:(可选)为你的 Python 脚本设置上下文
sudo semanage fcontext -a -t bin_t "/home/demo.py"
sudo restorecon -v /home/demo.py
步骤 5:验证上下文是否正确
ls -Z /home/rytec/anaconda3/envs/demo/bin/python3.8
应看到:
system_u:object_r:bin_t:s0
而不是:
unconfined_u:object_r:user_home_t:s0 ← 错误的上下文
步骤 6:重启 systemd 服务
sudo systemctl daemon-reload
sudo systemctl restart demo.service
sudo systemctl status demo.service
此时应显示:
Active: active (running)
步骤 7:检查 SELinux 是否还在阻止
sudo ausearch -m avc -ts recent | grep demo
如果没有输出,说明配置成功 🎉
🛡️ 推荐的长期方案(更稳定)
除了修改 SELinux 上下文,还可以用以下更稳定的方法:
方案 A:把启动脚本放在 /usr/local/bin
sudo tee /usr/local/bin/start_demo.sh > /dev/null << 'EOF'
#!/bin/bash
cd /home
exec /home/rytec/anaconda3/envs/demo/bin/python3.8 demo.py
EOFsudo chmod +x /usr/local/bin/start_demo.sh
修改 dianli.service
:
ExecStart=/usr/local/bin/start_demo.sh
/usr/local/bin
默认使用bin_t
上下文,不会被 SELinux 拦截。
方案 B:避免 /home
,把虚拟环境放在 /opt
或 /usr/local
例如:
/opt/demo_env/bin/python3.8
这样天然规避 SELinux 的限制。
📌 总结:核心命令一览
# 安装工具
sudo yum install -y policycoreutils-python-utils# 设置 conda 环境 bin 目录上下文
sudo semanage fcontext -a -t bin_t "/home/rytec/anaconda3/envs/demo/bin(/.*)?"
sudo restorecon -R /home/rytec/anaconda3/envs/demo/bin# (可选)设置 Python 脚本上下文
sudo semanage fcontext -a -t bin_t "/home/demo.py"
sudo restorecon -v /home/demo.py# 重启服务
sudo systemctl daemon-reload
sudo systemctl restart demo.service
sudo systemctl status demo.service# 确认 SELinux 是否还在阻止
sudo ausearch -m avc -ts recent | grep demo
✅ 成功标志
systemctl status
显示active (running)
ausearch
没有新的 SELinux 拒绝日志setenforce 1
下服务依旧能正常运行
🎉 最终效果
通过正确配置 SELinux 上下文或调整部署路径,你的 systemd 服务就能在 SELinux 启用状态下稳定运行了!
这套方案适用于 OpenEuler / CentOS / RHEL / Fedora 等所有启用 SELinux 的系统。