Настройка Yubikey + WSL2 + SSH

TL:DR Настраиваем подключение по ssh к серверам с yubikey, без паролей, физических приватных ключей и смс.Заодно покажу как с помощью хака прокидывать физические USB устройства в WSL машину,авось захочется тебе что-то другое прокинуть и поковырять.
ЧИТАТЬ ПЕРВЫМ В ТЕЛЕГРАМ ЧИТАТЬ ПЕРВЫМ В MAX
Ставим YubiKey Manager, оно есть под все ОС, я буду ставить на винду и прокидывать ключ в WSL2. Под линукс это все работает из коробки, а вот с виндой + wsl 2— есть проблемы.
Вставляем Yubikey в USB, открываем Manager и проверяем, если всё ок, то ключ появляется. Дополнительно можно проверить в консоли командой: ykman info в ответ получен:
Device type: YubiKey 5 NFC
Serial number: 12345678
Firmware version: 5.7.4
Form factor: Keychain (USB-A)
Enabled USB interfaces: OTP, FIDO, CCID
NFC transport is enabled.
Предварительно в ключ нужно зашить PIN, делается это через тот же Yubikey Manager в разделе Application → FIDO2 → FIDO2 PIN. Забиваем PIN.
PIN можно установить из консоли винды, командой:
ykman fido access change-pin. Но если есть морда, то быстрее и приятнее сделать это через морду.
Едем дальше. Прокинуть физический USB в WSL2 не так просто, но есть решение. Называется оно usbipd-win и позволяет прокинуть любую USB железяку внутрь пресловутого WSL2. Скачиваем установщик в разделе Releases и устанавливаем. Рутина.
Дальше еще интереснее. Открываем консоль PowerShell и запускаем:
usbipd list
И видим кучу устройств. Среди всего нужно найти Yubikey, у меня это:
3-2 1050:0407 USB-устройство ввода, Устройство чтения смарт-карт Micros...
Как я это понял? Да банально выткнул ключ из USB, прогнал команду, воткнул и снова прогнал, сравнил что появилось. А появилось именно это устройство, нам нужен его ID, у меня это 1050:0407.
usbipd bind --busid 3-2
usbipd attach --wsl --busid 3-2
Если вылезет ошибка, в большинстве случаев это виндовый фаервол. У меня установлена морда TinyWall, я его на время отключаю. Позже уже добавлю нужные правила.
Нахуя мне фаервол? Хочу держать под контролем софт, который у меня установлен, ну не нравится мне когда что-то утекает без моего ведома, тем более после «гугл приключений».
Так, теперь идем в WSL машину и выполняем sudo lsusb, если всё ок то увидим:
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 1050:0407 Yubico.com Yubikey 4/5
Кайф! Что-то прокинулось. Но что? Терпение!
У меня в WSL живет ubuntu 24, доставляем необходимые пакеты:
sudo apt install -y yubikey-manager fido2-tools
Проверяем:
sudo ykman info
Device type: YubiKey 5 NFC
Serial number: 12345678
Firmware version: 5.7.4
Form factor: Keychain (USB-A)
Enabled USB interfaces: OTP, FIDO, CCID
NFC transport is enabled.
sudo fido2-token -L
/dev/hidraw1: vendor=0x1050, product=0x0407 (Yubico YubiKey)
Да сучка! Поздравляю, мы успешно прокинули USB железяку в WSL2. Нюансы! Кудаж без них. Сейчас ключ виден только руту, а нам надо обычному юзеру. Хакаем систему!
В WSL машине создаем файл /etc/udev/rules.d/99-yubikey.rules:
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0407", MODE="0660", GROUP="plugdev", TAG+="uaccess"
Не забываем вставить ID вендора и продукта, мы их выше уже получили и знаем.
Применяем:
sudo usermod -aG plugdev $USER
sudo udevadm control --reload-rules
sudo udevadm trigger
Всё, для чистоты эксперимента можешь открыть новую консоль и убедиться что рядовой юзер теперь в деле.
Теперь можем генерить ключ и подключаться к серверам.
Создаём SSH ключ:
ssh-keygen -t ed25519-sk -O resident -C "shuba@bashdays"
Оно запросит у тебя PIN который мы впендюрили в самом начале. Жмем несколько раз Enter и радуемся жизни. Новый приватный ключ создан, записан на Yubikey, публичная же часть ключа упала в ~/.ssh/id_ed25519_sk.pub.
Да, рядом будем лежать файл
id_ed25519_sk, но это ничего не меняет, это не приватный ключ, приватный ключ НЕ хранится на диске, он сразу записывается в Yubikey. А то что ты видишь у себя на диске, это дескриптор (handle). Этот файл содержит идентификатор Yubikey ключа, параметры и ссылку на resident key. Приватный ключ физически находится внутри YubiKey и не может быть извлечён.
А дальше по классике. Закидываем публичную часть ключа на нужный сервер и пробуем подключиться:
ssh root@bashdays.ru
Confirm user presence for key ED25519-SK
Опа, прикасаемся своим обрубком к Yubikey и успешно подключаемся к серверу. Также можно сгенерить ключ, который не требует прикосновений, либо вообще сгенерить одноразовые пины, но это уже оверхед безопасность.
Про SSH ключи я подробно расписывал в серии постов по тегу #linuxfactory нажми на тег, получишь список всех этих постов. Настоятельно рекомендую ознакомиться, такому в школах не учат. По крайней мере не рассказывают нюансы.
Фиксим баги.
После того как ты достанешь ключ из USB и затем воткнешь обратно. Всё к хуям сломается. Вот такая особенность винды и WSL2. Поэтому делаем финт ушами. Пишем powershell скрипт, который будет это фиксить.
Создаем файл YubiKeyAttachToWSL.ps1
$yubiKeyBusId = (usbipd list | Select-String "1050:0407" |
ForEach-Object { $_.Line.Split()[0] })
if ($yubiKeyBusId) {
usbipd attach --wsl --busid $yubiKeyBusId
Write-Host "YubiKey attached…"
} else {
Write-Host "YubiKey not found."
}
Не забываем изменить ID вендора и продукта. Закидываем скрипт в виндовый планировщик с параметрами:
Триггер:
- At log on (при входе в систему)
- On Event (событие USB)
- Log: System, Source:
WudfUsbccidDrv, Event ID:104
Действие:
- Запуск
powershell.exeс аргументами-ExecutionPolicy Bypass -File "C:\YubiKeyAttachToWSL.ps1"
Теперь этот скрипт будет запускать при входе в систему ну и если ты будешь тыркать Yubikey туда-сюда в USB портах. Автоматизация ёпта!
Всё! Поставленная задача успешно решена. Что важно, тут не только потыкали Yubikey + SSH, но и научились прокидывать USB устройства в WSL2.
Всё остальное поищешь сам, информации полно. Я показал тебе лишь неочевидные штуки, которые могут загнать в тупик и свести с ума.
Изучай!