Ich versuche, 2FA mit SSH unter Verwendung von libpam-google-authenticator zu aktivieren. Nicht alle Benutzer müssen Authenticator aktivieren. Jeder verwendet öffentliche SSH-Schlüssel und niemand hat ein Passwort. Ich verwende Debian Buster und habe auch libpam-google-authenticator von Bullseye ausprobiert.
Mein Problem ist, dass, egal was ich in die PAM-Konfiguration eingebe,Benutzer ohne aktivierten Authenticator werden nie direkt angemeldet, sondern immer nach einem Passwort gefragt.
Ich habe libpam-google-authenticator installiert und /etc/ssh/sshd_config mit Folgendem konfiguriert:
PasswordAuthentication no
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
PasswordAuthentication no
PermitEmptyPasswords no
Ich konnte die richtige PAM-Konfiguration nicht herausfinden, sodass Benutzer ohne eine .google_authenticator-Datei trotzdem angemeldet bleiben. Je nachdem, was ich verwende, werden Benutzer entweder zur Eingabe eines Kennworts aufgefordert (sie haben keines) oder erhalten überhaupt keinen Zugriff.
In /etc/pam.d/sshd habe ich versucht (soVersuch, SSH mit öffentlichem Schlüssel (kein Passwort) + Google Authenticator unter Ubuntu 14.04.1 zum Laufen zu bringen):
#@include common-auth
auth required pam_google_authenticator.so debug nullok
In diesem Fall werden Benutzer ohne Authentifikator-Setup mit dem folgenden Debug abgelehnt:
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>
Ist pam_permit
es erforderlich, den Fallback-Fall einzurichten?
Ich habe auch verschiedene Kombinationen von auth required
und auth sufficient
davor und danach ausprobiert @include common-auth
, aber sie führen alle dazu, dass Benutzer ohne Authentifikator nach einem Passwort gefragt werden und manchmal auch Benutzer MIT Authentifikator nach einem Passwort gefragt werden.
Hat jemand ein Rezept, mit dem das funktioniert?
Antwort1
Hier ist meine funktionierende Konfiguration. Einige Benutzer haben den Authentifikator aktiviert, andere nicht. Außerdem sind nur SSH-Anmeldungen mit öffentlichen Schlüsseln zulässig, niemals Passwörter.
In /etc/ssh/sshd_config,
UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
PermitEmptyPasswords no
In /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-auth
muss deaktiviert werden, da es pam_unix enthält, das ich nicht verwenden möchte. Dann müssen Sie pam_permit
die Authentifizierung für Benutzer ohne Authentifikator erfolgreich machen (für den pam_google_authenticator
„ignore“ statt „pass“ zurückgegeben wird).
Dies erlaubt weiterhin keine Root-Anmeldung mit einem SSH-Schlüssel; SSHD loggt
sshd[1244501]: fatal: Internal error: PAM auth succeeded when it should have failed
Dies wird diskutiert beiGoogle Authenticator PAM auf SSH blockiert Root-Login ohne 2FA.
Nachdem dies wie oben beschrieben funktioniert, ich denke, es ist eigentlich besser, 2FA für bestimmte Gruppen mithilfe der SSH-Konfiguration zu erzwingen, wie @zoredache vorgeschlagen hat. Auf diese Weise können Sie ganz einfach bestimmte IPs auf die Whitelist setzen, die auch keine 2FA erfordern. In diesem Fall sagt sshd_config beispielsweise
UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
#AuthenticationMethods any # default
PermitEmptyPasswords no
Match Group adm Address *,!172.16.1.0/24
AuthenticationMethods publickey,keyboard-interactive
und /etc/pam.d/ssh sagt
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
Antwort2
Ich glaube nicht, dass Sie das auskommentieren müssen oder wollen @include common-auth
. Oder zumindest habe ich das nicht getan und es schien richtig zu funktionieren. Aber ich bin immer noch hauptsächlich damit beschäftigt, das zu testen.
Hat jemand ein Rezept, mit dem das funktioniert?
Ich habe keine Zeit, es für Sie in ein Shell-Skript zu übersetzen, aber dies ist ein Auszug aus einem Ansible-Playbook, das bei mir zu funktionieren scheint. Ich vermute, Sie sollten in der Lage sein, zu verstehen, was hier passiert, auch wenn Sie Ansible nicht verwenden.
- 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