В предыдущей статье я рассказал, как добавить проверку одноразовых кодов при логине на свой сервер по SSH. Статья завершалась словами «если ходим по ключу — двухфакторная аутентификация не работает (не используется PAM)».
С недавнего времени, после выпуска OpenSSH версии 6.2, ситуация поменялась к лучшему.
+
Рассмотрю пример настройки: аутентификация по ключу и, затем, по одноразовому коду. У меня используется Debian Jessie (testing), там всё доступно «из коробки».
С момента написания прошлой статьи консольную тулзу положили рядом с модулем, поэтому на сервере нужен лишь один новый пакет:
На телефон с Android'ом ставим Google Autenticator и какой-либо сканер QR кодов, например такой. Если у вас на телефоне Windows Phone, то программа называется Authenticator (thnx to Skywrtr). Если у вас телефон с другой ОС, то вам сюда.
После запуска этой команды:
первым вопросом будет, хотим ли мы time-based токены. Ответ — «y».
В ответ получаем ASCII-art с таким симпатичным QR кодом, содержащим в себе секретный ключ (картинка кликабельная):
Также, если вы хотите добавить данные в Google Authenticator вручную — выводятся сам секретный код инициализации и код для проверки.
Также имеет смысл записать в надёжном месте 5 резервных кодов на случай, если вдруг с телефоном что-то случится. А по URL, который тулза тоже пишет, ходить не нужно — там лишь рисуется тот же самый QR код покрасивее. Вы ведь не хотите показывать свой секретный код Гуглу? :)
QR код сразу сканируем из приложения в телефоне, потом отвечаем на вопросы в консоли.
— Сохранить всё насовсем в ~/.google_authenticator?
— y
— Запретить использование одного кода несколько раз? Помогает заметить или даже предотвратить атаку man-in-the-middle.
— y
— Увеличить окно времени с приблизительно 1.5 минут до 4 минут?
— n (и тут сразу проверяем, точно ли время в телефоне; впрочем, Google Authenticator последних версий умеет синхронизировать время из интернета)
— Ограничить число попыток логина за промежуток времени?
— y
В файле /etc/pam.d/sshd в группе «auth» должна быть лишь одна строка с вызовом модуля pam_google_authenticator.so:
Обращаю внимание на важный момент: с одной стороны, нужно закомментировать все строки и инклюды, добавляющие в группу «auth» проверку пароля, (например, «@include common-auth» выше), иначе у вас после одноразового кода спросят и пароль. С другой стороны, надо понимать, что аутентификация по паролю, которая в большинстве современных дистрибутивов также делается через PAM, будет таким образом сломана. Но это неопасно, т.к. ниже мы явно указываем серверу sshd, что проверка ключа обязательна и без правильного ключа авторизация будет неуспешна.
Пока я не придумал, как можно сделать в PAM одновременно два сценария, например «ключ + одноразовый код» и «пароль + одноразовый код».
Можно сделать так, чтобы одноразовый код спрашивался не для всех. Для этого есть модуль pam_access.so, который нужно вписать перед pam_google_authenticator.so:
В файл /etc/ssh/two-factor-skip.conf можно указать что-то эдакое:
В /etc/ssh/sshd_config включаем ChallengeResponse аутентификацию, PAM и указываем, что нужно проверять как ключ, так и одноразовый пароль.
Затем:
Все консольные команды (ssh, scp, sftp) OpenSSH версии 5.9p1 и, очевидно, позднее — поддерживают ChallengeResponse аутентификацию. Более старые версии не проверял.
lftp версий 4.3.3 и 4.4.8 не поддерживает. Другие версии не проверял.
По данным funditus
Если кто-либо сможет проверить другие программы на (не)совместимость, пишите мне в личку — я допишу сюда.
С недавнего времени, после выпуска OpenSSH версии 6.2, ситуация поменялась к лучшему.
+
sshd(8): Added support for multiple required authentication in SSH protocol 2 via an AuthenticationMethods option. This option lists one or more comma-separated lists of authentication method names. Successful completion of all the methods in any list is required for authentication to complete.
sshd(8): Добавлена поддержка множественных способов аутентификации в SSH протоколе 2 посредством параметра AuthenticationMethods. Этот параметр задаёт один или более списков с запятой-разделителем, перечисляющих названия методов аутентификации. Для аутентификации требуется успешное завершение всех методов в любом из списков.
Начинаем
Рассмотрю пример настройки: аутентификация по ключу и, затем, по одноразовому коду. У меня используется Debian Jessie (testing), там всё доступно «из коробки».
Ставим нужный софт
С момента написания прошлой статьи консольную тулзу положили рядом с модулем, поэтому на сервере нужен лишь один новый пакет:
apt-get install libpam-google-authenticator
На телефон с Android'ом ставим Google Autenticator и какой-либо сканер QR кодов, например такой. Если у вас на телефоне Windows Phone, то программа называется Authenticator (thnx to Skywrtr). Если у вас телефон с другой ОС, то вам сюда.
Инициализация одноразовых кодов
После запуска этой команды:
google-authenticator
первым вопросом будет, хотим ли мы time-based токены. Ответ — «y».
В ответ получаем ASCII-art с таким симпатичным QR кодом, содержащим в себе секретный ключ (картинка кликабельная):
Также, если вы хотите добавить данные в Google Authenticator вручную — выводятся сам секретный код инициализации и код для проверки.
Также имеет смысл записать в надёжном месте 5 резервных кодов на случай, если вдруг с телефоном что-то случится. А по URL, который тулза тоже пишет, ходить не нужно — там лишь рисуется тот же самый QR код покрасивее. Вы ведь не хотите показывать свой секретный код Гуглу? :)
QR код сразу сканируем из приложения в телефоне, потом отвечаем на вопросы в консоли.
— Сохранить всё насовсем в ~/.google_authenticator?
— y
— Запретить использование одного кода несколько раз? Помогает заметить или даже предотвратить атаку man-in-the-middle.
— y
— Увеличить окно времени с приблизительно 1.5 минут до 4 минут?
— n (и тут сразу проверяем, точно ли время в телефоне; впрочем, Google Authenticator последних версий умеет синхронизировать время из интернета)
— Ограничить число попыток логина за промежуток времени?
— y
Настройка PAM
В файле /etc/pam.d/sshd в группе «auth» должна быть лишь одна строка с вызовом модуля pam_google_authenticator.so:
--- /etc/pam.d/sshd.orig 2013-05-22 05:05:49.000000000 +0400
+++ /etc/pam.d/sshd 2013-09-04 16:36:43.141649326 +0400
@@ -1,7 +1,9 @@
# PAM configuration for the Secure Shell service
+auth required pam_google_authenticator.so
+
# Standard Un*x authentication.
-@include common-auth
+#@include common-auth
# Disallow non-root logins when /etc/nologin exists.
account required pam_nologin.so
Обращаю внимание на важный момент: с одной стороны, нужно закомментировать все строки и инклюды, добавляющие в группу «auth» проверку пароля, (например, «@include common-auth» выше), иначе у вас после одноразового кода спросят и пароль. С другой стороны, надо понимать, что аутентификация по паролю, которая в большинстве современных дистрибутивов также делается через PAM, будет таким образом сломана. Но это неопасно, т.к. ниже мы явно указываем серверу sshd, что проверка ключа обязательна и без правильного ключа авторизация будет неуспешна.
Пока я не придумал, как можно сделать в PAM одновременно два сценария, например «ключ + одноразовый код» и «пароль + одноразовый код».
Настройка PAM, дополнительные плюшки
Можно сделать так, чтобы одноразовый код спрашивался не для всех. Для этого есть модуль pam_access.so, который нужно вписать перед pam_google_authenticator.so:
auth sufficient pam_access.so accessfile=/etc/ssh/two-factor-skip.conf
auth required pam_google_authenticator.so
В файл /etc/ssh/two-factor-skip.conf можно указать что-то эдакое:
# В локальной сети ходим только лишь с ключём
+ : ALL : 192.168.1.0/24
# Этот юзер не может вводить одноразовые коды
+ : oldskool : ALL
# Всех остальных заставим вводить ещё и одноразовый код
- : ALL : ALL
Настройка sshd
В /etc/ssh/sshd_config включаем ChallengeResponse аутентификацию, PAM и указываем, что нужно проверять как ключ, так и одноразовый пароль.
ChallengeResponseAuthentication yes
UsePAM yes
AuthenticationMethods publickey,keyboard-interactive
Затем:
service ssh reload
Проверяем
Совместимость
Все консольные команды (ssh, scp, sftp) OpenSSH версии 5.9p1 и, очевидно, позднее — поддерживают ChallengeResponse аутентификацию. Более старые версии не проверял.
lftp версий 4.3.3 и 4.4.8 не поддерживает. Другие версии не проверял.
По данным funditus
Irssi Conectbot на Android — поддерживает.
SecureCRT — поддерживает, но в настройках соединения необходимо установить Keyboard-interactive и Publickey.
Putty — поддерживает.
Если кто-либо сможет проверить другие программы на (не)совместимость, пишите мне в личку — я допишу сюда.