Я пытаюсь включить 2FA с ssh с помощью libpam-google-authenticator. Не всем пользователям нужно включать аутентификатор. Все используют открытые ключи ssh, и ни у кого нет пароля. Я использую Debian buster, и я также пробовал libpam-google-authenticator из bullseye.
Моя проблема в том, что независимо от того, что я ввожу в конфигурацию PAM,пользователи без включенного аутентификатора никогда не входят в систему напрямую, а всегда запрашивают пароль.
Я установил libpam-google-authenticator и настроил /etc/ssh/sshd_config следующим образом:
PasswordAuthentication no
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
PasswordAuthentication no
PermitEmptyPasswords no
Мне не удалось разработать правильную конфигурацию PAM, чтобы пользователи без файла .google_authenticator все равно могли войти в систему. В зависимости от того, что я использую, пользователям либо предлагается ввести пароль (у них его нет), либо вход вообще не допускается.
В /etc/pam.d/sshd я пробовал (вроде этого)Попытка заставить SSH работать с открытым ключом (без пароля) + Google Authenticator на Ubuntu 14.04.1):
#@include common-auth
auth required pam_google_authenticator.so debug nullok
В этом случае пользователи без настройки аутентификатора будут отклонены со следующей отладкой;
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_permit
настроить запасной вариант?
Я также пробовал различные комбинации auth required
и auth sufficient
до и после @include common-auth
, но все они приводят к тому, что у пользователей без аутентификатора запрашивается пароль, а иногда и у пользователей С аутентификатором также запрашивается пароль.
Есть ли у кого-нибудь рецепт, как это сделать?
решение1
Вот моя рабочая конфигурация. У некоторых пользователей включен аутентификатор, у некоторых нет, и разрешены только входы по SSH с открытыми ключами, а не с паролями.
В /etc/ssh/sshd_config,
UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
PermitEmptyPasswords no
В /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
должно быть отключено, потому что оно включает pam_unix, который я не хочу использовать. Затем вам нужно pam_permit
сделать аутентификацию успешной для пользователей без аутентификатора (для которого pam_google_authenticator
возвращается игнорирование, а не передача).
Это по-прежнему не позволяет войти в систему root с помощью ключа SSH; логи SSHD
sshd[1244501]: fatal: Internal error: PAM auth succeeded when it should have failed
Это обсуждается наGoogle Authenticator PAM на SSH блокирует вход с правами root без 2FA.
Получив это, работающее как указано выше, я думаю, что на самом деле лучше принудительно применять 2FA для определенных групп с помощью конфигурации SSH, как предложил @zoredache. Это легко позволяет вам вносить в белый список определенные IP-адреса, не требующие 2FA. В этом случае sshd_config говорит, например,
UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
#AuthenticationMethods any # default
PermitEmptyPasswords no
Match Group adm Address *,!172.16.1.0/24
AuthenticationMethods publickey,keyboard-interactive
и /etc/pam.d/ssh говорит
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
решение2
Я не думаю, что вам нужно или хочется комментировать @include common-auth
. Или, по крайней мере, я этого не сделал, и, похоже, это работало правильно. Но я все еще в основном тестирую это.
Есть ли у кого-нибудь рецепт, как это сделать?
У меня нет времени переводить это в скрипт оболочки для вас, но это отрывок из ansible playbook, который, кажется, работает для меня. Я подозреваю, что вы сможете понять, что это делает, даже если вы не используете 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