Как настроить SSH с FIDO2 и YubiKey на macOS
Как использовать аппаратный ключ для аутентификации по SSH? Для этого существует стандарт FIDO2, который позволяет использовать внешнее устройство. В этой статье как расскажу о том, как настроить вход с использованием аппаратного ключа YubiKey на macOS.
Весь процесс проделывал с:
- YubiKey 5C NFC;
- macOS 14.5 Sonoma.
Однако во многом инструкция подойдёт и для других систем, специфичные шаги я далее отмечу.
Подготовка
Для начала нужно убедиться, что установленный OpenSSH версии не ниже 8.3:
ssh -V
Если ниже, то обновитесь доступным способом, например, через brew
.
macOS
Однако даже если версия SSH у вас корректная, скорее всего при выполнении дальнейших шагов вы столкнётесь с ошибкой:
Key enrollment failed: unknown or unsupported key type
Связано это с тем, что встроенный OpenSSH в macOS по умолчанию не поддерживает sk
ключи. Но это легко исправить!
Есть GitHub Issue, в котором прекрасный человек под ником MichaelRoosz собрал все необходимые библиотеки в виде brew
пакета, и на этапе подготовке давайте сразу установим этот пакет:
brew install michaelroosz/ssh/libsk-libfido2-install
После установки остаётся только прописать переменную окружения SSH_SK_PROVIDER
и SSH_ASKPASS
в вашем ~/.zshrc
или ~/.bash_profile
:
export SSH_SK_PROVIDER=/usr/local/lib/libsk-libfido2.dylib
export SSH_ASKPASS=/opt/homebrew/bin/ssh-askpass
И мы готовы к самому главному: генерации ключей.
Генерация
Поскольку перед нами стоит задача сгенерировать FIDO2 ключ, дальнейший путь разделяется на две дороги: нужно решить генерировать резидентский или нерезидентский ключ. Чем они отличаются?
Нерезидентский FIDO2 ключ
Когда конечная сторона (приложение или веб-сайт) хочет аутентифицировать вас, оно отправляет обязательный Credential ID. Это некая зашифрованная информация, которую расшифровать может ли ваш аппаратный ключ.
Сам процесс происходит за счёт использования уникального мастер-ключа. Обратите внимание, что это именно мастер-ключ: он один для всего аппаратного ключа, а вторую часть "формулы" – Credential ID, обязано предоставить приложение. Но при этом ни один из ваших аккаунтов не хранится в YubiKey, поэтому место нерезидентские ключи не расходуют, и их количество неограниченно.
Резидентский FIDO2 ключ
Резидентские или обнаруживаемые ключи, напротив, занимают слот на вашем аппаратном ключе. Их количество может разниться в зависимости от модели: на некоторых 8 слотов, на YubiKey 5 от 25 до 32, а на некоторых слотов нет совсем, а значит резидентский ключ сгенерировать невозможно.
В данном случае приложению не нужно предоставлять Credential ID: вся необходимая информация формируется на аппаратном ключе в момент добавления аккаунта. Если аккаунтов несколько, то браузер предложит выбрать конкретный. И далее уже сам ключ "расскажет" конечной стороне Credential ID и необходимую информацию для аутентификации.
Также сама по себе работа с резидентскими FIDO2 ключами отличаются из-за разных версий стандарта CTAP. На данный момент существуют версии 2.0, 2.1PRE и 2.1. И лишь 2.1PRE и 2.1 дают возможность вам удалить (освободить слот) резидентский ключ с устройства без сброса всего хранилища. Было бы неприятно добавить 25 ключей, и ради удаления одного сбрасывать все, м?
Так что выбрать, что безопаснее?
Обе опции являются безопасными. Да, в случае резидентского ключа вообще все чувствительные данные хранятся на аппаратном ключе, а у нерезидентского Credential ID есть у приложения. Однако нельзя сказать, что последнее плохо: Credential ID шифруется с AES128, а это довольно надёжный стандарт.
Однако если у вас очень много аккаунтов (больше или сравнительно с количеством слотов), то с обывательской точки зрения лучше выбрать опцию с неограниченными не-резидентскими ключами.
Команды
Для генерации не-резидентского ключа запустите:
ssh-keygen -t ed25519-sk
А для генерации резидентского:
ssh-keygen -t ed25519-sk -O resident -O application=ssh:my-hostname -O verify-required
Вместо ssh:my-hostname
можете ввести любой текст, и далее он будет отображаться в Yubico Authenticator (или другом менеджере вашего аппаратного ключа в списке FIDO2):
И, кстати, да, генерация происходит привычным ssh-keygen
. Если вы не пропустили шаг с подготовкой для macOS, то сейчас утилита должна попросить ввести пин-код и коснуться ключа. А по итогу появится id_ed25519_sk
SSH ключ.
Публичную часть необходимо выгрузить на сервер:
ssh-copy-id -i ~/.ssh/id_ed25519_sk user@remote
После чего вы можете убедиться, что всё работает:
ssh -i ~/.ssh/id_ed25519_sk -o 'IdentitiesOnly yes' user@remote
Победа 🙂
Ссылки
Обязательно смотрите сам ролик про мою попытку безопасно работать с SSH: Как использовать SSH ПРАВИЛЬНО | YubiKey, FIDO2, PIV и правила использования SSH ключей.
И огромное количество информации я узнал благодаря статьям других авторов:
- Discoverable vs non-discoverable credentials в документации YubiKey
- How passkeys work в документации YubiKey
- ssh authentication via Yubikeys
- How Hype Will Turn Your Security Key Into Junk про разницу резидентских и не-резидентских ключей
- Тот самый Github Issue с решением для macOS и кучей полезной информации