В эпоху удалённого управления серверами двухфакторная аутентификация (2FA) стала обязательным элементом защиты. Стандартный подход – использование PAM‑модулей в сочетании с TOTP‑токенами. В статье мы покажем, как построить полностью кастомный механизм 2FA, который будет работать в любой терминальной службе Linux (SSH, sudo, su) и как использовать Android‑приложение Termux в роли надёжного TOTP‑генератора.
Краткий обзор PAM
Pluggable Authentication Modules (PAM) – это гибкая система, позволяющая добавлять, удалять и комбинировать методы аутентификации без изменения ядра сервисов. Каждый сервис (например, sshd или login) имеет файл конфигурации /etc/pam.d/имя_сервиса, где перечислены используемые модули и их порядок.
Для внедрения 2FA нам потребуются два модуля:
pam_unix.so– проверка пароля пользователя.pam_google_authenticator.so– проверка одноразового кода, сгенерированного по алгоритму TOTP.
Установка пакета libpam-google-authenticator
На большинстве дистрибутивов пакет доступен в официальных репозиториях. Ниже приведены команды для Debian/Ubuntu и Arch Linux.
# Debian/Ubuntu
apt update && apt install -y libpam-google-authenticator
# Arch Linux
pacman -Sy libpam-google-authenticator
После установки появится исполняемый файл google-authenticator, который генерирует секретный ключ и QR‑код для вашего TOTP‑клиента.
Настройка TOTP‑генератора в Termux
Termux – это терминальное приложение для Android, позволяющее запускать полноценный Linux‑окружение. Для генерации кодов мы будем использовать пакет oathtool, входящий в состав coreutils и libotp.
# Установка необходимых пакетов в Termux
pkg update && pkg upgrade -y
pkg install -y oathtool qrencode
# Сохранение секретного ключа в безопасном месте
echo "JBSWY3DPEHPK3PXP" > $HOME/.totp_secret
Для удобства можно добавить в ~/.bashrc функцию, генерирующую код по запросу:
function totp() {
local secret=$(cat $HOME/.totp_secret)
oathtool --totp -b "$secret"
}
# После перезапуска терминала можно вызвать
# $ totp
Сгенерированный QR‑код можно отобразить в Termux, используя qrencode:
qrencode -t ANSI256 "otpauth://totp/username@hostname?secret=$(cat $HOME/.totp_secret)&issuer=RybinskLab"
Сканируйте полученный QR‑код любой TOTP‑приложением (Google Authenticator, Authy) – ваш Android‑устройство будет готово к работе.
Инициализация пользователя на сервере
Каждому пользователю, которому требуется 2FA, необходимо запустить google-authenticator и сохранить выданный секретный ключ. Это делается один раз, после чего пользователь может использовать любой TOTP‑клиент, включая наш Termux‑скрипт.
# Выполняется от имени пользователя
google-authenticator -t -d -f -r 3 -R 30 -w 3
Опции:
-t– использовать временные коды (TOTP).-d– запрещать резервные коды.-f– принудительно перезаписать существующий файл.google_authenticator.-r 3– разрешить максимум 3 попытки ввода кода.-R 30– окно в 30 секунд.-w 3– разрешить откат до 3 шагов (для синхронизации часов).
Конфигурация PAM для SSH
Откройте файл /etc/pam.d/sshd и добавьте строку перед проверкой пароля:
auth required pam_google_authenticator.so nullok
Затем отредактируйте /etc/ssh/sshd_config:
# Включаем использование PAM
UsePAM yes
# Требуем ввод пароля + TOTP
ChallengeResponseAuthentication yes
PasswordAuthentication no
Перезапустите службу SSH:
systemctl restart sshd
Теперь при подключении к серверу пользователь будет вводить сначала пароль, а затем одноразовый код, полученный в Termux.
Создание собственного PAM‑модуля (опционально)
Для более тонкой настройки (например, проверка наличия устройства, ограничение по IP или интеграция с LDAP) можно написать собственный модуль на C. Ниже – минимальный шаблон.
#include <security/pam_modules.h>
#include <security/pam_ext.h>
#include <stdio.h>
PAM_EXTERN int pam_sm_authenticate(pam_handle_t pamh, int flags,
int argc, const char argv) {
const char user;
pam_get_user(pamh, &user, NULL);
pam_info(pamh, "Custom 2FA for user %s", user);
/ Здесь реализуем проверку TOTP, например, через libotp /
return PAM_SUCCESS; // или PAM_AUTH_ERR при ошибке
}
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags,
int argc, const char argv) {
return PAM_SUCCESS;
}
Скомпилировать модуль:
gcc -fPIC -shared -o pam_custom_2fa.so pam_custom_2fa.c -lpam -lrt
Поместить полученный pam_custom_2fa.so в /lib/security/ и добавить в конфиг, например, в /etc/pam.d/sudo:
auth required pam_custom_2fa.so
Таким образом, любой сервис, использующий PAM, получит ваш кастомный уровень защиты.
Тестирование и отладка
Для быстрой проверки можно воспользоваться утилитой pamtester:
pamtester sshd username authenticate
Если всё настроено правильно, консоль запросит пароль, а затем одноразовый код. При ошибке в логах (/var/log/auth.log или /var/log/secure) ищите сообщения от pam_google_authenticator или вашего кастомного модуля.
Рекомендации по безопасности
- Всегда используйте синхронизацию времени (NTP) как на сервере, так и на клиентском устройстве.
- Храните секретный ключ в зашифрованном виде; в Termux рекомендуется использовать
gpg --symmetricдля защиты.totp_secret. - Ограничьте доступ к файлам
.google_authenticatorправами600. - Регулярно проверяйте логи на предмет попыток перебора кода.
- При необходимости внедрите политику блокировки аккаунта после N неудачных попыток (параметр
denyв/etc/pam.d/common-auth).
Заключение
Внедрение двухфакторной аутентификации через PAM и TOTP‑генератор в Termux позволяет создать надёжный, гибко настраиваемый и полностью автономный механизм защиты терминальных сервисов Linux. Такой подход минимизирует риски компрометации паролей и упрощает процесс управления токенами за счёт использования привычного мобильного устройства.
Если вы хотите получить профессиональную консультацию, разработку кастомных PAM‑модулей или настройку 2FA под ваш бизнес‑процесс, обратитесь в RybinskLab. Мы поможем ускорить внедрение безопасных решений, проведём аудит инфраструктуры и обеспечим поддержку на всех этапах проекта.