Новинка Виртуальный VDS сервер в Нидерландах от 390р
Выберите продукт

SSH c FIDO2: ключи sk‑ecd25519, U2F/YubiKey и защита от кражи ключей

Классические SSH‑ключи утекают вместе с ноутбуком и из бэкапа. FIDO2/U2F и ключи sk‑* делают приватный ключ неэкспортируемым и требуют подтверждения касанием или ПИН‑кодом. Разбираем включение в OpenSSH, выбор типа ключей, серверную политику, работу через бастион, ротацию и типовые ошибки.
SSH c FIDO2: ключи sk‑ecd25519, U2F/YubiKey и защита от кражи ключей

Аппаратные токены FIDO2/U2F для SSH решают главную проблему классических ключей: кражу приватного ключа с клиента. Вместо файла с секретом, который можно скопировать, приватный ключ хранится внутри токена и никогда его не покидает. Подпись выполняется на устройстве, а доступ к операции подтверждается касанием (user presence) и при необходимости ПИН‑кодом (user verification). В результате риск компрометации от вредоносного ПО, бэкапов и физической кражи ноутбука резко снижается.

Зачем использовать FIDO2 для SSH

Если вы админ или девопс и ежедневно используете SSH, то ваши ключи — это мастер‑ключи к инфраструктуре. Даже с грамотными правами и ограничениями в authorized_keys остаётся целый слой рисков: утечка ключа из бэкапа, скомпрометированный ноутбук, невнимательная передача агент‑сокета через перескоки, атаки через пост‑эксплуатационные инструменты. FIDO2/U2F ликвидирует целый класс угроз, поскольку секрет нельзя скопировать, а каждая подпись требует физического подтверждения.

Важно понимать ограничения модели: FIDO2 не «магическая панацея». Он усиливает аутентификацию, но не заменяет базовую гигиену: контроль доступа на сервере, своевременные обновления, аудит, журналирование и сегментацию.

Как это работает в OpenSSH

Поддержка аппаратных ключей есть в OpenSSH 8.2+ через библиотеку FIDO (обычно libfido2). Используются специальные типы ключей:

  • sk-ecdsa-sha2-nistp256@openssh.com — на базе ECDSA P‑256 (совместимо с U2F и FIDO2), самый универсальный вариант.
  • sk-ssh-ed25519@openssh.com — на базе Ed25519 (требует относительно новых токенов и библиотек).

Файлы «приватного ключа» на диске в случае FIDO — это не сам секрет, а дескриптор (handle), привязанный к определённому токену и приложению ssh:. При подключении OpenSSH запрашивает у токена подпись челенджа. Для завершения операции требуется «прикосновение» к токену; опционально — проверка ПИН‑кода.

Есть два режима выпуска ключей:

  • Нерезидентные (по умолчанию): приватный ключ остаётся внутри токена, а дескриптор хранится в файле на диске. Быстрее и привычнее.
  • Резидентные (опция -O resident): сам дескриптор хранится на токене, что упрощает перенос между машинами и восстановление через ssh-keygen -K. Для доступа обычно требуется ПИН.

Важный плюс FIDO2: даже если злоумышленник получит копию вашего «приватного» файла id_*.sk, он не сможет им воспользоваться без физического токена. Это кардинально меняет оценку рисков по сравнению с классическим ed25519.

Требования и проверка окружения

Проверьте версии и поддержку типов ключей на клиенте:

ssh -V
ssh -Q key | grep sk

Если вывод содержит sk-ecdsa-* и sk-ssh-ed25519, клиент поддерживает FIDO. На сервере проверьте настройки:

sshd -T | grep -i pubkeyacceptedalgorithms
sshd -T | grep -i pubkeyacceptedkeytypes

Если нет sk-ecdsa-sha2-nistp256@openssh.com и sk-ssh-ed25519@openssh.com, добавьте их явно в sshd_config и перезагрузите демон. На Linux убедитесь, что система видит токен как HID‑устройство; обычно достаточно правил udev из пакета libfido2. На рабочих станциях с ограничениями USB доступ к устройствам может требовать добавления пользователя в соответствующую группу.

Генерация FIDO2‑ключа sk‑* для SSH в терминале

Генерация ключей: безопасные пресеты

Вариант 1: универсальный ECDSA‑ключ (совместим с U2F)

Подходит, если вы не уверены в поддержке Ed25519 на всех токенах и серверах.

ssh-keygen -t ecdsa-sk -f ~/.ssh/id_ecdsa_sk -C "admin@work fido2" -O verify-required

Опция -O verify-required заставляет устройство требовать ПИН при каждой подписи. Это повышает стойкость даже при краже токена. Если хотите хранить дескриптор на токене, добавьте -O resident и укажите имя пользователя, которое пригодится при восстановлении:

ssh-keygen -t ecdsa-sk -f ~/.ssh/id_ecdsa_sk_res -C "admin@work fido2 resident" -O verify-required -O resident -O user=admin

Вариант 2: Ed25519‑ключ (современнее и компактнее)

Используйте, если ваши токены и клиенты точно его поддерживают:

ssh-keygen -t ed25519-sk -f ~/.ssh/id_ed25519_sk -C "admin@work ed25519-sk" -O verify-required

Проверить список идентификаторов на токене (для резидентных ключей) можно так:

ssh-keygen -K

Команда импортирует публичные части резидентных ключей в ~/.ssh, не извлекая приватный материал с токена.

Размещение публичного ключа на сервере

Передайте ключ на сервер удобным способом. Самый простой вариант — ssh-copy-id:

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

Либо вручную:

ssh user@server 'mkdir -m 700 -p ~/.ssh'
cat ~/.ssh/id_ed25519_sk.pub | ssh user@server 'cat >> ~/.ssh/authorized_keys'
ssh user@server 'chmod 600 ~/.ssh/authorized_keys'

Для усиления политики в authorized_keys можно добавить ограничения перед типом ключа: from="10.0.0.0/8",restrict. Также имеет смысл запретить лишние возможности: no-agent-forwarding,no-port-forwarding,no-pty — если они не нужны для конкретного пользователя.

from="10.0.0.0/8",restrict,no-agent-forwarding,no-port-forwarding sk-ssh-ed25519@openssh.com AAAAC3NzaC1lZDI1NTE5AAAA.... comment

Если вы не используете резидентные ключи с ПИН по умолчанию, применяйте -O verify-required при генерации. На некоторых версиях OpenSSH требование можно продублировать флагами при выпуске ключа — это надёжнее, чем надеяться на интерпретацию в authorized_keys.

Минимальная настройка сервера

Убедитесь, что сервер принимает FIDO‑ключи и при необходимости отключите пароли:

sudo sed -i 's/^#\?PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^#\?KbdInteractiveAuthentication.*/KbdInteractiveAuthentication no/' /etc/ssh/sshd_config

В новых версиях директива называется PubkeyAcceptedAlgorithms (в старых — PubkeyAcceptedKeyTypes). Добавьте поддержку sk-* явно, если их нет по умолчанию:

echo 'PubkeyAcceptedAlgorithms sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com' | sudo tee -a /etc/ssh/sshd_config

Затем перезагрузите службу:

sudo systemctl reload sshd

Проверьте вход с клиента и держите план отката (консоль, IPMI/ILO, отдельный аккаунт со старым ключом на период миграции).

FastFox VDS
Облачный VDS-сервер
Виртуальные серверы с быстрым запуском и гибкой конфигурацией от 390₽ / мес
Доступные локации
Россия Нидерланды

Конфигурация клиента и работа через бастион

Рекомендую явно закрепить ключи и запретить агент‑форвардинг по умолчанию. В ~/.ssh/config это может выглядеть так:

Host bastion
  HostName bastion.example
  User admin
  IdentitiesOnly yes
  IdentityFile ~/.ssh/id_ed25519_sk
  PubkeyAcceptedAlgorithms sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com
  ForwardAgent no

Host internal-*
  User deploy
  ProxyJump bastion
  IdentitiesOnly yes
  IdentityFile ~/.ssh/id_ed25519_sk
  ForwardAgent no

Вместо передачи агент‑сокета по цепочке используйте ProxyJump. Если форвардинг всё же нужен, включайте его точечно и добавляйте ключ в агент с TTL: ssh-add -t 3600 ~/.ssh/id_ed25519_sk. Нужен изолированный бастион? Поднимите его на VDS. Если выбираете панель для управления сервером, пригодится сравнение панелей для VDS; а для инфраструктурного апгрейда смотрите переезд с шаред‑хостинга на VDS.

Если OpenSSH собран без встроенного FIDO‑провайдера, укажите источник: SecurityKeyProvider internal в клиентском конфиге.

Пример конфигурации OpenSSH с ProxyJump и бастионом

Ротация ключей и резерв

С аппаратными токенами основная проблема — неэкспортируемость. Это хорошо для безопасности, но требует дисциплины при ротации:

  • Держите два токена и выпустите по ключу на каждый. Оба публичных ключа добавьте в authorized_keys.
  • Обновляйте ключи по очереди: добавляйте новые записи параллельно со старыми, затем удаляйте устаревшие.
  • Храните аварийный классический ключ с ограничениями from= и command= офлайн как «спасательный трос».
  • Документируйте процесс замены и список серверов/учёток, чтобы не потерять доступ.

Потеряли токен и резервный не настроен? Придётся восстанавливать доступ через альтернативные каналы администрирования. Планируйте аварийные сценарии заранее.

Типичные ошибки и диагностика

  • Permission denied (publickey): сервер не принимает sk-*. Проверьте sshd -T на предмет поддерживаемых алгоритмов, включите нужные типы, перезагрузите sshd.
  • sign_and_send_pubkey: signing failed: клиент не видит токен или заблокирован доступ к USB/HID. Проверьте подключение устройства, разблокируйте ПИН, обновите libfido2, переподключите токен.
  • Резидентный ключ «пропал» на новой машине: выполните ssh-keygen -K для импорта публичной части из токена в ~/.ssh.
  • PIN/UV ошибки: проверьте, что ключ выпущен с -O verify-required и ПИН задан на токене. Сброс ПИН может удалить резидентные креденшалы.
  • WSL/виртуалки: проброс USB может быть ограничен. Используйте системный OpenSSH на хосте или продумайте прокси вместо прямого доступа к токену из гостя.

Практики безопасности

  • Выпускайте ключи с -O verify-required, чтобы подпись требовала ПИН, а не только касание.
  • Ограничивайте входы по IP через from=, включайте restrict в authorized_keys, разрешайте только необходимые форвардинги.
  • На сервере отключайте пароли (PasswordAuthentication no) и интерактивную аутентификацию (KbdInteractiveAuthentication no), снижайте LoginGraceTime и MaxAuthTries.
  • Минимизируйте время жизни ключа в агенте: ssh-add -t 600, и держите ForwardAgent no по умолчанию.
  • Следите за журналами: journalctl -u sshd и логи аутентификации помогут быстро отловить проблемы.

Что выбрать: ecdsa-sk или ed25519-sk

ecdsa-sk остаётся самым совместимым вариантом благодаря поддержке U2F (CTAP1) и FIDO2 (CTAP2). ed25519-sk современнее и немного компактнее, но требует новых токенов и библиотек. Компромисс для разнородной инфраструктуры: выпускать оба типа и регистрировать оба публичных ключа на критичных серверах.

Переход с классических ключей без простоя

  1. Выпустите новый FIDO‑ключ на токене 1, добавьте его на все нужные сервера.
  2. Подтвердите вход на каждого из них.
  3. Выпустите ключ на токене 2 и также добавьте в authorized_keys.
  4. Только после этого удаляйте старые классические ключи.

Если использовали автоматизацию и деплой через SSH, заранее проверьте совместимость инструментов: большинство клиентов прозрачно работают с sk-*, но первые подключения часто требуют ручного подтверждения касанием токена, что влияет на безоператорные сценарии. Для non-interactive задач используйте отдельного пользователя со строго ограниченными правами и классическим ключом, либо токен в безопасном HSM‑стенде, если подтверждение возможно.

Итоги

Переход на FIDO2/U2F‑ключи для SSH — один из самых эффективных апгрейдов безопасности для админов и девопсов. Аппаратный ключ делает невозможным тихую кражу приватного материала, а требование касания и ПИН ставит физический барьер для удалённой эксплуатации. На практике миграция сводится к обновлению OpenSSH, выпуску sk-* ключей, добавлению их на сервера и корректировке политик клиента/сервера. Дополните это разумной ротацией и резервом — и ваша поверхность атаки заметно сузится.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину

Ошибка mount: wrong fs type, bad option, bad superblock в Debian/Ubuntu может означать и простую опечатку в имени раздела, и пробл ...
Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление

Если XFS-раздел внезапно стал доступен только для чтения, а сервер ушёл в emergency mode, главное — не спешить. Разберём безопасны ...
Debian/Ubuntu: как исправить Failed to fetch при apt update OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить Failed to fetch при apt update

Ошибка Failed to fetch при apt update в Debian и Ubuntu обычно связана не с самим APT, а с DNS, сетью, зеркалом, прокси, временем ...