selinux 没有关闭导致ssh 无法免密连接问题
selinux
集成在 Linux
内核中。它的核心目标是通过精细化权限控制,限制进程和用户对系统资源的访问权限。
1. 问题现象
在没有关闭selinux
下,在机器A 10.42.72.9
执行:
ssh-keygen
ssh-copy-id root@10.42.72.10
,将公有证书id_rsa.pub
写到机器B10.42.72.10
的/root/.ssh/authorized_keys
中;ssh root@10.42.72.10
仍然需要输入密码,这显然不符合预期
临时关闭机器B的selinux
,执行 setenforce 0
后即可连接,这说明是selinux
的策略限制了。
2. 问题排查
先安装包: yum install -y policycoreutils-python-utils
, 安装后才有audit2allow ,semodule,semanage
等命令
2.1. 查看审计日志文件: /var/log/audit/audit.log
sudo grep AVC /var/log/audit/audit.log
type=AVC msg=audit(1744624463.213:420): avc: denied { open } for pid=20655 comm="sshd" path="/etc/pve/priv/authorized_keys" dev="fuse" ino=27 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:fusefs_t:s0 tclass=file permissive=0
type=AVC msg=audit(1744626167.435:699): avc: denied { read } for pid=32937 comm="sshd" name="authorized_keys" dev="fuse" ino=27 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:fusefs_t:s0 tclass=file permissive=0
type=AVC msg=audit(1744626331.692:714): avc: denied { getattr } for pid=33284 comm="sshd" path="/etc/pve/priv/authorized_keys" dev="fuse" ino=27 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:fusefs_t:s0 tclass=file permissive=0
根据日志,问题明确是SELinux
阻止的,对文件没有open, read, getattr
权限,所以主要解决策略问题。另外,由于文件位于FUSE
文件系统,可能需要特殊的文件上下文规则,因为FUSE
挂载的文件系统可能默认使用fusefs_t
类型,而sshd_t
默认不允许访问这种类型。
2.2 查看/root/.ssh/authorized_keys
ls -lh /root.ssh/authorized_keys
lrwxrwxrwx. 1 root root 29 4月 14 16:17 /root/.ssh/authorized_keys -> /etc/xxx/priv/authorized_keys
发现它是另一个文件的软链接。
2.3 确认上下文
ls -Z /etc/xxx/priv/authorized_keys
输出
system_u:object_r:fusefs_t:s0 /etc/pve/priv/authorized_keys
确实是fusefs_t
类型。
3. 创建自定义 SELinux 策略
在机器B上: 通过 audit2allow
生成允许规则:
3.1. 提取 AVC 日志并生成策略模块(推荐)
sudo grep AVC /var/log/audit/audit.log | audit2allow -M sshd_fusefs
3.2. 查看生成的策略文件内容(确保合理性)
cat sshd_fusefs.te
module sshd_fusefs 1.0;
require {
type session_dbusd_tmp_t;
type xdm_t;
type keepalived_t;
type sshd_t;
type fusefs_t;
class sock_file write; # sock_file 没写权限
class dir search; # 目录没search 权限
class file { getattr open read };
}
#============= keepalived_t ==============
allow keepalived_t fusefs_t:dir search;
#============= sshd_t ==============
#!!!! This avc is allowed in the current policy
allow sshd_t fusefs_t:file { getattr open read };
#============= xdm_t ==============
allow xdm_t session_dbusd_tmp_t:sock_file write;
3.3. 编译并加载模块
sudo semodule -i sshd_fusefs.pp
4 验证
从机器A ssh
机器B不需要再输入密码。
sudo ausearch -m AVC | grep denied
# 确认无新拒绝日志
5 自定义te文件
也可以自已编写或修改te
文件
5.1. 编译模块
checkmodule -M -m -o mypolicy.mod mypolicy.te
semodule_package -o mypolicy.pp -m mypolicy.mod
5.2. 加载模块
sudo semodule -i mypolicy.pp
5.3. 验证模块是否加载
sudo semodule -l | grep mypolicy
6 . 设置新上下文
除了步骤3的方式,也可以 修改文件上下文标签
# 临时修复
sudo chcon -t ssh_home_t ~/.ssh/authorized_keys
# 永久修复
sudo semanage fcontext -a -t ssh_home_t "/path/to/authorized_keys"
sudo restorecon -v /path/to/authorized_keys
但是这种方式在上述遇到的问题中没作用。