La autenticación de clave pública SSH con el autenticador de Google todavía solicita la contraseña

La autenticación de clave pública SSH con el autenticador de Google todavía solicita la contraseña

Estoy intentando habilitar 2FA con ssh usando libpam-google-authenticator. No todos los usuarios necesitan tener habilitado el autenticador. Todo el mundo usa claves públicas ssh y nadie tiene una contraseña. Estoy ejecutando Debian Buster y también probé libpam-google-authenticator de bullseye.

Mi problema es que no importa lo que ponga en la configuración de PAM,los usuarios sin el autenticador habilitado nunca inician sesión directamente, pero siempre se les solicita una contraseña.

Instalé libpam-google-authenticator y configuré /etc/ssh/sshd_config con:

PasswordAuthentication no
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
PasswordAuthentication no
PermitEmptyPasswords no

No he podido encontrar la configuración PAM correcta para que los usuarios sin un archivo .google_authenticator sigan conectados. Dependiendo de lo que uso, a los usuarios se les solicita una contraseña (no tienen una) o no. permitido en absoluto.

En /etc/pam.d/sshd lo he intentado (asíIntentando que SSH con clave pública (sin contraseña) + autenticador de Google funcione en Ubuntu 14.04.1):

#@include common-auth
auth       required     pam_google_authenticator.so debug nullok

En este caso, los usuarios sin una configuración de autenticación son rechazados con la siguiente depuración;

Aug 05 15:11:18 <host> sshd(pam_google_authenticator)[746624]: debug: start of google_authenticator for "<user>"
Aug 05 15:11:18 <host> sshd(pam_google_authenticator)[746624]: debug: end of google_authenticator for "<user>" Result: The return value should be ignored by PAM dispatch
Aug 05 15:11:18 <host> sshd[746620]: error: PAM: Permission denied for <user> from <IP>

¿ pam_permitEs necesario configurar el caso alternativo?

También probé varias combinaciones de auth requiredy auth sufficientantes y después @include common-auth, pero todas dan como resultado que a los usuarios sin autenticador se les solicite una contraseña y, a veces, a los usuarios CON autenticador también se les solicite una contraseña.

¿Alguien tiene una receta para hacer que esto funcione?

Respuesta1

Aquí está mi configuración de trabajo. Algunos usuarios tienen habilitado el autenticador y otros no, y solo se permiten inicios de sesión SSH con claves públicas, nunca contraseñas.

En /etc/ssh/sshd_config,

UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
PermitEmptyPasswords no

En /etc/pam.d/sshd,

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

# Require authenticator, if not configured then allow
auth    required    pam_google_authenticator.so debug nullok
auth    required    pam_permit.so

@include comon-authdebe estar deshabilitado porque incluye pam_unix, que no quiero usar. Luego, debe pam_permithacer que la autenticación sea exitosa para los usuarios sin autenticador (para lo cual pam_google_authenticatorse devuelve ignorar en lugar de aprobar).

Esto todavía no permite que el root inicie sesión con una clave ssh; registros sshd

sshd[1244501]: fatal: Internal error: PAM auth succeeded when it should have failed

Esto se discute enGoogle Authenticator PAM en SSH bloquea el inicio de sesión de root sin 2FA.

Habiendo conseguido que esto funcione como se indica arriba, Creo que en realidad es mejor aplicar 2FA para ciertos grupos usando la configuración SSH como sugirió @zoredache. Esto le permite fácilmente incluir en la lista blanca ciertas IP que tampoco requieren 2FA. En este caso, sshd_config dice por ejemplo

UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
#AuthenticationMethods any # default
PermitEmptyPasswords no

Match Group adm Address *,!172.16.1.0/24
    AuthenticationMethods publickey,keyboard-interactive

y /etc/pam.d/ssh dice

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

# Require authenticator; SSH should not allow any user in who doesn't have it
auth       sufficient   pam_google_authenticator.so debug nullok
auth       requisite    pam_deny.so

Respuesta2

No creo que necesites o quieras comentar el @include common-auth. O al menos yo no lo hice y pareció funcionar correctamente. Pero todavía estoy probando esto en su mayor parte.

¿Alguien tiene una receta para hacer que esto funcione?

No tengo tiempo para traducirlo a un script de shell, pero este es un extracto de un manual de estrategias ansible que parece funcionar para mí. Sospecho que deberías poder seguir lo que esto hace incluso si no estás usando ansible.

- hosts: linux_systems
  tasks:

  - name: Add group 'totp'
    group:
      name: totp
      state: present
      system: yes

  - name: Create directory for totp secrets
    file:
      state: directory
      path: /var/lib/google-authenticator
      owner: "0"
      group: "0"
      mode: "0700"

  - name: install libpam-google-authenticator
    apt:
      update_cache: yes
      cache_valid_time: '{{ apt_cache_valid_time | default(7200) }}'
      state: present
      name:
      - libpam-google-authenticator

  - name: Create secret for 'example-user'
    args:
      creates: /var/lib/google-authenticator/example-user
    shell: |
      TOTP_USER=example-user; \
      google-authenticator \
        --force --quiet \
        --emergency-codes=10 \
        --time-based \
        --qr-mode=none \
        --allow-reuse \
        --window-size=3 \
        --rate-limit=4 --rate-time=30 \
        --secret=/var/lib/google-authenticator/${TOTP_USER}

  - name: update pam
    lineinfile:
      insertafter: '^@include common-password'
      path: /etc/pam.d/login
      line: 'auth required pam_google_authenticator.so nullok user=root secret=/var/lib/google-authenticator/${USER}'

  - name: update pam
    lineinfile:
      insertafter: '^@include common-password'
      path: /etc/pam.d/sshd
      line: 'auth required pam_google_authenticator.so nullok user=root secret=/var/lib/google-authenticator/${USER}'

  - name: update sshd ChallengeResponseAuthentication
    notify: Restart sshd
    lineinfile:
      path: /etc/ssh/sshd_config
      regexp: '^ChallengeResponseAuthentication .*'
      line: 'ChallengeResponseAuthentication yes'

  handlers:

  - name: Restart sshd
    service:
      name: sshd
      state: restarted

información relacionada