
SSH-ключ надёжнее пароля, но если приватный ключ утечёт, атакующий получит полный доступ к серверу. Двухфакторная аутентификация добавляет второй рубеж: даже с ключом нужен одноразовый код из приложения. Настройка занимает 10 минут.
Дистрибутив: Ubuntu 22.04 / Debian 12. Приложение: Google Authenticator или любой TOTP-клиент (Aegis, Authy, 2FAS).
Что происходит при входе
После настройки SSH-сессия будет требовать:
SSH-ключ (или пароль, если ключи не используются)
Одноразовый 6-значный код TOTP из приложения на телефоне
Код обновляется каждые 30 секунд по алгоритму RFC 6238. Сервер и телефон синхронизированы по времени — важно, чтобы расхождение не превышало 30-60 секунд.
Установка libpam-google-authenticator
sudo apt update
sudo apt install libpam-google-authenticator -y
Пакет весит около 50 KB и не тянет лишних зависимостей.
Инициализация TOTP для пользователя
Выполняем от имени пользователя, для которого настраиваем 2FA (не от root, если планируете защищать отдельный аккаунт):
google-authenticator
Утилита задаёт несколько вопросов:
Do you want authentication tokens to be time-based (y/n) y
Отвечаем y — используем TOTP (Time-based One-Time Passwords).
После этого на экране появится QR-код для сканирования и резервные коды. QR-код сканируем в приложении Google Authenticator, Aegis или любом другом TOTP-клиенте.
Сохраните резервные коды. Это единственный способ войти на сервер, если телефон потерян или недоступен. Пример резервных кодов выглядит так:
Your emergency scratch codes are:
12345678
87654321
11223344
44332211
99887766
Каждый код одноразовый. Храните в надёжном месте — менеджер паролей подойдёт.
Остальные вопросы:
Do you want me to update your "/home/user/.google_authenticator" file (y/n) y
Do you want to disallow multiple uses of the same authentication token? (y/n) y
By default, a new token is generated every 30 seconds... Do you want to increase the window? (y/n) n
Do you want to enable rate-limiting (y/n) y
Rate-limiting (последний вопрос) ограничивает попытки ввода кода: не более 3 за 30 секунд.


Настройка PAM
PAM (Pluggable Authentication Modules) — система аутентификации Linux. Добавляем модуль Google Authenticator в конфиг SSH:
sudo nano /etc/pam.d/sshd
В начало файла добавляем строку:
auth required pam_google_authenticator.so
Если хотим, чтобы 2FA применялся только к пользователям, у которых он настроен (остальные входят без него):
auth required pam_google_authenticator.so nullok
nullok позволяет пользователям без настроенного .google_authenticator войти без кода. Удобно при поэтапном внедрении на сервере с несколькими пользователями.
Настройка sshd_config
Открываем конфигурацию SSH-сервера:
sudo nano /etc/ssh/sshd_config
Находим или добавляем:
ChallengeResponseAuthentication yes
На Ubuntu 22.04 и новее эта директива называется KbdInteractiveAuthentication:
KbdInteractiveAuthentication yes
Также убеждаемся, что PAM включён:
UsePAM yes
Совместное использование SSH-ключей и 2FA
По умолчанию при входе по SSH-ключу PAM-аутентификация не запускается — OpenSSH считает ключ достаточным. Чтобы требовать и ключ, и OTP-код, добавляем в sshd_config:
AuthenticationMethods publickey,keyboard-interactive
Эта строка означает: сначала проверяем ключ, затем запрашиваем интерактивный код (OTP).
Если хотим принимать ИЛИ ключ+OTP, ИЛИ пароль+OTP:
AuthenticationMethods publickey,keyboard-interactive keyboard-interactive
Применяем изменения:
sudo systemctl restart sshd
Важно: не закрывайте текущую SSH-сессию до проверки нового входа. Откройте второй терминал и попробуйте войти. Если что-то пошло не так, через открытую сессию можно исправить конфиг.

Проверка входа
С клиентской машины:
ssh user@server-ip
При правильной настройке процесс выглядит так:
Authenticated with partial success.
Verification code:
Вводим 6-значный код из приложения. Код принимается один раз — повторное использование в течение 30 секунд заблокировано.
2FA только для определённых пользователей
Если нужен 2FA только для группы пользователей, используем Match блок в sshd_config:
Match User deploy,staging
AuthenticationMethods publickey
Match User admin,root
AuthenticationMethods publickey,keyboard-interactive
Блоки Match обрабатываются сверху вниз. Пользователи deploy и staging входят только по ключу, admin и root требуют ключ + OTP.
2FA через SSH для sudo
Можно требовать OTP-код не только при входе по SSH, но и при использовании sudo. Редактируем /etc/pam.d/sudo:
sudo nano /etc/pam.d/sudo
Добавляем в начало:
auth required pam_google_authenticator.so
После этого каждый sudo запросит OTP-код. Удобно для серверов, где несколько администраторов используют один аккаунт — каждый генерирует коды со своего устройства.
Резервный вход при утере телефона
Четыре способа восстановить доступ:
Резервные коды — сохранённые при первоначальной настройке одноразовые коды.
Консольный доступ — через VNC/KVM (IPMI) у VPS-провайдера. Не требует SSH.
Rescue mode — большинство провайдеров предоставляет загрузку в режиме восстановления.
Удалить
~/.google_authenticator— через консоль провайдера. После удаления 2FA отключается для этого пользователя.

Итог
Google Authenticator через libpam-google-authenticator настраивается тремя шагами: установка пакета, запуск google-authenticator для генерации QR-кода, правка /etc/pam.d/sshd и sshd_config. Директива AuthenticationMethods publickey,keyboard-interactive требует оба фактора при входе по ключу. Резервные коды обязательно сохранить до перезапуска sshd — иначе рискуете остаться без доступа.