使用 Fish(通过 Nix 安装)作为 shell 时无法使用 SSH

使用 Fish(通过 Nix 安装)作为 shell 时无法使用 SSH

使用尼克斯包管理器,我已经安装了对于我的登录外壳。我已将外壳添加到/etc/shell:

$ bat /etc/shells | grep --color=auto fish
/home/ajgringo619/.nix-profile/bin/fish

这适用于我的所有系统 - Debian、Fedora、Gentoo、Ubuntu、openSUSE。问题在于软呢帽(使用 v37)和 SSH 连接。虽然我的其他系统都可以工作,但 Fedora 系统声称登录 shell 不存在:

$ which fish
/home/ajgringo619/.nix-profile/bin/fish
$ journalctl -fu sshd.service 
Dec 26 11:30:50 fedora sshd[977]: Server listening on 0.0.0.0 port 22.
Dec 26 11:30:50 fedora sshd[977]: Server listening on :: port 22.
Dec 26 11:30:50 fedora systemd[1]: Starting sshd.service - OpenSSH server daemon...
Dec 26 11:30:50 fedora systemd[1]: Started sshd.service - OpenSSH server daemon.
Dec 26 11:31:46 fedora-cin sshd[2030]: User ajgringo619 not allowed because shell /home/ajgringo619/.nix-profile/bin/fish does not exist
Dec 26 11:31:57 fedora-cin sshd[2030]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.122.1  user=ajgringo619
Dec 26 11:32:00 fedora-cin sshd[2030]: Failed password for invalid user ajgringo619 from 192.168.122.1 port 39226 ssh2
Dec 26 11:32:11 fedora-cin sshd[2030]: Connection closed by invalid user ajgringo619 192.168.122.1 port 39226 [preauth]

在查看中/etc/ssh/sshd_config,自安装以来没有任何变化。任何想法什么软呢帽难道别人都没有这样做吗?当我有的时候这并没有发生通过安装dnf

更新#1:这是一个 selinux 问题。自从将selinux更改为“permissive”后,这个问题就得到了解决。然而,我真的很想编辑 selinux 所做的事情,这样我就可以保留默认设置。

答案1

fish安装通过dnf安装/usr/bin/并具有以下 SELinux 上下文:

$ ls -laZ $(which fish)
-rwxr-xr-x. 1 root root system_u:object_r:shell_exec_t:s0 1721760 Jan 31 15:35 /usr/bin/fish

注意shell_exec_t!现在,让我们通过Nix安装Fish:

# Download Nix
$ sh <(curl -L https://nixos.org/nix/install)

# Source profile
$ . ~/.nix-profile/etc/profile.d/nix.sh

# Install Fish
$ nix-env -iA nixpkgs.fish

让我们fish再次检查二进制文件:

$ which fish
/home/edward/.nix-profile/bin/fish

$ ls -laZ $(which fish)
lrwxrwxrwx. 1 edward wheel unconfined_u:object_r:default_t:s0 63 Jan  1  1970 /home/edward/.nix-profile/bin/fish -> /nix/store/4mh0j2gm92dwin2dx4v6rhhjr01d6q5y-fish-3.6.0/bin/fish

你看它default_t现在有上下文了。

让我们尝试设置fish为我的默认 shell:

$ sudo usermod -s $(which fish) edward
$ cat /etc/passwd|grep edward
edward:x:1000:10::/home/edward:/home/edward/.nix-profile/bin/fish

好吧。现在通过 SSH 登录edward,它不会工作,就像你说的那样。让我们检查一下 SELinux AVC 拒绝日志:

$ sudo ausearch -ts recent -m avc -i
----
type=AVC msg=audit(02/17/2023 20:01:31.125:440) : avc:  denied  { read } for  pid=2642 comm=sshd name=profile dev="dm-0" ino=839852 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:default_t:s0 tclass=lnk_file permissive=0

因此,在上下文sshd中运行时sshd_t,不允许访问 inode 839852 处的文件。什么文件?

$ sudo find / -xdev -inum 839852
/nix/var/nix/profiles/per-user/edward/profile

这就是您应该得出的结论:Nix 不能在启用 SELinux 的情况下工作,因为下面的所有内容/nix都没有标签。

当然,您可以编写自己的策略文件。这仅适用于这个特定的用例:在 Nix 环境中使用 Fish 作为 shell 通过 SSH 登录。

首先:通过暂时将 SELinux 置于宽容模式来禁用它:

$ sudo setenforce 0

现在再次执行登录操作,就可以了。重新启用 SELinux:

$ sudo setenforce 1

为同时失败的所有事情获取一个策略模块。让我们列出失败的地方:

$ sudo ausearch -m avc -ts recent -c sshd
----
time->Fri Feb 17 20:01:31 2023
type=AVC msg=audit(1676660491.125:440): avc:  denied  { read } for  pid=2642 comm="sshd" name="profile" dev="dm-0" ino=839852 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:default_t:s0 tclass=lnk_file permissive=0
----
time->Fri Feb 17 20:09:11 2023
type=AVC msg=audit(1676660951.340:455): avc:  denied  { read } for  pid=2679 comm="sshd" name="profile" dev="dm-0" ino=839852 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:default_t:s0 tclass=lnk_file permissive=1
----
time->Fri Feb 17 20:09:11 2023
type=AVC msg=audit(1676660951.342:456): avc:  denied  { getattr } for  pid=2679 comm="sshd" path="/nix/store/4mh0j2gm92dwin2dx4v6rhhjr01d6q5y-fish-3.6.0/bin/fish" dev="dm-0" ino=839796 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:default_t:s0 tclass=file permissive=1
----
time->Fri Feb 17 20:09:11 2023
type=AVC msg=audit(1676660951.825:473): avc:  denied  { read } for  pid=2681 comm="sshd" name="profile" dev="dm-0" ino=839852 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:default_t:s0 tclass=lnk_file permissive=1

第一行是当我们尝试在启用 SELinux 的情况下登录时。最后一行是我们成功的登录。

如果通过管道输出上面的输出audit2allow,您会发现从 SELinux 的角度来看,只需要这样做:

#============= sshd_t ==============
allow sshd_t default_t:file getattr;
allow sshd_t default_t:lnk_file read;

差不多了。让我们用它制作一个模块并将其安装到运行策略中。

$ sudo ausearch -m avc -ts recent -c sshd | audit2allow -M sshd-fish-nix
$ sudo semodule -i sshd-fish-nix.pp

您现在可以使用启用了 SELinux 的 SSH 登录。

相关内容