背景
我正在通过 SystemD 设置基于 SSH 服务的 rsync 备份。由于本地 SElinux 的问题,此操作最终无法运行;以下是可复现的最小示例:
[Unit]
Description=Rsync backup service
[Service]
Type=oneshot
User=myuser
ExecStart=/usr/bin/ssh -vvv 192.168.1.10 "ls -lah"
如果我setenforce 0
在启动服务之前一切正常,我就能得到请求的目录列表。但如果 SElinux 正在强制执行,我就会收到来自 SystemD 的错误:
Starting backup.service - Rsync backup service...
backup.service: Main process exited, code=exited, status=203/EXEC
backup.service: Failed with result 'exit-code'.
Failed to start backup.service - Rsync backup service
同样,如果我通过带有 rsync 的 SystemD 运行,我会看到子进程以 -13 终止:
rsync: [sender] Failed to exec /usr/bin/ssh: Permission denied (13)
我已检查过的内容
无论 SElinux 的强制状态如何,从终端运行时所有命令都会按预期工作。
我正在以我的用户身份运行(
ExecStart=/usr/bin/whoami
):whoami[726624]: myuser
我可以访问 ssh 二进制文件(
ExecStart=/usr/bin/which ssh
):which[727067]: /usr/bin/ssh
我可以访问我的用户
.ssh
目录(由于显而易见的原因,不发布该目录的日志)。根据这篇SO 帖子,SElinux 可以阻止非标准端口。我只允许使用标准端口(rsync 会使用其他端口吗?),但这应该没问题,因为基本测试用例没有使用其他端口:
# semanage port -l | grep ssh ssh_port_t tcp 22
问题
尽管使用标准端口并且对所涉及的文件拥有完全权限,什么原因会导致 SElinux 仅阻止来自 SystemD 的 SSH 尝试?
编辑1
明确检查拒绝消息:
# ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR
...
type=AVC msg=audit(1743626691.891:17160): avc: denied { execute } for pid=728337 comm="(ssh)" name="ssh" dev="dm-0" ino=3077371 scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:ssh_exec_t:s0 tclass=file permissive=0
# journalctl -t setroubleshoot
-- No entries --
# dmesg | grep -i -e type=1300 -e type=1400
#
我承认,我的 SElinux 不太好,我不太确定该怎么办。我翻阅了文档,但有时……文档……真的……冗长。
我无法提供所有相关细节 - 我正在阅读我的第一本 SElinux 书籍......
基本问题是您的 systemd 单元没有在与您的终端相同的 SElinux 环境中运行。
您可以从审计消息中看到尝试了什么但失败了:
因此,正如预期的那样,该单元运行(启动),
init_t
然后尝试域转换ssh_exec_t
(要执行的二进制文件的上下文)。我看到两种方法:
我从这个答案中得知,有一种间接的方法可以不受限制地运行单元:使用调用
ssh
并将脚本标记为的包装脚本bin_t
。允许政策转型
这超出了我目前对 SELinux 的了解。我发现这可能很简单,但我不知道这个建议是否正确。