4 September 2013

Двухфакторная аутентификация в OpenSSH: ключ+одноразовый код

System administration
В предыдущей статье я рассказал, как добавить проверку одноразовых кодов при логине на свой сервер по SSH. Статья завершалась словами «если ходим по ключу — двухфакторная аутентификация не работает (не используется PAM)».

С недавнего времени, после выпуска 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 — поддерживает.


Если кто-либо сможет проверить другие программы на (не)совместимость, пишите мне в личку — я допишу сюда.

Ссылки


  1. OpenSSH 6.2 Release Notes
  2. Установка приложения Google Authenticator
  3. Google Authenticator
  4. Сканер QR кодов
Tags:authenticationgoogleдвухфакторная аутентификацияpamlinuxdebianandroidiphoneblackberrysshopenssh
Hubs: System administration
+50
26.3k 358
Comments 24
Popular right now
Flutter Developer
to 160,000 ₽КлючМосква
Android
from 150,000 ₽NatsONМоскваRemote job
Web аналитик
from 1,200 to 1,800 $InsightWhaleRemote job
Digital Marketing Manager | Google Ads
from 1,000 $GOAT digitalRemote job
Android-разработчик
from 80,000 ₽FlowwowRemote job