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

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

SSH-ключи — основа аутентификации на Linux-серверах, но у них есть критическая уязвимость: приватный ключ хранится файлом на диске. Если рабочая станция администратора скомпрометирована (малварь, кража ноутбука, доступ коллеги), злоумышленник получает приватный ключ и полный доступ ко всем серверам. Пароль на ключ (passphrase) замедляет, но не останавливает атаку — его можно подобрать офлайн.

Аппаратный токен YubiKey решает эту проблему: приватный ключ генерируется внутри устройства и никогда не покидает его. Даже при полной компрометации компьютера злоумышленник не сможет извлечь ключ — потребуется физическое владение токеном. Кроме того, YubiKey требует касания (touch) при каждой операции подписи, что защищает от удалённого использования даже если токен подключён к компьютеру.

YubiKey поддерживает несколько протоколов для SSH: FIDO2/WebAuthn (ed25519-sk, ecdsa-sk) — встроен в OpenSSH 8.2+, не требует дополнительного ПО; PIV (Personal Identity Verification) — эмулирует смарт-карту, совместим с PKCS#11; 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

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

# 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-подход — альтернатива FIDO2, совместимая со старыми версиями OpenSSH. YubiKey эмулирует смарт-карту стандарта PIV (NIST SP 800-73), ключ хранится в одном из четырёх слотов. Преимущество — работает с любой версией OpenSSH через PKCS#11 библиотеку.

# Генерация 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

Помимо замены SSH-ключей, YubiKey может выступать вторым фактором (2FA) поверх существующей аутентификации. Пользователь вводит пароль и затем касается YubiKey. Это реализуется через 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

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

# Установка клиента 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

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

Для корпоративной среды, где обращения к внешним сервисам нежелательны, разверните собственный сервер валидации 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

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

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

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

  • Два токена на сотрудника — основной (носится с собой) и резервный (хранится в сейфе). Оба регистрируются для всех серверов
  • 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 подходят все модели начиная с YubiKey 4.

Немедленно удалите публичный ключ потерянного токена из ~/.ssh/authorized_keys на всех серверах (каждый ключ имеет уникальный comment для идентификации). Если использовался PAM U2F — удалите соответствующую запись из u2f_keys. Для FIDO2-ключей важно: потерянный токен без знания PIN бесполезен (PIN блокируется после 8 попыток). Тем не менее, считайте ключ скомпрометированным и замените его везде.

PuTTY начиная с версии 0.78 (2022) поддерживает ecdsa-sk и ed25519-sk ключи через встроенный SSH-агент Pageant. Однако удобнее использовать OpenSSH из Windows 10/11 — он полностью поддерживает FIDO2 с версии 8.2. Команды идентичны 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 «always» для PIV: 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

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

загрузка...