opened image

Настройка 2FA для SSH: двухфакторная аутентификация на сервере

 

SSH-ключ надёжнее пароля, но если приватный ключ утечёт, атакующий получит полный доступ к серверу. Двухфакторная аутентификация добавляет второй рубеж: даже с ключом нужен одноразовый код из приложения. Настройка занимает 10 минут.

 

Дистрибутив: Ubuntu 22.04 / Debian 12. Приложение: Google Authenticator или любой TOTP-клиент (Aegis, Authy, 2FAS).

 

 

Что происходит при входе

 

После настройки SSH-сессия будет требовать:

  1. SSH-ключ (или пароль, если ключи не используются)

  2. Одноразовый 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-код. Удобно для серверов, где несколько администраторов используют один аккаунт — каждый генерирует коды со своего устройства.

 

 

Резервный вход при утере телефона

 

Четыре способа восстановить доступ:

  1. Резервные коды — сохранённые при первоначальной настройке одноразовые коды.

  2. Консольный доступ — через VNC/KVM (IPMI) у VPS-провайдера. Не требует SSH.

  3. Rescue mode — большинство провайдеров предоставляет загрузку в режиме восстановления.

  4. Удалить ~/.google_authenticator — через консоль провайдера. После удаления 2FA отключается для этого пользователя.

 

 

 

Итог

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