Когда я стал счастливым обладателем устройства Yubikey 5 nfc и узнал, что при помощи него можно авторизовываться по ssh, я столкнулся с множеством статей про настройку подобной связки на unix-системах… И с полнейшим отсутствием адекватного материала про Windows.
Разобравшись в теме, собрав информацию из многих источников и проверив работоспособность связки на личном опыте, я пишу эту статью для тех, кто решит повторить мой путь.
О чём эта статья
Я предполагаю, что, читая мой гайд, вы уже создали gpg-ключи в нужной вам конфигурации и записали их на Yubikey. Информации о том, как это сделать, достаточно много, и инструкции не отличаются для Linux и Windows.
Также, я предполагаю, что в вашей системе уже установлен GnuPG последней версии (на момент написания статьи — версия 2.40), и вы умеете базово с ним обращаться.
Почитать про создание ключей и запись их на Yubikey можно здесь.
Скачать GnuPg для Windows можно здесь (во всяком случае, я использовал именно gpg4win).
Желаемый результат
Выполнив все шаги, описанные ниже, вы получите:
- Возможность использовать Yubikey вместе с OpenSSH в Windows;
- Возможность использовать Yubikey вместе с ssh внутри Wsl.
Подготовка
Перед тем, как приступить к настройке, убедитесь, что:
- У вас установлена Windows 10 версии 1803 или новее;
- У вас установлен gpg4win или другая версия GnuPg;
- Команда
gpg --card-status
корректно отображает информацию о вашем Yubikey и ключах, записанных на нём; - Соответствующие публичные ключи хранятся в gpg на компьютере и отображаются по команде
gpg --list-keys
.
Настройка GnuPg
Первым делом нам необходимо изменить конфигурацию GnuPg таким образом, чтобы GnuPg использовал gpg-agent, а также включить поддержку OpenSsh в самом агенте.
Для начала выясним, где GnuPg будет искать конфигурационные файлы. Для этого введём в командной строке следующее:gpgconf --list-dirs homedir
В ответ мы получим путь, по которому и хранятся все данные и настройки gpg в вашей системе.
Далее необходимо открыть папку по указанному пути и создать в папке два файла: gpg.conf и gpg-agent.conf.
Затем, в файле gpg.conf мы должны написать следующее:use-agent
Таким образом мы укажем gpg необходимость использовать gpg-agent.
А в файле gpg-agent.conf мы пишем это:
enable-putty-support
enable-ssh-support
Если у вас в системе установлен Windows OpenSsh версии 9.0 или новее, вы можете добавить третьей строкой следующее:enable-win32-openssh-support
Зачем это нужно, я объясню чуть позже.
Теперь, изменив конфигурацию gpg, мы можем запустить gpg-agent такой командой:gpg-connect-agent /bye
А остановить запущенный агент при помощи командыgpg-connect-agent killagent /bye
Убедившись, что агент запускается без ошибок, мы должны создать ещё один файл в директории gnupg.
Файл должен называться sshcontrol, а поместить в него нужно keygrip вашего ключа для аутентификации (то есть ключа с capability a).
Чтобы получить keygrip 'ы всех ваших ключей, используйте командуgpg --list-keys --with-keygrip
Вывод команды будет выглядеть примерно так:
pub rsa4096 2022-07-18 [SC]
58DE66838D1CFAD22A5283F3AEFB45ACA247412F
Keygrip = B53F9C92114AB637817A4EE28242654636D718A2
uid [ultimate] Kirill Belousov <belousov.k.m@yandex.ru>
uid [ultimate] Kirill Belousov <bkm.grotschool@yandex.ru>
uid [ultimate] Kirill Belousov <funnytastymeat@gmail.com>
sub rsa4096 2022-07-18 [E]
Keygrip = B68CC0A9905D5737547DDC8AEA532259F2679107
sub rsa4096 2022-07-18 [A]
Keygrip = B21B4285DC89262A7EF194E68C73AE76C793D591
Обратите внимание на две последние строки. Буква [a] в квадратных скобках означает, что сабключ предназначен именно для аутентификации, а строчка keygrip=...
— и есть искомый keygrip.
Необходимо скопировать всё, что написано после keygrip=
и вставить в файл sshcontrol.
Обратите внимание, что до и после вставленной строки не должно быть пустых строк, а на самой строке не должно быть пробелов в начале и в конце.
Сохранив файл sshcontrol, перезапустите gpg-agent при помощи описанных выше команд.
Ещё одна утилита
После запуска gpg-agent в системе появится сокет, при помощи которого ssh может подключаться к gpg и запрашивать ssh-ключи… На linux.
Ssh в Windows с такими сокетами работать не умеет. Именно поэтому нам понадобится внешняя утилита под названием wsl-ssh-pageant.
Скачать утилиту можно здесь.
Для загрузки доступны две версии программы: версия для командной строки (запускается с окном командной строки, которое будет висеть открытым, пока программа работает), и gui-версия, которая запускается в фоне, не "светится" окном командной строки и может быть остановлена только через диспетчер задач или при помощи иконки в системном трее.
Для использования с планировщиком задач (для автоматического запуска) больше подойдёт первый вариант, а для ручного запуска по нажатию на ярлык — вторая. Но какую версию использовать — исключительно ваш выбор, по функционалу они идентичны.
Скачав утилиту и сохранив её в удобном месте, запустите её со следующими параметрами:--wsl C:\path\to\wsl\socket.sock --winssh pipe-name-for-windows-ssh --systray --force
Параметр --wsl <path>
позволяет указать путь, по которому будет создан файл сокета для wsl. Если вам не нужна поддержка Wsl, можете опустить этот параметр.--winssh <pipe-name>
позволяет указать имя для именованой трубки, при помощи которой OpenSsh в Windows будет пытаться подключиться к агенту.--systray
включает отображение иконки в системном трее,
а --force
перезапускает утилиту и пересоздаёт все сущности, если утилита уже запущена (полезно для быстрого перезапуска по нажатию на ярлык).
Я обычно запускаю gui-версию программы при помощи ярлыка со следующим содержимым:C:\wsl-ssh-pageant\wsl-ssh-pageant-amd64-gui.exe --wsl C:\wsl-ssh-pageant\ssh-agent.sock --winssh ssh-pageant --systray --force
Запустив утилиту и убедившись, что она стартовала без ошибок (по иконке в трее или по выводу командной строки), перейдём к последнему шагу.
Изменение переменной окружения SSH_AUTH_SOCK
Последним штрихом, после которого всё должно заработать, станет установка переменной окружения, при помощи которой Windows OpenSsh будет искать подключение к gpg через настроенную выше утилиту.
Чтобы добавить необходимую переменную окружения, в командной строке выполняем командуsetx SSH_AUTH_SOCK \\.\pipe\<name>
Вместо <name>
подставьте то, что вы указали в параметре --winssh
при запуске wsl-ssh-pageant.
Настройка Wsl
Если вам необходима авторизация по ssh при помощи Yubikey в Wsl, вы должны создать переменную окружения SSH_AUTH_SOCK в Wsl, а в качестве её значения указать путь к файлу сокета, создаваемому wsl-ssh-pageant.
В моём случае команда выглядит следующим образом:export SSH_AUTH_SOCK=/mnt/c/wsl-ssh-pageant/ssh-agent.sock
Примечание: несмотря на то, что во всех инструкциях описывается именно такой алгоритм действий для Wsl, в моей системе это не сработало. Возможно, необходимы дополнительные шаги, о которых я не знаю.
Для тех, у кого Windows OpenSsh версии 9.0
При настройке gpg я упоминал об опции, доступной "не для всех".
Если у вас gpg версии 2.40 или новее и Windows Openssh версии 9.0 или новее, вы можете обойтись без wsl-ssh-pageant и использовать gpg-agent и ssh напрямую.
Если вы при заполнении файла gpg-agent.conf вписали опцию enable-win32-openssh-support
, вернитесь к шагу с настройкой переменной окружения и в качестве значения для переменной установите \\.\pipe\openssh-ssh-agent
.
Внимание! Несмотря на то, что версии всех компонентов у меня подходят по условиям, на моей системе этот способ не сработал, и мне пришлось вернуться к использованию wsl-ssh-pageant.
Если вы столкнётесь с такой же проблемой и найдёте её решение, пожалуйста, расскажите о своём опыте в комментариях. Не забудьте указать версии всех используемых компонентов и версию вашей системы.
Проверка
Чтобы убедиться, что все компоненты видят друг друга, и настройка выполнена правильно, выполните две командыgpg --export-ssh-key <id_публичного_ключа>
Эта команда выведет в консоль публичный ssh-ключ, соответствующий аутентификационному сабключу.
Затем, убедившись, что gpg-agent и wsl-ssh-pageant запущены, запустите командуssh-add -L
Эта команда выведет все ssh-ключи, которые Windows OpenSsh смог найти в вашей системе.
Если среди выводимых ключей отображается такой же ключ, который отобразила предыдущая команда gpg --export-ssh-key
, значит вы настроили всё правильно и теперь можете авторизоваться по ssh при помощи вашего Yubikey.
Заключение
Я надеюсь, что статья оказалась для вас полезной, и у вас всё получилось.
Если у вас есть какие-либо дополнения, рекомендации и советы, не стесняйтесь оставлять их в комментариях. Думаю, другие читатели будут вам благодарны.
Комментарии (5)
Johan_Palych
22.01.2023 14:09+1И с полнейшим отсутствием адекватного материала про Windows
Использовал данный материал в 2020г.
SSH on Windows with private key on Yubikey(Posted on March 24, 2020 by Sid) - WSL, minGW/GIT Bash and Yubikey 5.
Автор статьи писал:
"...Я также связался с Yubico, чтобы узнать, есть ли у них какая-либо внутренняя документация, поскольку внешней документации по этому поводу было мало.
Удивительно, но они только что отправили несвязанные ссылки на сторонние посты в блогах..."На сегодня, похоже качество материалов изменилось к лучшему:
Using Your YubiKey with OpenPGP
YubiKey-Guide-wslcyrmax Автор
22.01.2023 23:42Большое спасибо за последнюю ссылку :)
Предпоследняя есть у меня в статье, в самом начале, а вот последняя - действительно хороший материал, который интересно прочитать.
Кстати, если бы я изначально нашёл именно его, я бы не совершил глупейшую ошибку, когда мастер-ключ является ещё и ключом для подписания [S].
Сохранил ссылку на будущее. Когда протухнут уже готовые ключи, воспользуюсь именно этой инструкцией для создания новых.
Ещё раз спасибо
l0ser140
Данное решение работает с WSL2?
При прокидывании сокета от keeagent в WSL2 мне приходилось использовать socat + npiperelay, т.к. при монтировании внутрь WSL2 сокеты не работали.
cyrmax Автор
Кажется, что, несмотря на то, что разработчик wsl-ssh-pageant утверждает обратное, с wsl2 оно не работает.
У меня получилось прокинуть в wsl2 только при помощи socat + npiperelay. Так что, видимо, это единственный рабочий вариант
FFxSquall
вот это завелось с wsl2 (поддержка прекращена), но там есть баги в этом issue можно взять исправленную версию. В целом всё работало на момент когда тестировал