使用尼克斯包管理器,我已经安装了鱼对于我的登录外壳。我已将外壳添加到/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 登录。