Как настроить SSH с PIV и YubiKey на macOS
PIV – это стандарт двухфакторной аутентификации с использованием смарт-карт. И есть более специфический стандарт, который чаще всего используется в этом направлении: PKCS #11.
PKCS #11 – это уже стандарт программной имплементации интерфейса доступа к смарт-картам, токенам и другим криптографическим устройствам.
По итогу получится такая схема, когда публичный и приватный ключ будет храниться прямо на YubiKey, никогда его не покинет, а значит невозможно будет аутентифицироваться без физически подключённого YubiKey. Двигаемся дальше.
YubiKey предоставляет интерфейс PKCS #11, а SSH умеет подгружать специфическую динамическую библиотеку, которая и будет отвечать за взаимодействие по интерфейсу PKCS #11 c YubiKey. И нам останется лишь сгенерировать ключи, добавить их на сервер, и наслаждаться секьюрным решением!
Весь процесс проделывал с:
- YubiKey 5C NFC;
- macOS 14.5 Sonoma.
Подготовка
Нам понадобится взаимодействовать с YubiKey для дальнейшей генерации ключей. Для этого понадобится установить две утилиты: Yubico PIV Tool и Yubikey Manager.
macOS
На macOS для этого можно использовать brew
:
brew install yubico-piv-tool yubico-yubikey-manager
И важно скопировать динамическую библиотеку, которая понадобится нашему SSH позже:
sudo cp /opt/homebrew/Cellar/yubico-piv-tool/2.3.1/lib/libykcs11.2.3.1.dylib /usr/local/lib/libykcs11.dylib
Обратите внимание, что в моём случае версия yubico-piv-tool
была 2.3.1
. Замените номер версии на тот, который у вас.
Первоначальная настройка YubiKey
В этой части мы установим PIN и PUK коды, и сгенерируем "management key" для безопасного взаимодействия с YubiKey.
Если всё это вы уже настроили, то можете перейти к следующему шагу.
- Мы будем работать с командой
ykman
. Она поставляется вместе сYubikey Manager
, поэтому для удобства можем прописать alias:
alias ykman="/Applications/YubiKey\ Manager.app/Contents/MacOS/ykman"
- Далее установим PIN и PUK код
- PIN код – тот, который вы будете вводить при использовании YubiKey
- PUK код – тот, который нужно будет ввести, если вы забудете PIN и израсходует попытки ввода (да, они ограничены)
ykman piv access change-pin
ykman piv access change-puk
- Последнее что остаётся – сгенерировать management key, который мы будем использовать далее при заполнении PIV слотов. Строго говоря его генерация необязательна (вроде), но без неё у меня далее ничего не работало. Поэтому запускаем команду
ykman piv access change-management-key --generate --protect
Генерация ключей
Приватный ключ
Для подписи дальнейших шагов нужно сгенерировать ключ следующей командой:
yubico-piv-tool --key -s 9a -AECCP384 -a generate --pin-policy=once --touch-policy=always -o public.pem
Эта команда сгенерирует приватный ключ прямо на YubiKey, и сохранит на вашем компьютере публичный ключ в файл public.pem
.
Вы также можете поправить некоторые опции:
--pin-policy
– политика ввода PIN кода. Возможные значения:never
– никогда не вводить пин-код, достаточно подключённого YubiKey;always
– вводить пароль при каждом использовании;once
– вводить пароль единожды для каждой сессии. Сессия – период между подключением и отключением YubiKey.
--touch-policy
– политика требования касания сенсорной кнопки YubiKey. Возможные значения:never
– никогда не требоваться касания:always
– всегда требовать касание;cached
– не требовать касание в течение 15 секунд после последнего (удобно, когда нужно залогиниться в несколько мест сразу).
Подробнее про опции можете почитать в официальной документации.
PIV сертификат
Стандарт PIV требует использование сертификата. Поскольку выше мы предпочли сгенерировать приватный ключ прямо на YubiKey, то нам достаточно запустить одну команду:
yubico-piv-tool --key -a verify-pin -a selfsign-certificate -s 9a --subject "/CN=SSH key/" --valid-days=3650 -i public.pem -o cert.pem
И сертификат окажется в слоте 9a
на YubiKey.
Публичный SSH ключ
И остаётся последнее: получить публичный SSH ключ, чтобы затем добавить его на сервере:
ssh-keygen -D /usr/local/lib/libykcs11.dylib -e
Команда выведет публичный ключ, который нужно добавить в ~/.ssh/authorized_keys
на вашем сервере.
И после этого можно пытаться залогиниться:
Здесь вы можете столкнуться с проблемой, что SSH не сможет "спросить" у вас пин-код. Если такое случится, то вам нужно установить скрипт этого самого окна, чтобы SSH в него "перенаправил" запрос пин-кода. Самое простое: установить brew install michaelroosz/ssh/libsk-libfido2-install
(и пусть вас не смущает FIDO2, в комплекте автор оставил нужный нам скрипт), и затем прописать переменные окружения в вашем ~/.zshrc
или ~/.bash_profile
:
export SSH_ASKPASS=/opt/homebrew/bin/ssh-askpass
export DISPLAY=":0"
Желательно это делать в самом верху файла, если у вас установлен автоматический ssh-agent
. Тогда он будет использовать эту конфигурацию.
Пара советов
Рекомендую прописать PKCS11Provider в вашем ~/.ssh/config
, чтобы не нужно было писать эту опцию каждый раз руками:
Host *
PKCS11Provider /usr/local/lib/libykcs11.dylib
Вы также можете настроить переиспользование установленного SSH соединения между несколькими сессиями, чтобы не касаться каждый раз аппаратного ключа:
Host bitbucket.org
ControlMaster auto
ControlPath ~/.ssh/S.%r@%h:%p
ControlPersist 10m
Ссылки
Обязательно смотрите сам ролик про мою попытку безопасно работать с SSH: Как использовать SSH ПРАВИЛЬНО | YubiKey, FIDO2, PIV и правила использования SSH ключей.
Статьи, видео и инструкции не появилось бы без следующих материалов:
- PIV Walk-Through в официальной документации
- Вновь официальная документация по
ykman
- Великолепная инструкция от человека с ником
m3nu
, которая легла в основу этой статьи