Двухфакторная аутентификация для Ubuntu
Второй фактор при входе в Ubuntu обеспечивает PAM-адаптер Simple2FA. Он устанавливается на сервер или рабочую станцию и обращается к бэкенду локального инстанса по HTTPS. Где именно будет запрашиваться второй фактор, определяет то, в какие PAM-стеки добавлена строка адаптера: локальный вход, вход по SSH или вход по RDP (xRDP).
Для проверки используется логин пользователя ОС, и пользователь с таким логином должен быть в Simple2FA. В каталоге организации он обязан быть только при SendPassword = true — тогда по каталогу проверяется пароль. При SendPassword = false подойдёт и локальная учётная запись Linux, заведённая в панели вручную.
Инструкция проверялась на Ubuntu 22.04.
Схема работы:
- Пользователь входит в систему и вводит логин и пароль.
- Первый фактор проверяется по режиму
SendPassword: приfalseпароль проверяют штатные средства ОС и на сервер он не передаётся; приtruePAM-адаптер передаёт логин и пароль локальному инстансу, и тот проверяет их по каталогу организации (LDAP, Active Directory или Keycloak). - После успешной проверки первого фактора адаптер запрашивает у локального инстанса подтверждение вторым фактором.
- Пользователь подтверждает вход.
- После успешной проверки сессия предоставляется пользователю.
Требования
- Ubuntu с PAM в системе.
- Для сценария SSH — OpenSSH-сервер с поддержкой PAM.
- Для сценария RDP — установленный xRDP.
- Сетевой доступ к локальному инстансу Simple2FA по HTTPS — на порт из его адреса (обычно 443).
- Корректное системное время (NTP) на машине и на локальном инстансе.
- Права root для установки адаптера и изменения конфигурации PAM.
- Архитектура хоста x86_64 или aarch64 и glibc 2.28 или новее — версию покажет
ldd --version.
Доступ к локальному инстансу обязателен
Без него проверка второго фактора не выполняется, и вход не пройдёт.
Подготовка в Simple2FA
Войдите в панель администратора локального инстанса, перейдите в раздел «Настройка ресурсов» и создайте новый ресурс:
| Поле | Значение |
|---|---|
| Название | Ubuntu — или любое удобное |
| Протокол | HTTPS |
| Проверять первый фактор | Включить при SendPassword = true, отключить при SendPassword = false |
| Поставщики учётных записей | При SendPassword = true — один или несколько каталогов, в которых проверяется первый фактор |
| Использовать кеширование сессий | Включить, если после успешного входа второй фактор не должен запрашиваться повторно в течение указанного времени |
| Длительность кеша | Рекомендуемое значение — 60 минут |
После сохранения ресурса скопируйте его ключ (API key ресурса) — он указывается в файле конфигурации PAM-адаптера.
Один ресурс может использоваться на любом числе серверов: его ключ указывается в конфигурации каждого из них. Подробнее — в статье Группа серверов.
Кеш сессий работает по паре «пользователь + IP»
Для входа по SSH адаптер передаёт адрес подключающегося клиента. При локальном входе и при вызове sudo этого адреса нет — тогда адаптер передаёт адрес первого не-loopback интерфейса самого хоста, и кеш привязывается к нему.
В глобальных настройках убедитесь, что указан корректный API-ключ организации для связи локального инстанса с облаком.
Установка PAM-адаптера
Установите модуль из комплекта
Адаптер поставляется комплектом: архив с модулем simple2fa_pam.so под обе архитектуры, установщиком install.sh, шаблоном конфигурации и инструкцией. Распакуйте архив на защищаемом хосте и запустите установщик от root:
sudo ./install.sh
Установщик:
- определяет архитектуру хоста (
x86_64илиaarch64) и берёт из комплекта нужный файл модуля; - находит каталог модулей PAM — тот, в котором лежит штатный
pam_unix.so, — и копирует модуль туда; - создаёт каталоги
/etc/simple2faи/var/log/simple2fa; - кладёт в
/etc/simple2faшаблон конфигурацииs2fa_conf.toml.example.
Рабочий файл s2fa_conf.toml установщик не создаёт и не перезаписывает, строку в /etc/pam.d/ не добавляет: и то и другое делается вручную — в разделах ниже.
Вторая копия модуля в системе
Если установщик сообщает WARNING: another simple2fa_pam.so is at …, удалите лишний файл: PAM может загрузить старую копию вместо новой.
Каталог модулей PAM можно задать и вручную:
sudo LIBDIR=/usr/lib/security ./install.sh
Для справки, где этот каталог обычно находится: в Debian и Ubuntu — /lib/<архитектура>-linux-gnu/security/, в Astra Linux — /usr/lib/security/, в RHEL и совместимых системах — /usr/lib64/security/.
Создайте конфигурацию
Адаптер настраивается файлом /etc/simple2fa/s2fa_conf.toml. Скопируйте шаблон, который положил установщик, и отредактируйте его:
sudo cp /etc/simple2fa/s2fa_conf.toml.example /etc/simple2fa/s2fa_conf.toml
sudo chmod 0640 /etc/simple2fa/s2fa_conf.toml
Файл можно положить и по другому пути — тогда он указывается аргументом conf= в строке PAM.
Обязательных параметров два: ApiKey и Simple2faUrl. Остальные можно не указывать, применяются значения по умолчанию.
| Параметр | По умолчанию | Назначение |
|---|---|---|
ApiKey |
— | Ключ ресурса из панели. Ключ организации и ключ RADIUS-ресурса не подходят |
Simple2faUrl |
— | Адрес бэкенда локального инстанса (local-backend), без пути. Адрес панели администратора не подходит |
SendPassword |
false |
Кто проверяет первый фактор. true — пароль передаётся в Simple2FA и проверяется по каталогу организации; false — пароль проверяет ОС и на сервер не передаётся |
Method |
"auto" |
Способ подтверждения: auto, push, telegram, max, otp. При auto применяется способ, выбранный пользователем |
AskMethod |
false |
При Method = "auto" и нескольких настроенных способах предложить пользователю выбор |
OtpPrompt |
OTP |
Текст приглашения для ввода кода |
MethodPrompt |
Способ подтверждения |
Текст приглашения при выборе способа |
WaitSeconds |
60 |
Сколько ждать подтверждения |
PollIntervalSeconds |
2 |
Интервал опроса состояния |
HttpTimeoutSeconds |
8 |
Таймаут одного запроса |
Timeout |
45 |
Таймаут запроса к инстансам предыдущих версий |
Debug |
false |
Подробный журнал. В рабочем режиме отключить |
LogFile |
/var/log/simple2fa/simple2fa.log |
Файл журнала, режим 0600 |
SkipCertValidation |
false |
Отключить проверку сертификата. Для самоподписанных сертификатов |
Пример файла конфигурации:
ApiKey = "<ключ ресурса>"
Simple2faUrl = "https://<адрес бэкенда локального инстанса>"
SendPassword = false
Method = "auto"
Debug = false
SkipCertValidation = false
Строковые значения — в двойных кавычках
Без кавычек файл не разбирается и вход отклоняется; символ # в незакавыченном значении обрезает его до конца строки. По той же причине вход отклоняется, если файла нет, он недоступен по правам или в нём не заполнены ApiKey и Simple2faUrl. Причина отказа пишется в журнал модуля.
Адрес бэкенда, а не панели администратора
У бэкенда локального инстанса свой адрес, отдельный от адреса панели: при установке инстанса они задаются как DOMAIN_API и DOMAIN_ADMIN. В Simple2faUrl указываются только протокол, имя хоста и порт бэкенда — путь запроса адаптер добавляет сам. Схема должна совпадать с той, по которой бэкенд опубликован: перенаправлениям адаптер намеренно не следует, поэтому адрес с http:// при переадресации на HTTPS даёт отказ (в журнале — http_status=301). При самоподписанном сертификате укажите https:// и добавьте SkipCertValidation = true.
Файл содержит ключ ресурса
Ограничьте доступ к нему правами root.
Параметр UseOTP устарел. Если он остался в файле со значением true, адаптер понимает его как Method = "otp" и пишет предупреждение в журнал; в новых установках используйте Method.
Выберите способ подтверждения
По умолчанию (Method = "auto") применяется способ, выбранный пользователем в профиле. Чтобы на этом хосте всегда использовался один способ, укажите его явно: push, telegram, max или otp.
Method = "otp"— адаптер сам запрашивает одноразовый код приглашением изOtpPrompt. Способ требует интерактивного ввода.AskMethod = trueвместе сMethod = "auto"— если у пользователя настроено несколько способов, адаптер выведет их нумерованным списком и спросит, каким подтверждать вход.- Если указанный способ у пользователя не настроен, вход отклоняется (в журнале —
method_not_configured).
Подтверждения адаптер ждёт WaitSeconds секунд, опрашивая инстанс каждые PollIntervalSeconds.
Сервисы без интерактивного ввода
Некоторые сервисы вызывают адаптер с подавленными приглашениями. Ввести код в таком сценарии нельзя, и вход с Method = "otp" или с AskMethod = true будет отклонён (interactive_prompt_suppressed); подтверждение через push, Telegram и MAX работает и без приглашений.
Подключите адаптер к PAM
Строка подключения адаптера выглядит так:
auth required simple2fa_pam.so conf=/etc/simple2fa/s2fa_conf.toml
Аргумент conf= можно опустить, если файл лежит по пути по умолчанию. Всего модуль понимает три аргумента:
| Аргумент | Назначение |
|---|---|
conf=/путь/к/s2fa_conf.toml |
Путь к файлу конфигурации |
method=<способ> |
Способ подтверждения для этого сервиса — auto, push, telegram, max или otp; перекрывает Method из файла |
debug |
Подробный журнал независимо от Debug в файле |
Аргумент method= позволяет требовать на одном хосте разные способы для разных сервисов — например, одноразовый код для sudo и push для входа по SSH. Неизвестные аргументы модуль записывает в журнал и продолжает проверку.
Где ставить строку, зависит от режима SendPassword:
SendPassword = false— строка адаптера ставится после штатной проверки пароля: послеpam_unix.soили после подключения общего стека (@include common-auth,substack system-auth). Иначе подтверждение уйдёт пользователю до проверки пароля, и любой, кто набрал чужой логин, сможет забросать его уведомлениями.SendPassword = true— строка ставится вместо штатной проверки пароля: логин и пароль проверит Simple2FA по каталогу организации.
Контроли required и requisite оба отклоняют вход при неуспешной проверке; requisite прерывает стек сразу, не выполняя следующие модули.
В какие файлы добавлять эту строку — в разделах ниже: у каждого сценария входа свой PAM-стек.
Локальный вход
Локальный вход в Ubuntu настраивается через общий PAM-стек аутентификации. Добавьте строку PAM-адаптера в файл:
/etc/pam.d/common-auth
Стек общий для всей системы
common-auth подключается к большинству сервисов системы, поэтому изменения затронут и другие сценарии входа. Перед изменением сделайте резервную копию файла и держите открытой активную root-сессию до успешной проверки входа.
Вход по SSH
-
Добавьте строку PAM-адаптера в
/etc/pam.d/sshd.Не добавляйте адаптер дважды
Если строка уже добавлена в
common-auth, повторно добавлять её вsshdне нужно — иначе второй фактор будет запрашиваться дважды. -
Убедитесь, что в
/etc/ssh/sshd_configвключены поддержка PAM и интерактивная аутентификация:UsePAM yes KbdInteractiveAuthentication yes -
Перезапустите SSH:
sudo systemctl restart sshd
Вход по ключу и второй фактор
По умолчанию аутентификация по SSH-ключу выполняется в обход PAM-стека, и второй фактор не запрашивается. Чтобы требовать и ключ, и подтверждение, укажите в /etc/ssh/sshd_config цепочку методов:
UsePAM yes
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Первый фактор здесь уже подтверждён ключом, поэтому для такого сценария используйте SendPassword = false.
После изменения перезапустите SSH:
sudo systemctl restart sshd
Вход по RDP (xRDP)
-
Установите и запустите xRDP:
sudo apt -y install xrdp sudo systemctl restart xrdp -
Откройте порт RDP:
sudo ufw allow 3389 -
Добавьте строку PAM-адаптера в
/etc/pam.d/xrdp-sesman. -
Перезапустите xRDP:
sudo systemctl restart xrdp
Способ подтверждения для RDP
При подключении по RDP интерактивный ввод одноразового кода может быть недоступен: задайте способ, который ввода не требует — Method = "push" в конфигурации или аргумент method=push в строке этого стека.
Исключение группы из проверки
Если для отдельной группы (например, localadmins) второй фактор запрашивать не нужно, добавьте перед строкой адаптера стандартный модуль pam_succeed_if:
auth [success=1 default=ignore] pam_succeed_if.so user ingroup localadmins
auth required simple2fa_pam.so
Для пользователей группы строка адаптера будет пропущена, для остальных — выполнена. Приём применим в любом PAM-стеке.
Каждое исключение — вход без второго фактора
Оставляйте в группе исключений минимум учётных записей. Точечные исключения для отдельных пользователей удобнее задавать в панели — в карточке пользователя или в политике группы.
Журнал модуля
Модуль пишет по одной строке на событие — в свой файл и в syslog:
- файл
/var/log/simple2fa/simple2fa.log(или путь изLogFile), права0600; каталог/var/log/simple2faсоздаётся при установке; - syslog — facility
authpriv, идентификаторsimple2fa_pam.
Пароль, одноразовый код и ключ ресурса в журнал не попадают.
sudo tail -n 50 /var/log/simple2fa/simple2fa.log
sudo journalctl -t simple2fa_pam -e
sudo grep simple2fa_pam /var/log/auth.log /var/log/secure 2>/dev/null
Проверка работы
- Выполните вход в систему — локально, по SSH или по RDP, не закрывая текущую сессию.
- Введите логин и пароль пользователя (или пройдите проверку по ключу).
- Дождитесь запроса второго фактора.
- Подтвердите вход.
- После успешной проверки сессия будет предоставлена.
Если второй фактор у пользователя не настроен
Адаптер покажет ссылку на мастер настройки и отклонит вход. В режиме SendPassword = true ссылка появляется только после того, как сервер подтвердил пароль.
Результат каждой попытки входа доступен в панели администратора, в разделе «Попытки авторизации».
Если что-то не работает
Последовательно проверьте, что:
- пользователь с таким логином существует в каталоге организации и в Simple2FA и настроил второй фактор;
- с машины открыт сетевой доступ к локальному инстансу;
- в файле конфигурации указаны ключ ресурса с протоколом HTTPS и адрес бэкенда локального инстанса — со схемой, по которой бэкенд опубликован, и без пути API;
- установщик сообщил, в какой каталог положил модуль, и второй копии
simple2fa_pam.soв системе нет; - строковые значения в файле конфигурации взяты в двойные кавычки, а сам файл доступен root;
- строка адаптера добавлена в нужный PAM-стек и стоит в нём на месте, соответствующем выбранному режиму
SendPassword; - адаптер не подключён дважды — в
common-authи вsshdодновременно; - пользователь не входит в группу исключений, если она настроена;
- системное время на машине и на локальном инстансе синхронизировано;
- в панели администратора, в разделе «Попытки авторизации» отображаются попытки входа и их результат.
На время диагностики включите в конфигурации Debug = true (или добавьте аргумент debug в строку PAM), а после — верните false.
Модуль не загружается
Если файл журнала пуст или не создан, загрузка модуля могла не состояться — тогда причина видна в журнале самой службы (sshd, sudo, дисплей-менеджера), а не в журнале модуля:
file simple2fa_pam.so
uname -m
sudo journalctl -u sshd -e | grep -i pam
sudo grep -E 'simple2fa_pam|undefined symbol' /var/log/auth.log /var/log/secure 2>/dev/null
| Сообщение в журнале службы | Причина |
|---|---|
wrong ELF class, Exec format error |
Архитектура файла модуля не совпадает с архитектурой хоста |
GLIBC_2.xx not found |
Модуль собран на более новой версии glibc, чем установлена на хосте |
cannot open shared object file |
Файла нет в каталоге модулей PAM или он недоступен по правам |
undefined symbol: pam_sm_acct_mgmt |
Устаревшая сборка модуля |
Отказы в журнале модуля
| Запись | Причина |
|---|---|
config file is invalid |
Значения в TOML без кавычек или опечатка в файле |
http_status=301 или 302 |
В Simple2faUrl указан http://, а бэкенд перенаправляет на HTTPS |
api_key_rejected |
Указан ключ организации или ключ RADIUS-ресурса вместо ключа этого ресурса |
http_status=404 или 403 на check-user |
Пользователя нет в Simple2FA, он неактивен или у него нет доступа к ресурсу |
setup_required |
Пользователь не настроил второй фактор |
method_not_configured |
Способ из Method у пользователя не настроен |
interactive_prompt_suppressed |
Сервис вызвал адаптер с подавленными приглашениями, а выбранный способ требует ввода |
timeout |
Подтверждение не пришло за WaitSeconds |
Альтернатива: подключение через pam_radius
Если на серверах уже используется стандартный модуль pam_radius или установка стороннего ПО на защищаемые хосты запрещена, второй фактор для SSH и sudo можно подключить без PAM-адаптера — напрямую к встроенному RADIUS-серверу локального инстанса. Пошаговая инструкция и сравнение способов — в статье PAM RADIUS.