0x01. Yubikey + ssh/git (Linux)
TableOfContents
0x00. Інтро
З деякого часу у мене в арсеналі обов’язкових пристроїв є ключі-юбіки ( https://www.yubico.com/products/yubikey-5-overview/ ). Дуже багато сервісів як-то Google, Github (web GUI) тощо підтримують їх з коробки. Крім того є можливість створити на них сертифікат, за допомогою якого авторизуватись по ssh. Але тут вже треба вийняти бубен і трохи потанцювати, бо ні Linux, ні Windows не вміють того з коробки.
Так як деякі налаштування ключа можуть зроблені як під Windows, так і під Linux незалежно від того, в якій ОС потім ключ буде використовуватись, то в даній статті будуть розглянуті саме тільки особливості Yubikey під Linux.
0x01. Yubikey
Спершу треба налаштувати сам юбік - змінити дефолтні пін-коди (на випадок, якщо юбік потрапить не в ті руки), потім створити сертифікат, експортувати публічний ключ.
Як це робить у Windows можна прочитати тут: 0x00. Yubikey + ssh/git (Windows)
Yubikey manager (Linux, GUI)
По суті все те ж саме, що і під windows, тільки спершу встановити Yubikey Manager (заодно і інші пакети, що знадобляться потім):
sudo apt install -y ykcs11 yubico-piv-tool yubikey-manager scdaemon yubikey-personalization opensc libnss3-tools
Щоб викликати GUI для Yubikey Manager виконайте команду:
ykman-gui
PS: якщо Yubikey manager видасть помилку “Failed connecting to the YubiKey. Make sure the application has the required permissions.” (трапляється інколи на останніх релізах Ubuntu), то виконати команди:
sudo apt install pcscd
sudo systemctl enable pcscd
sudo systemctl start pcscd
Якщо не допоможе - то спробувати рецепти з
Якщо є бажання налаштувати все із консолі (наприклад, якщо у вас Linux не має графічної оболонки), то тоді шлях самурая:
ykman
YubiKey Manager CLI (ykman) User Manual
Подивитись підключені Yubikey пристрої:
ykman list
видасть щось на кшталт:
└─$ ykman list
YubiKey 5C NFC (5.4.3) [OTP+FIDO+CCID] Serial: 12345678
тобто модель ключа, версію прошивки, доступні API, серійний номер.
Розширена інформація:
└─$ ykman info
Device type: YubiKey 5C NFC
Serial number: 12345678
Firmware version: 5.4.3
Form factor: Keychain (USB-C)
Enabled USB interfaces: OTP, FIDO, CCID
NFC transport is enabled
Applications USB NFC
Yubico OTP Enabled Enabled
FIDO U2F Enabled Enabled
FIDO2 Enabled Enabled
OATH Enabled Enabled
PIV Enabled Enabled
OpenPGP Enabled Enabled
YubiHSM Auth Enabled Enabled
Повне скинення налаштувань/сертифікатів PIV (наприклад забули pin/puk чи переналаштовуєте з нуля):
ykman piv reset
Зміна puk:
ykman piv access change-puk
Зміна pin:
ykman piv access change-pin
Зміна management key (заодно вмикаємо захист його піном - тобто буде питати пін для підтвердження при кожному використанні management key):
ykman piv keys change-management-key --generate --protect
(і збережіть сгенерований ключ у секретному місці, він знадобиться потім)
Більше тут
Certificates
Аналогічно тому, як і під Windows.
Ну або знову шлях самурая (я тут знову генерую його й слоті 9c, а не 9a - щоб пін питало при кожному доступі по ssh, параноя вона така), сертифікат на 10 років.
- Спершу генеруємо приватний ключ.
- Створюємо самопідписаний сертифікат.
- Генеруємо публічний ключ для створеного сертифікату.
Всі ці дії можна робити як із використанням yubico-piv-tool (ми вже його встановили на самому початку), так і за допомогою консольного Yubikey Manager (ykman). Але в обох випадках треба буде management key, який ми створили і зберегли в секретному місці раніше. Якщо ні - то тоді тільки ykman. Бо yubico-piv-tool у випадку, коли не вказуємо management key, використовує дефолтний 0102…, який ми завбачливо змінили на свій. ykman же просто спитає пін код (пам’ятаємо, що ми захистили management key pin кодом? Так от саме для цього, щоб не виписувати і не зберігати його ще десь %) )
1. Створення приватного ключа
Наприклад, для сертифікату у слоті 9c (вже пояснював, чому надаю перевагу саме 9c, а не 9a), алгоритм еліптичних кривих 256 біт:
ykman piv keys generate --algorithm ECCP256 9c public92.pem
Enter PIN: ******
Приватний збережено на Yubikey пристрої, публічний записано у public92.pem (по замовчанню формат PEM).
Можна задати і інші опції:
└─$ ykman piv keys generate --help
Usage: ykman piv keys generate [OPTIONS] SLOT PUBLIC-KEY
Generate an asymmetric key pair.
The private key is generated on the YubiKey, and written to one of the slots.
SLOT PIV slot of the private key
PUBLIC-KEY file containing the generated public key (use '-' to use stdout)
Options:
-m, --management-key TEXT the management key
-P, --pin TEXT PIN code
-a, --algorithm [RSA1024|RSA2048|RSA3072|RSA4096|ECCP256|ECCP384|ED25519|X25519]
algorithm to use in key generation [default: RSA2048]
-F, --format [PEM|DER] encoding format [default: PEM]
--pin-policy [DEFAULT|NEVER|ONCE|ALWAYS|MATCH-ONCE|MATCH-ALWAYS]
PIN policy for slot
--touch-policy [DEFAULT|NEVER|ALWAYS|CACHED]
touch policy for slot
-h, --help show this message and exit
2. Створення сертифікату за допомогою створеного ключа
Створюємо сертифікат у слоті 9с на три роки, сабжект “x-ssh” (префікс “CN=” обов’язково!), public92.pem - це публічний ключ, що зберегли перед цим:
└─$ ykman piv certificates generate --valid-days=1095 --subject "CN=x-ssh" 9c public92.pem
Enter PIN: *******
Перевіряємо:
└─$ ykman piv info
PIV version: 5.4.3
PIN tries remaining: 3/3
PUK tries remaining: 3/3
Management key algorithm: AES256
Management key is stored on the YubiKey, protected by PIN.
CHUID: 3019d4e739da739ced39ce739d836858210842108421c84210c3eb3410ecff3c92f11bf17734ab8b6dc0e8f47d350832303330303130313e00fe00
CCC: No data available
Slot 9C (SIGNATURE):
Private key type: ECCP256
Public key type: ECCP256
Subject DN: CN=x-ssh
Issuer DN: CN=x-ssh
Serial: 161728660454137589467847298317485943567371955241
Fingerprint: 7d63fc02b49f58d7426519244440adec2cd557d84f9163b5f1fbb71f7b116953
Not before: 2024-12-15T07:38:34
Not after: 2027-12-15T07:38:34
0x02. OpenSSH
Для openssh спершу отримаємо публічний ключ у форматі саме openssh.
Але спершу нам треба знати повну адресу бібліотеки pkcs11.so .
В залежності від дистрибутива і версії пакетів вона може бути в різних місцях і мати різну назву, наприклад
/usr/lib64/pkcs11/opensc-pkcs11.so
/usr/lib/x86_64-linux-gnu/libykcs11.so
/usr/lib64/libykcs11.so
але є спільна частина - kcs11.so, тому якщо ні одного із вище вказаних у вас нема, можна спробувати знайти:
└─$ locate *kcs11.so
...
/usr/lib/jvm/java-17-openjdk-amd64/lib/libj2pkcs11.so
/usr/lib/x86_64-linux-gnu/libykcs11.so
/usr/lib/x86_64-linux-gnu/cryptsetup/libcryptsetup-token-systemd-pkcs11.so
...
в моєму випадку це
/usr/lib/x86_64-linux-gnu/libykcs11.so
Тому виконуємо
└─$ ssh-keygen -D /usr/lib/x86_64-linux-gnu/libykcs11.so -e
...
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIn6Oc8Bnq+kKEAYCwUILth7Yeo+EqbxP3zXH0UNIT9EIINxhmyNriSF1uu8d3hDIXQvAp4CQr8elNCML85tX54= Public key for Digital Signature
...
Для слота 9a ключ має в кінці Public key for PIV Authentication , для 9c - Public key for Digital Signature.
Це і є ключ, який ми потім використовуємо на віддалених системах/github для надання доступу за допомогою Yubikey.
Наприклад якщо ssh - то будь-яким варіантом встановлюємо його у ~/.ssh/authorized_keys на віддаленій системі і далі вже з клієнтської машини викликаємо:
ssh -I /usr/lib/x86_64-linux-gnu/libykcs11.so user@host
Опція -I /usr/lib/x86_64-linux-gnu/libykcs11.so означає, що якщо є під’єднаний Yubikey і на ньому в слотах 9a/9c є відповідний приватний ключ, то спитає пін-код - і якщо він правильний - далі з’єднання буде відбуватись вже із використанням даного приватного ключа. У іншому випадку піде звичним для ssh шляхом.
Щоб кожен раз не вказувати цю опцію, можна задати її як дефолтну:
sudo echo "PKCS11Provider /usr/lib/x86_64-linux-gnu/libykcs11.so" | sudo tee -a /etc/ssh/ssh_config
У цьому випадку користуйтесь ssh як звичайно. Це також дуже зручно, якщо ви користуєтесь якимось іншими програмами, що використовують ssh - git, scp тощо.
Refs
- https://developers.yubico.com/yubico-piv-tool/
- https://developers.yubico.com/PIV/Guides/SSH_with_PIV_and_PKCS11.html
- https://docs.yubico.com/software/yubikey/tools/ykman/Install_ykman.html#linux-installation
- https://support.yubico.com/hc/en-us/articles/360016648939-Troubleshooting-Failed-connecting-to-the-YubiKey-Make-sure-the-application-has-the-required-permissions-in-YubiKey-Manager
- https://debugging.works/blog/yubikey-cheatsheet/
- https://support.yubico.com/hc/en-us/articles/360016614940-YubiKey-Manager-CLI-ykman-User-Manual
- https://docs.yubico.com/software/yubikey/tools/ykman/PIV_Commands.html
- https://developers.yubico.com/PIV/Guides/PIV_Walk-Through.html
- https://developers.yubico.com/PIV/Guides/SSH_with_PIV_and_PKCS11.html
- https://developers.yubico.com/PIV/Guides/Device_setup.html