SSHD 使用密码 + google-authenticator 组合拒绝访问

SSHD 使用密码 + google-authenticator 组合拒绝访问

我正在运行 ProxMox 5.3 (Debian 9stretch) 虚拟机管理程序,并且我想保护对虚拟机管理程序的 SSH 访问。我已按照找到的文档进行操作这里为了将 MFA 添加到 openssh,但是我做了一些细微的修改。也就是说,我想允许以下身份验证方法

  • 密码后跟 OATH-TOTP(google-authenticator)
  • 公钥后跟 OATH-TOTP(google-authenticator)

然而,无论出于何种原因,当我尝试从其中一台虚拟机通过 SSH 连接到虚拟机管理程序来测试此配置时,系统从未提示我输入 google-authenticator 代码。这就是我所看到的/var/log/auth.log

[root@vm1 ~]# ssh 192.168.86.2
[email protected]'s password: 
Permission denied, please try again.
root@hypervisor:~# tail -f /var/log/auth.log
...
Apr 17 08:58:53 pve1-gkh8ww1 sshd(pam_google_authenticator)[8971]: Invalid verification code
Apr 17 08:58:54 pve1-gkh8ww1 sshd[8971]: Failed password for root from 192.168.86.3 port 54948 ssh2

我知道我输入的密码正确,因为我刚刚用它登录。因此,我尝试在客户端和服务器上运行更详细的输出。

来自客户

debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /root/.ssh/id_rsa
debug1: Authentications that can continue: publickey,password
debug1: Trying private key: /root/.ssh/id_dsa
debug1: Trying private key: /root/.ssh/id_ecdsa
debug1: Trying private key: /root/.ssh/id_ed25519
debug1: Next authentication method: password
[email protected]'s password: 
debug1: Authentications that can continue: publickey,password
Permission denied, please try again.

从服务器

debug1: KEX done [preauth]
debug1: userauth-request for user root service ssh-connection method none [preauth]
debug1: attempt 0 failures 0 [preauth]
debug1: authentication methods list 0: password,keyboard-interactive
debug1: authentication methods list 1: publickey,keyboard-interactive
debug1: authentication methods list 0: password,keyboard-interactive [preauth]
debug1: authentication methods list 1: publickey,keyboard-interactive [preauth]
debug1: PAM: initializing for "root"
debug1: PAM: setting PAM_RHOST to "192.168.86.3"
debug1: PAM: setting PAM_TTY to "ssh"
debug1: userauth-request for user root service ssh-connection method publickey [preauth]
debug1: attempt 1 failures 0 [preauth]
debug1: userauth_pubkey: test whether pkalg/pkblob are acceptable for RSA SHA256:5OtnlHMBJnFp75gii09+T8zQdJcFoHlI0wHZoL8i8wU [preauth]
debug1: temporarily_use_uid: 0/0 (e=0/0)
debug1: trying public key file /root/.ssh/authorized_keys
debug1: fd 4 clearing O_NONBLOCK
debug1: restore_uid: 0/0
debug1: temporarily_use_uid: 0/0 (e=0/0)
debug1: trying public key file /root/.ssh/authorized_keys2
debug1: Could not open authorized keys '/root/.ssh/authorized_keys2': No such file or directory
debug1: restore_uid: 0/0
Failed publickey for root from 192.168.86.3 port 54954 ssh2: RSA SHA256:5OtnlHMBJnFp75gii09+T8zQdJcFoHlI0wHZoL8i8wU

debug1: userauth-request for user root service ssh-connection method password [preauth]
debug1: attempt 2 failures 1 [preauth]
debug1: PAM: password authentication failed for root: Authentication failure
Failed password for root from 192.168.86.3 port 54954 ssh2

特别是,我对客户的这句话感到困惑

debug1: Authentications that can continue: publickey,password

这似乎与服务器的调试输出不匹配。

debug1: authentication methods list 0: password,keyboard-interactive
debug1: authentication methods list 1: publickey,keyboard-interactive

我已在服务器上显式设置 AuthenticationMethods 指令/etc/ssh/sshd_config以及其他必要的指令

AuthenticationMethods password,keyboard-interactive publickey,keyboard-interactive

ChallengeResponseAuthentication yes 

PermitRootLogin yes

PasswordAuthentication yes

UsePAM yes

这是我的相关部分/etc/pam.d/sshd

# Standard Un*x authentication.
@include common-auth
...
...
# Standard Un*x password updating.
@include common-password
auth required pam_google_authenticator.so

答案1

答案很简单,不可能通过密码身份验证请求两个因素,但可以向您提供解释以帮助使事情正常进行。您将密码身份验证视为使用密码的方式。这是不正确的。

“密码身份验证”是对单个密码的简单请求。服务器没有向客户端发送特定的提示。客户端选择如何标记提示 - 例如当它询问“输入 user@host 的密码:”时。

“键盘交互”是对任意数量的信息的更复杂的请求。对于每条信息,服务器都会发送提示标签。此外,它允许服务器提供其期望的响应形式的描述。服务器还可以指定哪些输入是秘密的(密码需要在屏幕上进行混淆),哪些不是(OTP)

在大多数情况下,键盘交互式身份验证用于请求单个“秘密”密码提示,因此与最终用户的密码身份验证相比几乎没有任何区别。

由于键盘交互是一种允许服务器发送多个质询/响应对的身份验证机制,因此 Google Authenticator PAM 插件需要它发送两个问题 - 密码和 OTP。

因此,密码身份验证永远不会与 Google Authenticator 一起使用,因为它无法提示多于一件事。 Google Authenticator 将使用私钥和 OTP 进入密码提示(尽管并不理想)。 Google Authenticator 将通过键盘与密码和 OTP 进行交互。 Google Authenticator 无法使用密码提示,因为它无法要求提供正确的信息。

在您的客户端软件中,优先考虑键盘交互而不是密码,您将根据当前配置获得两个提示。为了避免这种情况,我们可以完全禁用密码身份验证。

那么如何修复:

删除密码作为受支持的身份验证方法,并依靠键盘交互进行密码身份验证。在 /etc/ssh/sshd_config 中设置“PasswordAuthentication no”

所以: /etc/ssh/sshd_config

UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
PubkeyAuthentication yes
# I don't use AuthenticationMethods at all and rely on my yes/no's

/etc/pam.d/sshd(在底部)

auth required pam_google_authenticator.so nullok

答案2

在 /etc/ssh/sshd_config 中的 UsePAM yes 之后添加此内容

AuthenticationMethods publickey,keyboard-interactive

答案3

@michaelkrieger 答案非常好,但我认为它忽略了解释如何启用密码身份验证+谷歌身份验证器组合的要点。就我而言,我遵循这个数字海洋教程,并且使用密码不起作用。这是因为该教程让您评论这一行/etc/pam.d/sshd

# Standard Un*x authentication.
@include common-auth

我花了相当长的时间试图弄清楚它,直到我记得我在遵循教程时评论了该行。

正如迈克尔所说,您不需要PasswordAuthentication yeson sshd_config,甚至不需要AuthenticationMethodsline ,只需将ChallengeResponseUsePAM设置为yes

相关内容