如何使用所有 3 個元件設定 SSH 驗證:公鑰、密碼和 OTP

如何使用所有 3 個元件設定 SSH 驗證:公鑰、密碼和 OTP

更新1:我可以使用/etc/pam.d/common-auth.

auth [success=ok] pam_unix.so
auth [success=1] pam_google_authenticator.so nullok echo_verification_code  [authtok_prompt=Enter your OTP:]
auth    requisite                       pam_deny.so
auth    required                        pam_permit.so

我會嘗試將pam_faillock.so其作為原來的計劃應用。


原問題:

我正在使用 Debian 10 和 12,並且希望我的用戶只有在匹配公鑰的情況下才能成功透過 SSH 連接到伺服器,然後輸入密碼,然後使用 OTP(Google身份驗證器)。簡而言之,SSH 應該需要公鑰+密碼+OTP。

publickey + password我已經成功配置了or的組合publickey + OTP,但仍然很難將這三個組合起來。

請幫我配置一下。

到目前為止我的嘗試:

/etc/pam.d/common-auth

auth    required       pam_faillock.so preauth audit silent deny=5 unlock_time=1800
auth    sufficient     pam_unix.so try_first_pass
auth    [default=die]  pam_faillock.so authfail audit deny=5 fail_interval=120 unlock_time=1800
auth    sufficient     pam_faillock.so authsucc audit deny=5 fail_interval=120 unlock_time=1800
auth    required [success=1] pam_google_authenticator.so echo_verification_code
auth    requisite      pam_deny.so
auth    required       pam_permit.so

/etc/pam.d/sshd

@include common-auth
account    required     pam_nologin.so
@include common-account
session [success=ok ignore=ignore module_unknown=ignore default=bad]        pam_selinux.so close
session    required     pam_loginuid.so
session    optional     pam_keyinit.so force revoke
@include common-session
session    optional     pam_motd.so  motd=/run/motd.dynamic
session    optional     pam_motd.so noupdate
session    optional     pam_mail.so standard noenv # [1]
session    required     pam_limits.so
session    required     pam_env.so # [1]
session    required     pam_env.so user_readenv=1 envfile=/etc/default/locale
session [success=ok ignore=ignore module_unknown=ignore default=bad]        pam_selinux.so open
@include common-password

/etc/ssh/sshd_config

Include /etc/ssh/sshd_config.d/*.conf
MaxAuthTries 5
MaxSessions 1
PubkeyAuthentication yes
PasswordAuthentication yes
PermitEmptyPasswords no
KbdInteractiveAuthentication yes
UsePAM yes
X11Forwarding yes
PrintMotd no
ClientAliveInterval 60
ClientAliveCountMax 15
AcceptEnv LANG LC_*
Subsystem       sftp    /usr/lib/openssh/sftp-server
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,password,keyboard-interactive

嘗試連線時:ssh -i <key_path> user@server -vvv

debug1: Authentications that can continue: publickey
debug3: start over, passed a different list publickey
debug3: preferred publickey,keyboard-interactive,password
debug3: authmethod_lookup publickey
debug3: remaining preferred: keyboard-interactive,password
debug3: authmethod_is_enabled publickey
debug1: Next authentication method: publickey
debug1: Trying private key: <key_path>
debug3: sign_and_send_pubkey: 
debug3: sign_and_send_pubkey: signing using rsa-sha2-512
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 51
Authenticated with partial success.
debug1: Authentications that can continue: password
debug3: start over, passed a different list password
debug3: preferred publickey,keyboard-interactive,password
debug3: authmethod_lookup password
debug3: remaining preferred: ,keyboard-interactive,password
debug3: authmethod_is_enabled password
debug1: Next authentication method: password
user@server's password:
debug3: send packet: type 50
debug2: we sent a password packet, wait for reply
debug3: receive packet: type 51
Authenticated with partial success.
debug1: Authentications that can continue: keyboard-interactive
debug3: start over, passed a different list keyboard-interactive
debug3: preferred publickey,keyboard-interactive,password
debug3: authmethod_lookup keyboard-interactive
debug3: remaining preferred: password
debug3: authmethod_is_enabled keyboard-interactive
debug1: Next authentication method: keyboard-interactive
debug2: userauth_kbdint
debug3: send packet: type 50
debug2: we sent a keyboard-interactive packet, wait for reply
debug3: receive packet: type 60
debug2: input_userauth_info_req: entering
debug2: input_userauth_info_req: num_prompts 1
(user@server) Password:
debug3: send packet: type 61
debug3: receive packet: type 51
debug1: Authentications that can continue: keyboard-interactive
debug2: userauth_kbdint
debug3: send packet: type 50
debug2: we sent a keyboard-interactive packet, wait for reply
debug3: receive packet: type 60
debug2: input_userauth_info_req: entering
debug2: input_userauth_info_req: num_prompts 1
(user@server) Password:
debug3: send packet: type 61
debug3: receive packet: type 51
debug1: Authentications that can continue: keyboard-interactive
debug2: userauth_kbdint
debug3: send packet: type 50
debug2: we sent a keyboard-interactive packet, wait for reply
debug3: receive packet: type 60
debug2: input_userauth_info_req: entering
debug2: input_userauth_info_req: num_prompts 1
(user@server) Password:
debug3: send packet: type 61
debug3: receive packet: type 51
debug1: Authentications that can continue: keyboard-interactive
debug2: we did not send a packet, disable method
debug1: No more authentication methods to try.
user@server: Permission denied (keyboard-interactive).

在此輸入影像描述

它在步驟 3(鍵盤互動)中失敗,有些事情與正常的 OTP 驗證不同:

  • 它沒有要求,Verification code:而只是要求(user@server) Password:
  • 儘管echo_verification_codecommon-auth.

P/s:我還配置了pam_faillock.so在登入嘗試失敗時鎖定使用者。

答案1

經過一番嘗試,並感謝這個帖子,我可以添加pam_faillock.so到我的解決方案中以檢查日誌記錄嘗試並在需要時鎖定使用者。

當心在編輯下面那些與身分驗證相關的文件時。總是進行備份首先是文件。和記得保持一個 root 會話處於活動狀態,並在另一個會話中測試您的登入。

讓我們看看我的設定檔:

第一的:編輯/etc/pam.d/common-auth適用於各種登入方式:

auth    requisite       pam_faillock.so preauth audit deny=5 fail_interval=120 unlock_time=1800
auth    [success=1]     pam_unix.so try_first_pass
auth    [default=die]   pam_faillock.so authfail audit deny=5 fail_interval=120 unlock_time=1800
auth    [success=2]     pam_google_authenticator.so nullok echo_verification_code  [authtok_prompt=Enter your OTP:]
auth    sufficient      pam_faillock.so authsucc audit deny=5 fail_interval=120 unlock_time=1800
auth    requisite       pam_deny.so
auth    required        pam_permit.so

一些逐行解釋:

  1. pam_faillock.sopreauth和 一起使用requisite將檢查使用者的狀態。如果使用者被鎖定,則封鎖密碼提示。接下來是一些faillock您可以簽入的配置這裡
  2. 用於pam_unix.so檢查用戶的密碼。[success=1]如果密碼正確,將跳過下一行。try_first_pass使用第一步的輸入。
  3. pam_faillock.sowithauthfail將記錄失敗的嘗試,並阻止身份驗證過程進一步進行[default=die]。如果您希望使用者不知道哪裡出了問題(密碼或 OTP),則交換第 3 行和第 4 行。
  4. 用於pam_google_authenticator.so檢查 OTP。您可以找到更多信息這裡[success=2]如果 OTP 正確,將跳過接下來的兩行。
  5. pam_faillock.so這次有authsucc標記的嘗試是好的,會清除不良的嘗試記錄,讓使用者可以走得更遠。
  6. pam_deny.sowithrequisite將拒絕登入嘗試。因此,如果資訊正確,上面的某些行會跳過此行。
  7. pam_permit.so只需在完成上述所有檢查後允許訪問即可。

第二:編輯/etc/pam.d/common-account並在開頭新增此行以使用faillock

account required        pam_faillock.so

第三:編輯/etc/pam.d/sshdSSH 連線。我沒有對預設配置進行任何更改,只是將其列在這裡供大家比較。

@include common-auth
account    required     pam_nologin.so
@include common-account
session [success=ok ignore=ignore module_unknown=ignore default=bad]        pam_selinux.so close
session    required     pam_loginuid.so
session    optional     pam_keyinit.so force revoke
@include common-session
session    optional     pam_motd.so  motd=/run/motd.dynamic
session    optional     pam_motd.so noupdate
session    optional     pam_mail.so standard noenv # [1]
session    required     pam_limits.so
session    required     pam_env.so # [1]
session    required     pam_env.so user_readenv=1 envfile=/etc/default/locale
session [success=ok ignore=ignore module_unknown=ignore default=bad]        pam_selinux.so open
@include common-password

第四:編輯/etc/ssh/sshd_config配置SSH會話

Include /etc/ssh/sshd_config.d/*.conf
MaxAuthTries 5
MaxSessions 1
PubkeyAuthentication yes
PasswordAuthentication yes
PermitEmptyPasswords no
KbdInteractiveAuthentication yes
UsePAM yes
X11Forwarding yes
PrintMotd no
ClientAliveInterval 60
ClientAliveCountMax 15
AcceptEnv LANG LC_*
Subsystem       sftp    /usr/lib/openssh/sftp-server
AuthenticationMethods publickey,keyboard-interactive

一些關鍵項目:

  1. KbdInteractiveAuthentication=yes使用keyboard-interactive方法。ChallengeResponseAuthentication是已棄用的別名。
  2. UsePAM必須設定為yes使用上面的所有 PAM 配置
  3. 在 中AuthenticationMethods,我僅聲明keyboard-interactive密碼和 OTP 提示。

編輯檔案後sshd_config,重新載入sshd服務以更新新配置。

systemctl reload sshd

像這樣,我可以檢查所有public key + password (of the user) + OTP.

相關內容