每用户 SSH 密码身份验证中的奇怪行为

每用户 SSH 密码身份验证中的奇怪行为

我正在使用 NixOS。这是我的 SSHd 配置:

  services.openssh.enable = true;
  services.openssh.passwordAuthentication = false;
  services.openssh.challengeResponseAuthentication = false;
  services.openssh.permitRootLogin = "no";

  services.openssh.extraConfig = ''
    Match User dropbox
      PasswordAuthentication yes
  '';

正如您所看到的,我不允许使用密码进行 SSH 登录,但作为例外,允许 user 进行登录dropbox。此 Nix 语法会生成以下 sshd_config:

UsePAM yes

AddressFamily any
Port 22

X11Forwarding no

Subsystem sftp /nix/store/6fkb47ri4xndlpszjrbw8ggd3vmb6in7-openssh-8.1p1/libexec/sftp-server

PermitRootLogin no
GatewayPorts no
PasswordAuthentication no
ChallengeResponseAuthentication no

PrintMotd no # handled by pam_motd

AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 /etc/ssh/authorized_keys.d/%u

HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

KexAlgorithms [email protected],diffie-hellman-group-exchange-sha256
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
MACs [email protected],[email protected],[email protected],hmac-sha2-512,hmac-sha2-256,[email protected]

LogLevel VERBOSE

UseDNS no

Match User dropbox
  PasswordAuthentication yes

从表面上看,这似乎有效。它不允许其他用户使用密码登录,但允许dropbox.这是与ssh -v dropbox@poi

debug1: Next authentication method: password
dropbox@poi's password:
debug1: Authentications that can continue: publickey,password
Permission denied, please try again.

但是,它不接受dropbox的密码。这是允许我登录的完全相同的密码(简单的三个字母的玩具密码),因此密码没有错误。我什至复制粘贴它以避免大写锁定陷阱。允许登录的相同密码不允许 SSH 登录。

但是,如果我设置passwordAuthentication允许所有用户,那么dropbox就可以神奇地使用它的密码登录。我已经验证该Match部分始终位于 的末尾sshd_config,因此这与订购问题无关。

我从来没有听说过这种行为。有什么技巧可以让我调试这个吗?

答案1

如果你看一下 nix 源代码这里您可以看到他们正在使用passwordAuthentication 来设置PAM 规则。有效地:

security.pam.services.sshd.unixAuth = <passwordAuthentication>;

我无法想出在 sshd 配置中禁用 PAM[笔记2],nix 模块将“UsePAM yes”硬编码到文件顶部。相反,我们可以覆盖该设置,以便 PAM 接受您的密码。

services.openssh.enable = true;
services.openssh.permitRootLogin = "no";
services.openssh.passwordAuthentication= false;
services.openssh.challengeResponseAuthentication = false;
services.openssh.extraConfig = "
    Match User bootstrap
    PasswordAuthentication yes
    Match All
";
security.pam.services.sshd.unixAuth = pkgs.lib.mkForce true;

解释:

PAM 是大多数 Linux 系统上提供的一项服务,用于处理用户身份验证等。它可以配置为以各种方式进行身份验证。来自 NixOS 选项参考:

security.pam.services.<name?>.unixAuth
   Description:   Whether users can log in with passwords defined in /etc/shadow.
   Default value: true

需要challengeResponseAuthentication行来真正防止密码登录,因为challengeResponseAuthentication和passwordAuthentication指的是两个不同的基于“密码”的登录模式,并且它们独立启用/禁用。

笔记:如果你忘记使用 mkForce (或类似的东西),nix 会对你大喊大叫:

error: The option `security.pam.services.sshd.unixAuth' has conflicting definitions, in `/nix/var/nix/profiles/per-user/root/channels/nixos/nixos/modules/services/networking/ssh/sshd.nix' and `/etc/nixos/configuration.nix'.

笔记2:某些(也许是全部,IDK)openssh 选项在配置文件中设置后无法更改。相同值的后续定义将被忽略。因此,在 extraConfig 中输入“UsePAM no”无效,因为“UsePAM”已在 sshd_config 顶部设置为“yes”。

注3:NixOS v20.03.1619 (Markhor)、OpenSSH_8.2p1

如果有人有关于 PAM 或 sshd 配置或 NixOS 如何工作的更具体信息,请在评论中提及,我会将其添加到答案中。

相关内容