YubiKey для SSH и 2FA: аппаратная аутентификация — АйТи Фреш

YubiKey для SSH и 2FA: аппаратная аутентификация

Зачем нужен аппаратный токен для SSH

SSH-ключи — фундамент доступа к Linux-серверам, но у этого подхода есть одна неприятная дыра: приватный ключ лежит обычным файлом на диске. Скомпрометировали рабочую станцию — через малварь, кражу ноутбука или просто «коллега заглянул не туда» — и всё, злоумышленник забирает ключ и получает доступ ко всем серверам разом. Passphrase немного усложняет жизнь атакующему, но не спасает: офлайн-перебор никто не отменял.

Аппаратный токен YubiKey закрывает эту проблему принципиально иначе. Приватный ключ генерируется внутри устройства и физически не может его покинуть. Можете хоть полностью потерять контроль над компьютером — без самого токена ключ не извлечь. Плюс YubiKey требует касания при каждой операции подписи. Это важно: даже если токен воткнут в USB и компьютер захвачен удалённо, без вашего пальца ничего не произойдёт.

Для SSH YubiKey поддерживает три протокола. FIDO2/WebAuthn (ключи ed25519-sk, ecdsa-sk) — встроен прямо в OpenSSH 8.2+, никакого дополнительного ПО не нужно. PIV (Personal Identity Verification) — эмуляция смарт-карты, работает через PKCS#11, совместим со старыми версиями OpenSSH. OpenPGP — подключается через gpg-agent как SSH-агент. Мы в большинстве проектов берём FIDO2: меньше всего движущихся частей, нативная поддержка, современный стандарт.

Подготовка YubiKey и установка утилит

Начнём с установки утилит управления YubiKey на рабочую станцию:

# Ubuntu/Debian
apt install -y yubikey-manager libfido2-dev libfido2-1 fido2-tools

# Fedora/RHEL
dnf install -y yubikey-manager libfido2 fido2-tools

# macOS
brew install ykman libfido2

Убедитесь, что система видит токен:

# Информация о подключённом YubiKey
ykman info
# Device type: YubiKey 5 NFC
# Serial number: 12345678
# Firmware version: 5.4.3
# Enabled USB interfaces: OTP, FIDO, CCID

# Список FIDO credentials
fido2-token -L
# /dev/hidraw3: vendor=0x1050, product=0x0407 (Yubico YubiKey)

Установка PIN и настройка FIDO2

Перед работой с FIDO2 нужно задать PIN-код — без него резидентные ключи не создать:

# Установить PIN для FIDO2 (если ещё не задан)
ykman fido access change-pin
# Введите новый PIN (минимум 6 символов)

# Проверить статус FIDO2
ykman fido info
# PIN is set: True
# Min PIN length: 6
# Remaining retries: 8

# ВАЖНО: после 8 неверных попыток PIN FIDO2 блокируется
# Для сброса (удалит все FIDO2 credentials!):
# ykman fido reset

Если планируете использовать PIV-приложение (смарт-карта), задайте PIN и для него:

# PIN по умолчанию для PIV: 123456
# PUK по умолчанию: 12345678
ykman piv access change-pin -P 123456 -n ВашНовыйPIN
ykman piv access change-puk -p 12345678 -n ВашНовыйPUK

SSH-аутентификация через FIDO2 (ed25519-sk)

Начиная с OpenSSH 8.2 появились типы ключей ed25519-sk и ecdsa-sk — они аппаратно привязаны к FIDO2-токену. Честно говоря, это самый чистый и незамороченный способ подружить YubiKey с SSH.

Что нужно: OpenSSH >= 8.2 на клиенте и сервере, YubiKey с поддержкой FIDO2 — это серия 5 или Security Key. Генерируем ключ:

# Создание FIDO2 SSH-ключа (ed25519-sk)
ssh-keygen -t ed25519-sk -C "yubikey-admin@company"
# Коснитесь YubiKey, когда мигает индикатор
# Generating public/private ed25519-sk key pair.
# You may need to touch your authenticator...

# Файлы:
# ~/.ssh/id_ed25519_sk      — «ручка» (handle), НЕ приватный ключ
# ~/.ssh/id_ed25519_sk.pub  — публичный ключ

# С обязательным касанием при каждом использовании
ssh-keygen -t ed25519-sk -O verify-required -C "yubikey-admin"

Файл id_ed25519_sk — не приватный ключ в привычном смысле, а credential handle. Без физического YubiKey этот файл абсолютно бесполезен для атакующего. Публичный ключ копируем на сервер стандартным способом:

ssh-copy-id -i ~/.ssh/id_ed25519_sk.pub user@server.example.com

Резидентные ключи (discoverable credentials)

Обычный FIDO2-ключ требует, чтобы файл-handle лежал на том компьютере, с которого вы подключаетесь. Резидентный ключ хранится целиком внутри YubiKey — воткнул токен в любую машину и работаешь, никаких файлов переносить не надо:

# Создание резидентного ключа
ssh-keygen -t ed25519-sk -O resident -O verify-required \
  -O application=ssh:production-servers \
  -C "yubikey-resident-admin"

# Извлечение ключей из YubiKey на новый компьютер
ssh-keygen -K
# Введите PIN, коснитесь токена
# Создаст id_ed25519_sk_rk и id_ed25519_sk_rk.pub

Резидентный ключ занимает один слот FIDO2. YubiKey 5 держит до 25 таких слотов — на практике этого хватает с запасом даже для крупных команд. Опция application пригодится, когда нужно различать ключи для разных проектов при извлечении с токена.

Настройка ssh_config для FIDO2

В клиентском конфиге прописываем ключ и параметры подключения:

# ~/.ssh/config
Host production-*
  IdentityFile ~/.ssh/id_ed25519_sk
  IdentitiesOnly yes
  # Если используете ssh-agent
  AddKeysToAgent yes

Host staging-*
  IdentityFile ~/.ssh/id_ed25519_sk
  # Fallback на обычный ключ
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes

На сервере проверьте /etc/ssh/sshd_config — там должны быть перечислены допустимые типы ключей:

PubkeyAcceptedKeyTypes ssh-ed25519,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com

# Опционально: запретить обычные ключи, оставить только аппаратные
# PubkeyAcceptedKeyTypes sk-ssh-ed25519@openssh.com

SSH через PIV (смарт-карта PKCS#11)

PIV — альтернатива для тех, у кого на серверах живут старые версии OpenSSH. YubiKey эмулирует смарт-карту по стандарту PIV (NIST SP 800-73), ключ сидит в одном из четырёх слотов устройства. Главный плюс: работает через PKCS#11 с любой версией OpenSSH, где FIDO2 ещё не завезли.

# Генерация RSA-2048 ключа в PIV слоте 9a (Authentication)
ykman piv keys generate -a RSA2048 9a pubkey.pem

# Создание самоподписанного сертификата
ykman piv certificates generate \
  -s "CN=admin-yubikey" -d 3650 9a pubkey.pem

# Экспорт публичного SSH-ключа из PIV
ssh-keygen -D /usr/lib/x86_64-linux-gnu/libykcs11.so
# Выведет публичный ключ в формате OpenSSH

Для аутентификации через PIV подключаем библиотеку PKCS#11:

# Подключение к серверу через PIV
ssh -I /usr/lib/x86_64-linux-gnu/libykcs11.so user@server

# Или в ssh_config:
Host piv-servers
  PKCS11Provider /usr/lib/x86_64-linux-gnu/libykcs11.so

PIV через ssh-agent

Чтобы не указывать библиотеку руками каждый раз, добавляем PIV-ключ в ssh-agent:

# Добавить PKCS#11 провайдер в агент
ssh-add -s /usr/lib/x86_64-linux-gnu/libykcs11.so
# Введите PIV PIN

# Проверить загруженные ключи
ssh-add -L
# Должен показать ключ из YubiKey

# Удалить при необходимости
ssh-add -e /usr/lib/x86_64-linux-gnu/libykcs11.so

На macOS путь к библиотеке: /usr/local/lib/libykcs11.dylib. Если используете OpenSC вместо ykcs11 — путь будет /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so.

Двухфакторная аутентификация SSH через PAM

YubiKey можно использовать не только вместо SSH-ключей, но и как второй фактор поверх существующей аутентификации. Схема простая: пользователь вводит пароль, потом касается токена. Реализуется через PAM-модуль pam_u2f — мы такую схему внедряли в нескольких компаниях, где отказываться от паролей сразу не хотели.

# Установка PAM-модуля
apt install -y libpam-u2f

# Регистрация YubiKey для пользователя
mkdir -p ~/.config/Yubico
pamu2fcfg > ~/.config/Yubico/u2f_keys
# Коснитесь мигающего YubiKey

# Добавление второго токена (резервного)
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys

Настраиваем PAM для SSH:

# /etc/pam.d/sshd — добавить после @include common-auth
auth required pam_u2f.so cue [cue_prompt=Коснитесь YubiKey...]

# Для централизованного хранения (все пользователи в одном файле)
# auth required pam_u2f.so authfile=/etc/yubikey/u2f_keys cue

В /etc/ssh/sshd_config добавляем:

# Включить Challenge-Response для PAM
ChallengeResponseAuthentication yes
UsePAM yes

# Требовать и публичный ключ, и 2FA
AuthenticationMethods publickey,keyboard-interactive

После systemctl restart sshd процесс входа выглядит так: предъявляем SSH-ключ → вводим пароль → касаемся YubiKey. Три рубежа вместо одного.

Централизованное управление ключами

Когда администраторов десятки, таскать привязки YubiKey по каждому серверу руками — то ещё удовольствие. Удобнее хранить их централизованно:

# /etc/yubikey/u2f_keys — формат:
# username:key_handle,public_key,es256,+presence
# Каждый пользователь — отдельная строка

admin:aBcDeFgH...,AQIDBA...,es256,+presence
devops:xYzAbCdE...,BQIDBA...,es256,+presence

# PAM конфиг с централизованным файлом
# /etc/pam.d/sshd
auth required pam_u2f.so authfile=/etc/yubikey/u2f_keys cue nouserok

# nouserok — пользователи без записи в файле проходят без 2FA
# Убрать nouserok для обязательного 2FA всем

В окружениях с LDAP или Active Directory атрибуты YubiKey можно хранить прямо в директории и синхронизировать файл привязок через cron или отдельный скрипт.

YubiKey OTP и Yubico Cloud

Есть ещё один режим, о котором часто забывают, — OTP (One-Time Password). При касании токен генерирует 44-символьную строку, которую можно валидировать через Yubico Cloud или поднять локальный сервер валидации. Пригождается там, где FIDO2 просто не взлетит: старые системы, веб-панели, legacy-приложения.

# Установка клиента Yubico PAM для OTP
apt install -y libpam-yubico

# Получение API-ключей на https://upgrade.yubico.com/getapikey/
# Запишите client_id и secret_key

# /etc/pam.d/sshd
auth required pam_yubico.so id=CLIENT_ID key=SECRET_KEY \
  authfile=/etc/yubikey/otp_mappings mode=client

# /etc/yubikey/otp_mappings
# username:yubikey_id (первые 12 символов OTP)
admin:ccccccdvvbhk
devops:ccccccefjlkn

Локальный сервер валидации

Если гонять трафик до внешних сервисов Yubico не вариант — поднимаем собственный сервер валидации OTP внутри периметра:

# Установка ykval и ykksm
apt install -y yubikey-val yubikey-ksm

# Или использование Docker-образа
docker run -d --name ykval \
  -p 8080:80 \
  -e YKVAL_DB_HOST=db.local \
  yubico/yubikey-val

# Настройка PAM для локальной валидации
auth required pam_yubico.so id=1 \
  urllist=http://ykval.local:8080/wsapi/2.0/verify \
  authfile=/etc/yubikey/otp_mappings mode=client

Локальный сервер валидации также обязателен для изолированных сетей, где доступ к api.yubico.com попросту закрыт.

Резервные стратегии и восстановление доступа

Главная головная боль аппаратной аутентификации — потеря или поломка токена. Видели ситуацию, когда единственный YubiKey администратора утонул в стакане кофе в пятницу вечером. Без заранее продуманной стратегии резервирования можно разом потерять доступ ко всей инфраструктуре.

  • Два токена на сотрудника — основной всегда при себе, резервный лежит в сейфе. Оба регистрируются сразу на всех серверах, иначе смысл резерва теряется
  • Break-glass аккаунт — отдельный root с паролем в запечатанном конверте или в менеджере паролей, для совсем аварийных ситуаций. Вход по паролю разрешён строго с консоли, SSH — закрыт
  • Аварийный SSH-ключ — обычный ed25519, зашифрованный сильным паролем и запертый на USB-накопителе в том же сейфе
# Скрипт регистрации нового/резервного YubiKey для FIDO2 SSH
#!/bin/bash
set -e
SERVERS="server1 server2 server3 db-master db-slave"

echo "Вставьте новый YubiKey и нажмите Enter"
read

# Генерация нового ключа
ssh-keygen -t ed25519-sk -O resident -O verify-required \
  -f ~/.ssh/id_yubikey_backup -C "backup-yubikey-$(date +%Y%m%d)"

# Деплой на все серверы
for SRV in $SERVERS; do
  echo "Деплой на $SRV..."
  ssh-copy-id -i ~/.ssh/id_yubikey_backup.pub admin@$SRV
  echo "OK: $SRV"
done

echo "Резервный YubiKey зарегистрирован на $(echo $SERVERS | wc -w) серверах"

Резервный токен для PAM U2F регистрируется командой pamu2fcfg -n >> ~/.config/Yubico/u2f_keys. Флаг -n здесь принципиален — он дописывает запись к уже существующей строке пользователя, а не затирает её.

Часто задаваемые вопросы

Для FIDO2 SSH через ed25519-sk берите YubiKey 5-й серии — NFC, USB-C, Nano или Bio, без разницы. Есть ещё бюджетный YubiKey Security Key, он тоже умеет FIDO2/U2F, но только это. YubiKey 4 FIDO2 не поддерживает вообще — только PIV/PKCS#11, имейте в виду. Резидентные ключи работают исключительно на серии 5 с прошивкой 5.2.3 и выше. Для SSH через PIV подойдёт всё начиная с четвёрки.

Потеряли токен — первым делом удаляйте его публичный ключ из ~/.ssh/authorized_keys на каждом сервере. Каждый ключ имеет уникальный comment, так что найти нужную запись не составит труда. PAM U2F используете? Тогда чистите и запись в u2f_keys. Теперь про хорошую новость: потерянный FIDO2-токен без PIN бесполезен — после 8 неудачных попыток он блокируется. Но расслабляться не стоит. Считайте ключ скомпрометированным и меняйте везде.

PuTTY с версии 0.78 формально поддерживает ecdsa-sk и ed25519-sk через Pageant, но честно — мы предпочитаем OpenSSH прямо из Windows 10/11. Начиная с версии 8.2 он полноценно работает с FIDO2, команды те же, что на Linux: ssh-keygen -t ed25519-sk. Для PIV на Windows используйте библиотеку libykcs11.dll из YubiKey Smart Card Minidriver.

Да, один YubiKey тянет несколько задач одновременно. FIDO2 закрывает SSH и WebAuthn для сайтов, PIV — SSH и Windows Smart Card Logon, OTP — Yubico OTP и OATH-TOTP. Приложения работают параллельно и друг другу не мешают. На практике: до 25 FIDO2 резидентных ключей, 32 слота OATH-TOTP и 4 PIV-сертификата на одном токене — этого хватает с запасом для большинства задач.

Несколько вещей, которые мы делаем сразу после получения токена. PIN для FIDO2 — обязательно, через ykman fido access change-pin, иначе создать новые credentials не получится. При генерации ключей включайте verify-required — PIN будет запрашиваться при каждом использовании. Для PIV меняйте PIN с дефолтного 123456 и PUK с 12345678 в первую очередь, это азбука. Touch policy для PIV переводим в «always»: ykman piv keys generate -a RSA2048 --touch-policy always 9a pub.pem. И последнее — отключите ненужные USB-интерфейсы: ykman config usb --disable OTP.

Нужна помощь с настройкой?

Если хотите разобраться с внедрением без лишней головной боли — специалисты АйТи Фреш помогут настроить всё под вашу инфраструктуру. Больше 15 лет в теме, обслуживание от 15 000 ₽/мес.

📞 Связаться с нами
#YubiKey SSH#аппаратная аутентификация#FIDO2 SSH#2FA сервер Linux#YubiKey PAM#SSH ключ аппаратный токен#PIV SSH#yubikey-manager
Комментарии 0

Оставить комментарий

загрузка...

Подпишитесь на рассылку ITfresh

Каждую неделю мы выпускаем практические гайды для руководителей IT и системных администраторов. Это не просто теория! Здесь вы найдёте всё: безопасность, 1С, миграции, резервные копии и проверенные лайфхаки из наших реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.