Настройка SSH с двухфакторной аутентификацией (2FA): TOTP и YubiKey для Debian, Ubuntu, CentOS | AdminWiki

Настройка SSH с двухфакторной аутентификацией (2FA): TOTP и YubiKey для Debian, Ubuntu, CentOS

12 мая 2026 13 мин. чтения
Содержание статьи

Содержание

Зачем SSH нужна двухфакторная аутентификация и как выбрать метод

SSH 2FA добавляет независимый второй фактор к SSH-ключу. Если приватный ключ скомпрометирован из-за утечки или атаки на рабочую станцию, одного ключа для входа будет недостаточно. Это снижает риск несанкционированного доступа к критически важным серверам.

Выберите маршрут SSH 2FA

  • SSH-ключ + TOTP - основной сценарий для большинства команд. Код из Google Authenticator, Authy или Microsoft Authenticator проверяется через PAM.
  • SSH-ключ, защищенный YubiKey FIDO2, + PIN - сценарий для high-security-сред. Используется FIDO2 security key OpenSSH, а ключевой материал не покидает аппаратный ключ.

Выберите один маршрут для конкретной учетной записи и не смешивайте правила TOTP и YubiKey в одном PAM-стеке. Перед применением на production-сервере подготовьте и протестируйте сценарий восстановления доступа.

Совместимость Debian, Ubuntu и RHEL-подобных систем

Дистрибутив SSH-ключ + TOTP YubiKey для SSH Перезагрузка службы
Debian/Ubuntu libpam-oath, oathtool, модуль pam_oath OpenSSH с поддержкой security key; ключ создается на рабочей станции sudo systemctl reload ssh
RHEL/CentOS Stream/Rocky Linux 8/9 pam_oath, oathtool; в зависимости от релиза может потребоваться EPEL OpenSSH с поддержкой security key; fido2-tools полезен для диагностики устройства sudo systemctl reload sshd

Перед внедрением проверьте доступность пакетов и поддержку OpenSSH в репозиториях конкретной версии Linux. Пакет libfido2-dev нужен для разработки и не требуется для обычного использования YubiKey в SSH.

Выбор между TOTP (Time-based One-Time Password) и аппаратными ключами FIDO2/U2F зависит от требований к безопасности, бюджета и удобства команды.

TOTP (Google Authenticator): универсальность и простота

Метод TOTP генерирует одноразовые шестизначные коды, которые обычно меняются каждые 30 секунд. Секретный ключ хранится на сервере и в мобильном приложении пользователя (Google Authenticator, Authy, Microsoft Authenticator).

Преимущества TOTP:

  • Не требует дополнительного оборудования. Достаточно смартфона.
  • Работает офлайн. Приложение генерирует коды без интернета.
  • Широкая поддержка. Множество бесплатных приложений для всех платформ.
  • Простота развертывания и администрирования.

Главный недостаток - уязвимость к фишингу. Если пользователь введет одноразовый код на фейковом сайте, атакующий сможет использовать его для входа. Также критична синхронизация времени между сервером и устройством пользователя.

Аппаратные ключи (YubiKey): защита SSH через FIDO2

FIDO2 security key для SSH использует криптографию с открытым ключом: закрытая часть ключа остается в YubiKey, а OpenSSH проверяет подпись. При включенной проверке пользователя через PIN требуются и физический ключ, и подтверждение пользователя. Проверка ключа хоста SSH остается обязательной: именно она защищает подключение от подмены сервера и атак типа «человек посередине».

FIDO2 и U2F не следует считать взаимозаменяемыми. Модуль pam_u2f рассчитан на PAM-аутентификацию с устройством, подключенным к самому серверу, и не запрашивает касание YubiKey, подключенного к удаленному SSH-клиенту. Для удаленного SSH используйте FIDO2 security key OpenSSH, описанный ниже.

Для большинства рабочих сценариев TOTP предлагает оптимальный баланс безопасности и удобства. Аппаратные ключи - выбор для сред, где риск целевой атаки высок.

Что вы найдете в этом руководстве

Это пошаговое руководство содержит готовые решения для DevOps и системных администраторов:

  • Готовые конфигурации sshd_config и PAM для маршрута SSH-ключ + TOTP.
  • Готовую конфигурацию FIDO2 для SSH-ключа, защищенного YubiKey.
  • Скрипт для массового добавления пользователей в TOTP.
  • Алгоритм диагностики с таблицей частых ошибок и их решений.
  • Четкий план аварийного восстановления доступа при потере ключа.
  • Рекомендации по выбору метода для типовых сценариев.

Подготовка сервера и установка необходимых пакетов

Критически важное предупреждение: все изменения выполняйте, имея открытую вторую активную SSH-сессию или прямой доступ к консоли сервера через KVM/IPMI. Ошибка в конфигурации может заблокировать вход.

Что проверить до включения SSH 2FA

  1. Убедитесь, что вход по текущему SSH-ключу работает в отдельной сессии без использования пароля.
  2. Проверьте доступ к KVM/IPMI или физической консоли и подготовьте учетную запись восстановления breakglass.
  3. Сохраните копии /etc/ssh/sshd_config, /etc/pam.d/sshd и /etc/users.oath, если файл уже существует.
  4. Для TOTP проверьте синхронизацию времени на сервере и устройстве пользователя. Расхождение времени приведет к отказу аутентификации.
  5. После каждой правки проверяйте конфигурацию командой sudo sshd -t и тестируйте вход в новой сессии, не закрывая рабочую.

Установите пакеты в зависимости от дистрибутива.

Для Debian/Ubuntu:

sudo apt update
sudo apt install libpam-oath oathtool

Для вывода QR-кода в терминал дополнительно установите qrencode:

sudo apt install qrencode

Для RHEL/CentOS/Rocky Linux 8/9:

sudo dnf install epel-release
sudo dnf install pam_oath oathtool

Для проверки FIDO2-устройств при необходимости установите:

sudo dnf install fido2-tools

Для маршрута YubiKey через удаленный SSH не добавляйте pam-u2f в /etc/pam.d/sshd. На рабочей станции проверьте, что клиент OpenSSH поддерживает security key:

ssh -Q key | grep -- '-sk'

Маршрут 1: настройка двухфакторной аутентификации SSH-ключ + TOTP (Google Authenticator)

Это пошаговая инструкция для настройки TOTP для SSH через PAM-модуль pam_oath. Маршрут требует одновременно SSH-ключ и TOTP-код; парольная аутентификация отключается.

Готовые конфигурационные файлы: sshd_config и PAM

1. Генерация секретного ключа для пользователя. Выполните от имени пользователя, для которого настраивается 2FA:

SECRET=$(openssl rand -hex 20)
printf '%s\n' "$SECRET"

Команда выведет шестнадцатеричный секрет (hexsecret). Сохраните его до регистрации в приложении. Для удобства можно сгенерировать QR-код:

qrencode -t UTF8 "otpauth://totp/user@server?secret=ВАШ_HEXSECRET&issuer=MySSHServer"

2. Сохранение секрета. Добавьте запись в файл /etc/users.oath, где user - точное имя пользователя для входа по SSH:

HOTP/T30/6 user - ВАШ_HEXSECRET

Не используйте строку HOTP/HOTP/T30 $USER - $SECRET: для TOTP-записи pam_oath требуется формат с периодом и количеством цифр HOTP/T30/6. Установите строгие права на файл:

sudo touch /etc/users.oath
sudo chmod 600 /etc/users.oath
sudo chown root:root /etc/users.oath

3. Настройка PAM. Отредактируйте файл /etc/pam.d/sshd. Добавьте правило перед @include common-auth; удалите другие правила pam_oath и pam_u2f для этого SSH-маршрута:

# Двухфакторная аутентификация через TOTP (OATH)
auth [success=done default=die] pam_oath.so usersfile=/etc/users.oath window=5

Управляющее выражение завершает PAM-аутентификацию после успешной проверки TOTP и не передает пользователя в common-auth для повторного запроса пароля. При ошибке TOTP вход прекращается. Параметр window=5 допускает небольшое окно соседних кодов; не увеличивайте его без необходимости.

4. Критическая настройка sshd_config. Отредактируйте /etc/ssh/sshd_config:

# Требуем SSH-ключ и код TOTP
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication yes
UsePAM yes
AuthenticationMethods publickey,keyboard-interactive:pam

Не используйте в этом маршруте AuthenticationMethods password,keyboard-interactive:pam: это ослабляет первый фактор и меняет логику PAM-аутентификации.

5. Проверка конфигурации и тестирование.

sudo sshd -t

Если проверка завершилась без вывода, примените конфигурацию:

# Debian/Ubuntu
sudo systemctl reload ssh

# RHEL/CentOS/Rocky
sudo systemctl reload sshd

Откройте новое окно терминала и попробуйте подключиться. После проверки SSH-ключа система запросит Verification code - код из приложения. Не закрывайте исходную SSH-сессию, пока не подтвердите успешный вход.

Добавление TOTP для нескольких пользователей и централизованное управление

Файл /etc/users.oath поддерживает записи для множества пользователей. Каждая строка - отдельный пользователь. Для массового развертывания используйте скрипт, который создает секрет и не перезаписывает существующую запись пользователя.

Пример простого скрипта:

#!/bin/bash
USER="$1"

case "$USER" in
  ''|*[!a-zA-Z0-9._-]*)
    echo "Укажите корректное имя пользователя"
    exit 1
    ;;
esac

sudo touch /etc/users.oath
sudo chmod 600 /etc/users.oath
sudo chown root:root /etc/users.oath

if sudo awk -v user="$USER" '$2 == user { found=1 } END { exit !found }' /etc/users.oath; then
  echo "Пользователь $USER уже есть в /etc/users.oath"
  exit 1
fi

SECRET=$(openssl rand -hex 20)
printf 'HOTP/T30/6 %s - %s\n' "$USER" "$SECRET" | sudo tee -a /etc/users.oath >/dev/null
echo "Секрет для $USER: $SECRET"
echo "QR-код URI: otpauth://totp/$USER@$(hostname)?secret=$SECRET&issuer=$(hostname)"

Выдавайте секрет пользователю по защищенному каналу и не сохраняйте его в тикетах, shell history или открытых чатах. Для крупных инфраструктур рассмотрите централизованное управление секретами и конфигурациями; локальный файл /etc/users.oath требует контролируемого распространения на каждый сервер. Подробнее о построении масштабируемых систем аутентификации читайте в нашем руководстве по аутентификации и авторизации.

Маршрут 2: настройка SSH-ключа, защищенного YubiKey (FIDO2)

Для удаленного SSH с YubiKey используйте FIDO2 security key OpenSSH, а не модуль pam_u2f. pam_u2f выполняется на сервере и проверяет устройство, физически подключенное к серверу; он не может запросить касание ключа, подключенного к удаленному клиенту.

Этот маршрут использует SSH-ключ, созданный в YubiKey. Опция verify-required требует PIN-код FIDO2 и физическое подтверждение на ключе, поэтому для входа нужны и аппаратный ключ, и подтверждение пользователя.

1. Проверьте поддержку FIDO2. Выполните на рабочей станции:

ssh -Q key | grep -- '-sk'

В выводе должны присутствовать алгоритмы sk-ssh-ed25519@openssh.com или sk-ecdsa-sha2-nistp256@openssh.com. Поддержка должна быть доступна и на SSH-сервере.

2. Создайте SSH-ключ в YubiKey. Подключите YubiKey с включенным FIDO2 и выполните команду на рабочей станции:

ssh-keygen -t ed25519-sk -O verify-required -f ~/.ssh/id_ed25519_sk_yubikey

Команда запросит PIN FIDO2 и касание ключа. Закрытая часть ключа не содержит экспортируемый приватный ключ в обычном виде: операция подписи выполняется на YubiKey.

3. Добавьте открытый ключ на сервер. До включения ограничений скопируйте созданный открытый ключ:

ssh-copy-id -i ~/.ssh/id_ed25519_sk_yubikey.pub user@server

4. Настройте sshd_config. Разместите блок в конце /etc/ssh/sshd_config, заменив user на целевого пользователя. Такой подход не смешивает FIDO2 и TOTP для одной учетной записи:

Match User user
    PubkeyAuthentication yes
    PasswordAuthentication no
    KbdInteractiveAuthentication no
    AuthenticationMethods publickey
    PubkeyAcceptedAlgorithms sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com

Ограничение PubkeyAcceptedAlgorithms исключает вход по обычному SSH-ключу для пользователя из блока Match. Не применяйте этот блок к учетной записи восстановления, если для нее предусмотрен отдельный обычный SSH-ключ.

5. Проверка и тестирование. Проверьте синтаксис и примените конфигурацию, затем подключитесь с явным указанием FIDO2-ключа:

sudo sshd -t
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_sk_yubikey user@server

Клиент запросит PIN и касание ключа. Сообщение Please touch the device относится к локальной рабочей станции, на которой подключен YubiKey.

Отличия в конфигурации SSH для FIDO2 и работа с несколькими ключами

FIDO2 для SSH реализуется ключами OpenSSH с суффиксом -sk. Это отличается от U2F PAM: файл ~/.config/Yubico/u2f_keys и команда pamu2fcfg применяются к pam_u2f, а не к удаленному SSH-маршруту с YubiKey.

Для резервного YubiKey создайте второй FIDO2 SSH-ключ и добавьте его открытый ключ тому же пользователю:

ssh-keygen -t ed25519-sk -O verify-required -f ~/.ssh/id_ed25519_sk_yubikey_backup
ssh-copy-id -i ~/.ssh/id_ed25519_sk_yubikey_backup.pub user@server

Храните основной и резервный ключи раздельно. После регистрации обязательно протестируйте вход с каждым ключом в отдельной сессии. Для управления доступом в корпоративной среде с использованием современных стандартов безопасности ознакомьтесь с полным руководством по миграции на аппаратные ключи FIDO2, где детально разобран процесс интеграции с различными сервисами.

Диагностика проблем и логирование событий аутентификации

Если после настройки вход не работает, не закрывайте действующую сессию и следуйте этому алгоритму диагностики.

1. Включите детальное логирование SSH. В /etc/ssh/sshd_config добавьте:

LogLevel VERBOSE

Перезагрузите службу и проверьте журналы:

  • Debian/Ubuntu: sudo journalctl -u ssh -f или sudo tail -f /var/log/auth.log
  • RHEL/CentOS/Rocky: sudo journalctl -u sshd -f или sudo tail -f /var/log/secure

Ищите строки с Failed password, Invalid verification code, Failed keyboard-interactive и именем PAM-модуля.

2. Проверьте синхронизацию времени - это критично для TOTP. Расхождение более чем на один период TOTP между сервером и телефоном приведет к ошибке.

timedatectl status
sudo systemctl status chronyd
chronyc sources

Если используется systemd-timesyncd, проверяйте его состояние вместо chronyd. Команду chronyc sources запускайте только при установленном chrony.

3. Проверьте PAM и предложенные методы аутентификации. Для TOTP-маршрута используйте интерактивный тест без передачи пустого кода в stdin:

# Установите pamtester, если его нет
sudo apt install pamtester  # или sudo dnf install pamtester
sudo pamtester sshd user authenticate

Программа запросит Verification code. Для диагностики YubiKey добавьте подробный вывод на клиенте:

ssh -vvv -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_sk_yubikey user@server

Почему SSH не запрашивает TOTP или YubiKey

Если TOTP не запрашивается, проверьте наличие KbdInteractiveAuthentication yes, UsePAM yes и AuthenticationMethods publickey,keyboard-interactive:pam. Если не запрашивается YubiKey, убедитесь, что клиент предлагает ключ -sk, а сервер принимает только разрешенные алгоритмы FIDO2 для целевого пользователя.

Таблица типичных ошибок и их решений

Симптом / Сообщение в логах Возможная причина Команда для проверки / Решение
"Invalid verification code" Рассинхронизация времени, неправильный секрет или неверный формат записи TOTP. timedatectl status; проверьте NTP и строку HOTP/T30/6 user - SECRET в /etc/users.oath.
"Failed keyboard-interactive/pam" Отключен KbdInteractiveAuthentication, неверен PAM-стек или TOTP-модуль не может прочитать файл секретов. Проверьте KbdInteractiveAuthentication yes, правило pam_oath и журналы службы SSH.
"Permission denied (publickey,keyboard-interactive)" Не принят SSH-ключ, отсутствует запись пользователя или неверны права на файл секретов. ls -la /etc/users.oath; права должны быть 600, владелец root:root. Проверьте имя пользователя во втором поле записи.
Для YubiKey нет запроса PIN или касания Клиент не использует ключ -sk, FIDO2 не поддерживается или указан другой файл ключа. Запустите ssh -Q key | grep -- '-sk' и подключение с ssh -vvv -i ~/.ssh/id_ed25519_sk_yubikey.
Вход блокируется после настройки Ошибка в PAM-конфигурации или sshd_config, блокирующая все методы. Используйте консольный доступ (IPMI/KVM), выполните sshd -t и проверьте /etc/pam.d/sshd.

Подробные методики аудита и мониторинга безопасности серверов, включая анализ логов аутентификации, собраны в нашем полном руководстве по аудиту и защите серверов.

Аварийное восстановление доступа: что делать, если потерян второй фактор

Внедрение 2FA без плана восстановления - гарантированный инцидент. Подготовьте эти процедуры до применения изменений на боевых серверах.

1. Выделенная учетная запись для восстановления. Создайте отдельного системного пользователя, например breakglass. Разместите блок в конце sshd_config, заменив IP-адрес на доверенную рабочую станцию или административную сеть:

Match User breakglass Address 192.168.1.100
    AuthenticationMethods publickey
    PasswordAuthentication no
    KbdInteractiveAuthentication no

Блок Match должен находиться после общих директив sshd_config. Не добавляйте пользователя breakglass в /etc/users.oath: вне указанного IP-адреса для него останется действовать общий маршрут SSH 2FA, а с доверенного адреса будет разрешен только SSH-ключ.

2. Физический доступ к консоли. Убедитесь, что у вас есть доступ к IPMI, iDRAC, KVM или физической консоли сервера. Это последний рубеж.

3. Скрипт временного отключения 2FA - только для консольного доступа. Подготовьте и заранее протестируйте скрипт, который временно комментирует строку auth [success=done default=die] pam_oath.so в /etc/pam.d/sshd. Храните его на сервере и запускайте исключительно с локальной консоли.

4. Четкий алгоритм действий при инциденте:

  1. Попытайтесь войти через учетную запись восстановления breakglass с доверенной рабочей станции.
  2. Если это невозможно, используйте консольный доступ (IPMI/KVM).
  3. Через консоль временно отключите модуль PAM 2FA, используя подготовленный скрипт или вручную отредактировав /etc/pam.d/sshd.
  4. Войдите в систему, восстановите доступ основному пользователю: сгенерируйте новый TOTP-секрет или зарегистрируйте новый аппаратный ключ.
  5. Верните настройки 2FA в исходное состояние и проверьте вход в новой SSH-сессии.

Готовый пошаговый чек-лист для подобных ситуаций доступен в нашей шпаргалке по восстановлению доступа при потере ключа 2FA.

Итоги и рекомендации по построению отказоустойчивой системы

Двухфакторная аутентификация для SSH необходима для инфраструктуры, выходящей за рамки тестовой среды. TOTP через Google Authenticator обеспечивает практичный баланс защиты и удобства для большинства команд. YubiKey FIDO2 с SSH security key и проверкой PIN подходит для систем с высокими требованиями к защите административного доступа.

Выбор метода для типовых сценариев

Сценарий / Требования Рекомендуемый метод Ключевые аргументы
Хомлаб, небольшая команда, ограниченный бюджет TOTP (Google Authenticator) Бесплатно, просто в развертывании, не требует оборудования.
Банк, критичная инфраструктура, высокий риск целевых атак YubiKey FIDO2 для SSH с verify-required Закрытый ключ остается на устройстве, для входа требуются ключ и PIN.
Крупная инфраструктура, требуется централизованное управление Интеграция TOTP/YubiKey с Vault/FreeRADIUS Централизованное управление, аудит и масштабирование после отдельной проверки интеграции.

Ключевые принципы успешного внедрения:

  • Используйте TOTP только в связке с SSH-ключами, а не с паролями.
  • Для одной учетной записи применяйте один явно выбранный маршрут: SSH-ключ + TOTP или FIDO2 SSH-ключ в YubiKey.
  • План аварийного восстановления обязателен. Протестируйте его до развертывания в production.
  • Для крупных инфраструктур планируйте централизованное управление и избегайте ручного распространения секретов без контроля доступа.
  • Настройте мониторинг событий аутентификации. Неудачные попытки входа с правильным первым фактором могут сигнализировать об атаке.
  • Первым делом протестируйте всю конфигурацию на изолированном тестовом сервере или виртуальной машине.

Приведенные конфигурации требуют проверки на версии OpenSSH и Linux, используемой в вашей среде. Для более глубокого погружения в тему защиты административного доступа изучите наше полное руководство по защите SSH и веб-панелей с помощью 2FA, где рассмотрены дополнительные сценарии и интеграции.

Поделиться:
Сохранить гайд? В закладки браузера