Cómo configurar la autenticación SSH con los 3 componentes: clave pública, contraseña y OTP

Cómo configurar la autenticación SSH con los 3 componentes: clave pública, contraseña y OTP

Actualización 1: Puedo aplicar todas las claves públicas + contraseña + OTP con esta configuración básica en /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

Intentaré aplicar pam_faillock.soesto como el plan original.


Pregunta original:

Estoy usando Debian 10 y 12 y me gustaría que mis usuarios solo realicen SSH con éxito en el servidor si coinciden con la clave pública, luego ingresen su contraseña y luego sigan con OTP (autenticador de Google). En resumen, SSH debería requerir clave pública + contraseña + OTP.

Ya configuré con éxito la combinación de publickey + passwordo publickey + OTP, pero todavía me cuesta combinar los tres.

Por favor ayúdame a configurarlo.

Mi intento hasta ahora:

/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

Al intentar conectarse: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).

ingrese la descripción de la imagen aquí

Falló en el paso 3 (teclado interactivo) y algunas cosas fueron diferentes de la verificación OTP normal:

  • No pidió el Verification code:sino sólo preguntó (user@server) Password:.
  • No mostró el código OTP sin formato cuando ingresé a pesar de la configuración echo_verification_codeen common-auth.

P/s: También configuré pam_faillock.sobloquear a los usuarios por intentos fallidos de inicio de sesión.

Respuesta1

Después de algunos intentos y gracias aesta publicación, puedo agregar pam_faillock.soa mi solución para verificar los intentos de registro y bloquear al usuario si es necesario.

Ten cuidadoal editar los archivos relacionados con la autenticación que aparecen a continuación. Siemprehacer una copia de seguridaddel archivo primero. Yrecuerde mantener viva una sesión raízy pruebe su inicio de sesión en la otra sesión.

Veamos mis archivos de configuración:

Primero: Editar /etc/pam.d/common-authpara aplicar a todo tipo de métodos de inicio de sesión:

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

Alguna explicación línea por línea:

  1. Úselo pam_faillock.socon preauthy requisiteverificará el estado del usuario. Si el usuario está bloqueado, evite que se le solicite la contraseña. Seguido de alguna configuración faillockque puedes registraraquí.
  2. Se utiliza pam_unix.sopara comprobar la contraseña del usuario. [success=1]saltará la siguiente línea si la contraseña es correcta. try_first_passpara utilizar la entrada del primer paso.
  3. pam_faillock.sowith authfailregistrará el intento fallido y evitará que el proceso de autenticación avance con [default=die]. Si desea que el usuario no sepa dónde está fallando (contraseña u OTP), intercambie las líneas 3 y 4.
  4. Úselo pam_google_authenticator.sopara verificar la OTP. Puedes encontrar más información.aquí. [success=2]omitirá las siguientes dos líneas si la OTP es correcta.
  5. pam_faillock.socon authsuccmarcar este intento es bueno y borrará los registros de intentos fallidos, permitiendo al usuario ir más lejos.
  6. pam_deny.sowith requisitenegará el intento de inicio de sesión. Algunas líneas anteriores omiten esta línea si la información es correcta.
  7. pam_permit.sosimplemente permita el acceso después de todas las comprobaciones anteriores.

Segundo: Edite /etc/pam.d/common-accounty agregue esta línea al principio para usar faillock:

account required        pam_faillock.so

Tercero: Editar /etc/pam.d/sshdpara conexión SSH. No cambié nada de la configuración predeterminada, solo la enumeré aquí para que ustedes la comparen.

@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

Cuatro: Editar /etc/ssh/sshd_configpara configurar la sesión 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

Algunos elementos clave:

  1. KbdInteractiveAuthentication= yesal uso keyboard-interactivedel método. ChallengeResponseAuthenticationes un alias obsoleto para esto.
  2. UsePAMdebe configurarse para yesusar todas las configuraciones de PAM anteriores
  3. En AuthenticationMethods, solo declaro keyboard-interactivetanto para la contraseña como para la solicitud de OTP.

Después de editar el sshd_configarchivo, vuelva a cargar el sshdservicio para actualizar la nueva configuración.

systemctl reload sshd

Y así, puedo comprobarlo todo public key + password (of the user) + OTP.

información relacionada