Я пытаюсь реализовать двухфакторную аутентификацию для OpenSSH. Среда — Centos 7 (ядро: 3.10.0-229.1.2.el7.x86_64) с OpenSSH_6.6.1p1, OpenSSL 1.0.1e-fips 11 февраля 2013 г. У нас развернуты Active Directory (LDAP) + Kerberos. Спецификация следующая:
- Пользователю с действующим действительным билетом Kerberos необходимо задать только второй фактор.
- У пользователя без действующего билета Kerberos необходимо запросить как пароль, так и второй фактор.
- Локальные пользователи (без учетной записи LDAP) должны иметь возможность аутентификации с помощью своих локальных паролей.
- Второй фактор не должен предлагаться раньше первого.
- Помимо Kerberos, в качестве первого фактора следует также принимать аутентификацию с открытым ключом, если она доступна.
- Функцию следует ограничить кругом пользователей — остальные смогут войти только с помощью своих паролей.
Для выполнения процесса аутентификации второго фактора есть сторонний модуль PAM, который ничего не знает о Kerberos. Вот что я сделал:
Добавьте эти строки в /etc/ssh/sshd_config:
# To enable PAM - this will make sshd use PAM with configuration /etc/pam.d/sshd
UsePam yes
ChallengeResponseAuthentication yes
# To enable Kerberos and public key authentication - it will let sshd use existing Kerberos tickets
GSSAPIAuthentication yes
# Enable public key authentication
PubkeyAuthentication yes
# Password validation should be done via the KDC
PasswordAuthentication yes
KerberosAuthentication yes
KerberosOrLocalPasswd yes
# Kerberos / Public Key + PAM
AuthenticationMethods gssapi-with-mic,keyboard-interactive:pam publickey,keyboard-interactive:pam password,keyboard-interactive:pam
# (only supported for OpenSSH 6.2 or higher)
Раздел auth конфигурации PAM для sshd (/etc/pam.d/sshd)
auth [success=ignore default=1] pam_localuser.so
auth substack password-auth
auth [success=1 default=ignore] pam_localuser.so
auth required pam_2fa.so [...some arguments...]
auth include postlogin
Модуль pam_2fa.so отвечает за запрос и проверку второго фактора.
Теперь для Kerberos это делает почти все, чего я хотел добиться. Однако для локальных учетных записей это приводит к двум последующим запросам пароля. Это моя главная проблема здесь. Это потому, что в этом случае используется путь "password, keyboard-interactive: pam", как и ожидалось. (Мне нужен этот путь аутентификации, чтобы кто-то с учетной записью Kerberos, но без действительного билета, мог получить билет, введя пароль, а затем OTP.) Если я полностью удалю подстек password-auth из конфигурации PAM, то учетные записи Kerberos останутся рабочими, а локальные учетные записи — нет. Мне кажется, что оператор KerberosOrLocalPasswd yes игнорируется, потому что UsePAM yes также присутствует. Однако sshd действительно продолжает использовать KDC для проверки пароля, потому что в противном случае он не работал бы и для учетных записей LDAP.
Итак, еще раз, чтобы прояснить, что я хочу реализовать, вот псевдокод, описывающий желаемую логику аутентификации:
if gssapi_auth_ok(principal) or pubkey_auth_ok(pubkey):
return second_factor_auth(user, read_otp())
else:
if is_local_account(user):
if local_passwd_auth(user, read_password()):
return second_factor_auth(user, read_otp())
else:
return AUTH_ERR
else:
if krb5_auth(principal, read_password()):
return second_factor_auth(user, read_otp())
return AUTH_ERR
Итак, мой сценарий, я думаю, не слишком сложен или амбициозен в любом случае, но я все еще не смог найти четкий способ его реализовать, несмотря на то, что я провел дни, исследуя и экспериментируя. Не могли бы вы помочь мне найти решение?
Заранее большое спасибо!
решение1
Я не знаю ни одного способа сделать то, что вы хотите с PAM, не написав новый модуль pam. PAM относительно сложен, и способ, которым sshd взаимодействует с PAM и kerberos, по моему опыту, таков, что всегда есть крайний случай, который просто не работает.
То, что вы хотите, возможно, я просто не знаю, как это сделать. Если вам нужно только защитить ssh, я бы посоветовал использовать
ForceCommand /path/to/2fa_executable
в вашем sshd_config. Это позволит вам реализовать нужную логику, недостаток в том, что 2fa_executable должен быть setuid для чтения любых секретов 2fa.
Пример и код есть на сайте Duo Security. Вы можете использовать обертку duo setuid и любой код 2fa, который вы используете.
решение2
- Пользователю с действующим действительным билетом Kerberos необходимо задать только второй фактор.
Этого невозможно добиться с помощью PAM.
Успешная аутентификация на основе ключей, выполненная против sshd, обходит auth
стек PAM. Это включает GSSAPI, который является требованием для аутентификации Kerberos на основе билетов. У него нет выбора, кроме как сделать это, поскольку PAM просто не был разработан с учетом этого типа аутентификации.
Настройка UsePAM yes
делает следующее:
ChallengeResponseAuthentication
иPasswordAuthentication
будет подключатьauth
стек PAM для проверки пароля. Любая форма аутентификации, отличная от этих двух методов, будетнеткоснитесьauth
стека.- При успешной аутентификации
account
стек PAM будет вызван для определения, разрешен ли доступ аутентифицированному пользователю. (всегда) - Стек
session
PAM будет вызываться для обработки задач настройки сеанса.
Резюме: Нет абсолютно никакого способа заставить двухфакторную аутентификацию, размещенную в auth
стеке, сработать для того, кто прошел аутентификацию с помощью GSSAPI или ssh-ключа. Вы можете использовать account
и session
стеки в сочетании с этими методами аутентификации, но это все, на что способен PAM.
решение3
Вот объяснение, как это сделать.https://cern-cert.github.io/pam_2fa/
- Основа: 2-факторная аутентификация с помощью pam
Модуль pam, который лучше понимает методы аутентификации SSH:
auth [успех=2 игнорировать=игнорировать по умолчанию=умереть] pam_ssh_user_auth.so
Недавний или исправленный OpenSSH для предоставления этого pam
Методы аутентификации gssapi-with-mic,клавиатура-интерактивная:pam открытый ключ,клавиатура-интерактивная:pam клавиатура-интерактивная:pam