Przejdź do głównej zawartości

YubiKey na Fedora Linux: PAM, sudo, SSH, GPG i TOTP

· 15 min aby przeczytać
Przemysław Majdak
Full-Stack Developer, Automation Engineer & Web Security Specialist

YubiKey to fizyczny klucz bezpieczeństwa, który na Fedorze może zastąpić albo uzupełnić hasło przy sudo i logowaniu, trzymać klucze SSH i GPG oraz generować kody TOTP. Ten przewodnik prowadzi przez wszystkie te zastosowania — z naciskiem na to, jak nie zablokować sobie dostępu do systemu i jak nie nadpisać tego, co już jest na kluczu.

Aktualizacja 2026-10-03

Wpis przejrzany na Fedorze 44 z YubiKey 5 NFC (firmware 5.7.1). Poprawione błędy pierwotnej wersji: authselect enable-feature zamiast authselect select (który zdejmuje pozostałe cechy profilu), jednostki w sudoers (minuty, nie sekundy), sudoedit zamiast visudo dla plików PAM, ykman list zamiast nieistniejącego ykman --list, limity pamięci według firmware, brak yubioath-desktop w repozytorium Fedory. Na końcu każdej sekcji zaznaczam, co zostało uruchomione, a co opisuję na podstawie dokumentacji.

Wprowadzenie do YubiKey​

YubiKey 5 łączy kilka niezależnych aplikacji, każdą z osobnym PIN-em i osobną pamięcią:

  • FIDO U2F / FIDO2 — uwierzytelnianie w przeglądarce (passkeys), w PAM i w SSH
  • OTP — jednorazowe hasła Yubico OTP, challenge-response, statyczne hasło
  • PIV — karta inteligentna: certyfikaty X.509 i klucze prywatne
  • OpenPGP — klucze GPG do podpisu, szyfrowania i uwierzytelniania
  • OATH — kody TOTP/HOTP (zamiennik aplikacji typu Google Authenticator)

Ograniczenia pamięci YubiKey​

Limity zależą od firmware. Według dokumentacji Yubico (firmware 5.7, porównanie wersji):

AplikacjaFirmware 5.7.4+Starsze firmware
FIDO2 — poświadczenia rezydentne (passkeys)10025
FIDO U2F i nierezydentne FIDO2bez limitu (nic nie jest zapisywane na kluczu)bez limitu
OATH (TOTP/HOTP)6432
OTP2 sloty2 sloty
PIV24 certyfikaty (4 główne sloty + 20 „retired”)24
OpenPGP3 klucze: podpis, szyfrowanie, uwierzytelnianie3

Wersję firmware i stan pamięci sprawdzisz poleceniami ykman info i ykman fido info. Na moim kluczu ykman fido info pokazuje Credential storage remaining: 97, choć to firmware 5.7.1, a Yubico podaje zwiększoną pamięć FIDO2 i OATH dopiero od 5.7.4. Mój odczyt sugeruje, że wcześniejsze 5.7.x też ją mają — ale to obserwacja na jednym kluczu, nie deklaracja producenta.

Zanim cokolwiek zapiszesz na kluczu

Jeśli używasz klucza na co dzień (konta Google, menedżer haseł, inne komputery), najpierw sprawdź, co już na nim jest: ykman otp info (zajęte sloty OTP), ykman piv info (zajęte sloty PIV), ykman openpgp info. Polecenia z sekcji PIV, OTP challenge-response i OpenPGP nadpisują zawartość slotu bez pytania o to, co tam było. Rejestracja U2F w PAM i nierezydentny klucz SSH niczego na kluczu nie zapisują — tych możesz używać bez obaw.

Instalacja podstawowych pakietów​

Dla wszystkich funkcji​

Wszystkie pakiety poniżej są w repozytorium Fedory 44:

# ykman — konfiguracja klucza z wiersza poleceń
sudo dnf install yubikey-manager

# FIDO U2F/FIDO2 w PAM (zalecane)
sudo dnf install pam-u2f pamu2fcfg

# Yubico OTP i challenge-response w PAM (starsze metody)
sudo dnf install pam_yubico

# Karty inteligentne (PIV, OpenPGP)
sudo dnf install pcsc-lite opensc

yubikey-manager-qt i yubikey-personalization-gui też są w repozytorium, ale to starsze narzędzia graficzne. Yubico rozwija dziś Yubico Authenticator — dostępny na Fedorze jako Flatpak z Flathub. Pakietu yubioath-desktop, który polecała pierwotna wersja tego wpisu, w repozytorium Fedory 44 już nie ma.

Uruchamianie usług​

# Usługa kart inteligentnych — potrzebna dla PIV i OpenPGP
sudo systemctl enable --now pcscd

Sprawdzenie, czy klucz jest widoczny:

ykman list
# YubiKey 5 NFC (5.7.1) [OTP+FIDO+CCID] Serial: ...
ykman info

Uruchomione na Fedorze 44: instalacja pakietów, ykman list, ykman info, ykman fido info, ykman otp info, ykman piv info, ykman openpgp info.

Konfiguracja uwierzytelniania systemowego (PAM)​

Każda zmiana w PAM może odciąć Cię od sudo i od logowania. Zanim zaczniesz:

  1. Otwórz drugi terminal z powłoką roota (sudo -i) i nie zamykaj go, dopóki nie sprawdzisz, że sudo i logowanie działają w nowej sesji.
  2. Przy authselect używaj opcji -b — kopia zapasowa trafia do /var/lib/authselect/backups/ i można do niej wrócić poleceniem authselect backup-restore.

Metoda 1: FIDO U2F/FIDO2 (zalecana dla nowych kluczy)​

Krok 1: Rejestracja klucza

mkdir -p ~/.config/Yubico

# Rejestracja pierwszego klucza (dotknij klucza, gdy zacznie migać)
pamu2fcfg > ~/.config/Yubico/u2f_keys

Zapasowy klucz musi trafić do tej samej linii. Według dokumentacji pam-u2f plik użytkownika ma mieć dokładnie jedną linię: użytkownik:klucz1:klucz2:.... Opcja -n wypisuje sam fragment :klucz2 bez nazwy użytkownika:

# Włóż zapasowy klucz zamiast pierwszego
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys

wc -l ~/.config/Yubico/u2f_keys # oczekiwane: 0 — cały plik to jedna linia bez znaku końca

To działa, bo pamu2fcfg nie dopisuje znaku nowej linii na końcu — sprawdziłem na pam-u2f 1.4.0: ostatni bajt wyniku to znak klucza, a fragment z -n zaczyna się od :. Nie otwieraj pliku w edytorze, który dopisuje nową linię przy zapisie, między pierwszym a drugim poleceniem — wtedy zapasowy klucz trafi do drugiej linii i nie zadziała.

Dwie pułapki:

  • Origin. pamu2fcfg domyślnie przypisuje rejestrację do pam://$HOSTNAME. Zmiana nazwy hosta albo skopiowanie pliku na inny komputer sprawi, że klucz przestanie pasować. Na kilku maszynach podaj wspólny origin (-o pam://moja-nazwa -i pam://moja-nazwa) i ten sam parametr origin= w PAM.
  • SELinux. Zostań przy domyślnej ścieżce ~/.config/Yubico/u2f_keys. Plik w innym miejscu wymaga poprawnego kontekstu (chcon -R -t auth_home_t ...), a w połączeniu z nouserok błąd dostępu kończył się udanym logowaniem bez klucza — to CVE-2020-24612, opisane w dokumentacji pam-u2f.

Krok 2: Włączenie w PAM przez authselect

Fedora zarządza PAM narzędziem authselect — ręczne zmiany w /etc/pam.d/system-auth zostaną nadpisane. Profil local (domyślny na Fedorze 44) ma dwie cechy dla pam-u2f:

CechaCo robiLinia w system-auth
with-pam-u2fklucz zamiast hasła; bez klucza system pyta o hasłoauth sufficient pam_u2f.so cue
with-pam-u2f-2faklucz i hasłoauth required pam_u2f.so cue nouserok

cue wyświetla komunikat z prośbą o dotknięcie klucza. nouserok w trybie 2FA przepuszcza użytkowników, którzy nie mają pliku u2f_keys — dzięki temu root i inne konta nie zostają zablokowane. Cecha without-pam-u2f-nouserok to wyłącza; dokumentacja profilu ostrzega, że wtedy bez skonfigurowanego klucza nie zaloguje się nikt, łącznie z rootem.

authselect current # profil i włączone cechy

# klucz zamiast hasła:
sudo authselect enable-feature with-pam-u2f -b
# albo klucz + hasło:
# sudo authselect enable-feature with-pam-u2f-2fa -b
enable-feature, nie select

Pierwotna wersja tego wpisu (i Fedora Quick Docs) podaje authselect select local with-pam-u2f. select ustawia profil z cechami wymienionymi w poleceniu. Sprawdziłem to przez authselect test (podgląd bez zapisu) na Fedorze 44 z włączonym czytnikiem linii papilarnych: konfiguracja z select local with-pam-u2f nie zawiera pam_fprintd, czyli logowanie odciskiem palca by zniknęło. enable-feature dopisuje cechę do bieżącej konfiguracji.

Ponieważ /etc/pam.d/sudo, login i pliki ekranów logowania i blokady (gdm-password, plasmalogin, kde) dołączają system-auth albo password-auth, jedna cecha włącza klucz naraz w sudo, na ekranie logowania i na konsoli.

Uruchomione: rejestracja pamu2fcfg (do pliku testowego), authselect current, authselect list-features, authselect test. Nie włączałem cechy na swoim systemie — enable-feature opisuję na podstawie dokumentacji i wygenerowanej konfiguracji.

Metoda 2: YubiCloud OTP (starsze klucze)​

Yubico OTP sprawdza jednorazowe hasło na serwerach Yubico, więc logowanie wymaga internetu. Moduł pam_yubico potrzebuje klucza API z upgrade.yubico.com/getapikey. Fabrycznie Yubico OTP jest w slocie 1 (Yubico — OTP).

mkdir -p ~/.yubico
# Dotknij klucza w dowolnym polu tekstowym — pierwsze 12 znaków OTP to ID klucza.
# Kilka kluczy: użytkownik:id1:id2
echo "$USER:cccccbcgebif" > ~/.yubico/authorized_keys

Linia PAM (np. w osobnym pliku dołączanym przez include):

auth required pam_yubico.so id=<ID klienta API> key=<klucz API>

Przy authselect taka ręczna zmiana wymaga własnego profilu (authselect create-profile). Dla nowych konfiguracji lepszy jest pam-u2f: działa offline i jest wbudowany w profil Fedory.

Metoda 3: Challenge-Response (offline)​

Nadpisuje slot OTP

ykman otp chalresp zapisuje nowy sekret w wybranym slocie i kasuje to, co tam było. Sprawdź ykman otp info — jeśli slot 2 ma status programmed, ta metoda zniszczy jego zawartość.

# Nowy sekret challenge-response w slocie 2, z wymaganym dotykiem
ykman otp chalresp --generate --touch 2

# Zapisanie odpowiedzi dla bieżącego użytkownika (~/.yubico/challenge-<numer seryjny>)
ykpamcfg -2
auth required pam_yubico.so mode=challenge-response

Szczegóły: Yubico — Challenge-Response w PAM.

Metody 2 i 3 nie były uruchamiane — oba sloty OTP mojego klucza są zajęte.

Konfiguracja konkretnych usług​

Sudo z YubiKey​

Przy authselect nie trzeba edytować /etc/pam.d/sudo. Na Fedorze 44 ma on linię auth include system-auth, więc cecha with-pam-u2f albo with-pam-u2f-2fa z poprzedniej sekcji działa także dla sudo.

Jeśli chcesz klucz tylko w sudo, a nie przy logowaniu, dopisz moduł w samym pliku sudo. Pliki PAM edytuj przez sudoedit, nie visudo — visudo sprawdza składnię sudoers i do PAM się nie nadaje:

sudoedit /etc/pam.d/sudo
#%PAM-1.0
auth sufficient pam_u2f.so cue # klucz zamiast hasła
auth include system-auth
...

Dla 2FA (hasło + klucz) linię auth required pam_u2f.so cue wstaw pod auth include system-auth. Test w nowym terminalu: sudo -k && sudo true.

Cache sudo — żeby nie dotykać klucza przy każdym poleceniu. Ustawienia trzymaj w osobnym pliku i edytuj przez visudo -f, który sprawdzi składnię przed zapisem:

sudo visudo -f /etc/sudoers.d/timeout
Defaults timestamp_timeout=15

Według man sudoers: timestamp_timeout to minuty (domyślnie 5; 0 — pytaj zawsze; wartość ujemna — bez wygasania). Pierwotna wersja wpisu podawała timestamp_timeout=900 jako „15 minut” — to 15 godzin. timestamp_type=global daje jeden wspólny cache dla wszystkich terminali użytkownika.

Nie uruchomione — opis na podstawie /etc/pam.d/sudo z Fedory 44 i man sudoers.

Login GDM/graficzny​

Przy authselect — tak samo jak sudo. Ekrany logowania dołączają password-auth, w którym cecha with-pam-u2f dodaje tę samą linię pam_u2f.so co w system-auth (sprawdzone przez authselect test):

  • GNOME (GDM): /etc/pam.d/gdm-password z pakietu gdm-50.3 dla Fedory 44 ma auth substack password-auth.
  • KDE Plasma: ekran logowania /usr/lib/pam.d/plasmalogin (pakiet plasma-login-manager 6.7.5) i blokada ekranu /etc/pam.d/kde (plasma-workspace) — oba mają auth substack password-auth.

Po zmianie zablokuj ekran i odblokuj go kluczem, zanim się wylogujesz.

Login konsolowy​

/etc/pam.d/login na Fedorze 44 zaczyna się od auth substack system-auth — cecha authselect obejmuje więc również konsolę (np. Ctrl+Alt+F3), która jest Twoim awaryjnym wejściem, gdy GDM odmówi. Przy with-pam-u2f (klucz zamiast hasła) brak klucza oznacza po prostu pytanie o hasło. Przy 2FA bez zapasowego klucza zgubiony klucz oznacza brak logowania — dlatego zapasowy klucz w tej samej linii u2f_keys jest obowiązkowy.

SSH z YubiKey​

Opcja A: klucze SSH FIDO2 (zalecane)

OpenSSH obsługuje klucze -sk od wersji 8.2; Fedora 44 ma 10.2.

# Klucz nierezydentny — nic nie jest zapisywane na YubiKey,
# plik ~/.ssh/id_ed25519_sk zawiera uchwyt, bez klucza fizycznego jest bezużyteczny
ssh-keygen -t ed25519-sk

# Klucz rezydentny — zajmuje jedno z miejsc na passkeys, za to da się go
# odtworzyć na innym komputerze poleceniem ssh-keygen -K
ssh-keygen -t ed25519-sk -O resident -O application=ssh:fedora -O verify-required

ssh-copy-id -i ~/.ssh/id_ed25519_sk.pub user@server

verify-required wymaga PIN-u FIDO2 przy każdym użyciu (oprócz dotyku).

Opcja B: PIV / PKCS#11

Nadpisuje slot PIV

ykman piv keys generate tworzy nowy klucz w slocie i kasuje poprzedni. Sprawdź ykman piv info — jeśli slot 9a jest zajęty (np. certyfikat do logowania w firmie), wybierz inny albo zrezygnuj.

# Klucz ECC P-256 w slocie 9a (Ed25519 w PIV wymaga firmware 5.7 — patrz dokumentacja Yubico wyżej)
ykman piv keys generate --algorithm ECCP256 --pin-policy ONCE --touch-policy ALWAYS 9a public.pem
ykman piv certificates generate --subject "CN=OpenSSH" 9a public.pem

# Klucz publiczny dla authorized_keys — przez moduł PKCS#11 z OpenSC
ssh-keygen -D /usr/lib64/pkcs11/opensc-pkcs11.so -e
ssh -I /usr/lib64/pkcs11/opensc-pkcs11.so user@server

Pierwotna wersja wpisu używała /usr/lib64/libykcs11.so — na Fedorze 44 ten plik jest tylko w pakiecie yubico-piv-tool-devel. Moduł OpenSC instaluje się razem z pakietem opensc.

Uruchomione: ssh-keygen -t ed25519-sk (nierezydentny) — klucz [email protected] wygenerowany na Fedorze 44. Nie uruchomione: klucz rezydentny (zajmuje miejsce na kluczu) i opcja B (slot 9a na moim kluczu jest zajęty).

Konfiguracja OpenPGP/GPG​

Instalacja i przygotowanie​

sudo dnf install pcsc-lite gnupg2
sudo systemctl enable --now pcscd

gpg --card-status

Podstawowa konfiguracja GPG​

Jeśli gpg --card-status nie widzi klucza, choć ykman list go widzi, zwykle przyczyną jest konflikt wbudowanego sterownika CCID w scdaemon z pcscd. Wtedy:

echo "disable-ccid" >> ~/.gnupg/scdaemon.conf
gpgconf --kill scdaemon
gpg --card-status

Nie dodawaj tej linii zapobiegawczo — jeśli gpg --card-status działa, konfiguracja jest w porządku.

Zmiana PIN-ów PIV​

Fabryczne wartości PIV to PIN 123456, PUK 12345678 i publicznie znany klucz zarządzania (Yubico — PIV) — zmień je przed pierwszym użyciem PIV. Na moim kluczu z firmware 5.7.1 ykman piv info pokazuje klucz zarządzania AES192.

ykman piv access change-pin
ykman piv access change-puk
# Losowy klucz zarządzania, przechowywany na kluczu i chroniony PIN-em
ykman piv access change-management-key --generate --protect

Konfiguracja dotykania dla operacji OpenPGP​

ykman openpgp keys set-touch sig on
ykman openpgp keys set-touch dec on
ykman openpgp keys set-touch aut on

Polityka on da się wyłączyć. fixed — według ykman openpgp keys set-touch --help — nie da się wyłączyć bez usunięcia klucza prywatnego, a dla klucza atestacji — bez wymiany klucza atestacji.

Nie uruchomione na moim kluczu poza odczytem ykman openpgp info i ykman piv info.

OATH/TOTP (Google Authenticator replacement)​

Instalacja aplikacji​

flatpak install flathub com.yubico.yubioath

Sekrety TOTP są na kluczu, nie w telefonie, więc kody wygenerujesz na każdym komputerze z aplikacją albo przez ykman. Do aplikacji OATH na kluczu dostęp ma tylko interfejs CCID.

Zarządzanie kontami TOTP​

ykman oath access change # hasło do aplikacji OATH
ykman oath access remember # zapamiętanie hasła na tym komputerze
ykman oath accounts add google <SEKRET_TOTP>
ykman oath accounts code google
ykman oath accounts list
ykman oath accounts delete google

ykman oath accounts add zapisuje nowe konto; istniejące o innej nazwie zostają, przy tej samej nazwie ykman zapyta o nadpisanie.

Zaawansowane konfiguracje​

Blokowanie ekranu po wyjęciu YubiKey​

# /etc/udev/rules.d/85-yubikey-lock.rules
ACTION=="remove", ENV{ID_BUS}=="usb", ENV{ID_VENDOR_ID}=="1050", ENV{ID_MODEL_ID}=="0407", RUN+="/usr/bin/loginctl lock-sessions"
sudo udevadm control --reload

0407 to identyfikator YubiKey 5 z włączonymi interfejsami OTP+FIDO+CCID (taki pokazuje lsusb dla mojego klucza). Inny zestaw interfejsów to inny identyfikator — sprawdź swój przez lsusb | grep Yubico.

Reguła nie była testowana.

Konfiguracja różnych trybów dla różnych usług​

Cechy authselect działają globalnie. Żeby mieć np. 2FA w sudo, a samo hasło przy logowaniu, zostaw profil bez cechy u2f i dopisz linię pam_u2f.so tylko w /etc/pam.d/sudo (sekcja „Sudo z YubiKey”). authselect zarządza tylko plikami, które są w /etc/pam.d/ dowiązaniami do /etc/authselect/ (system-auth, password-auth, fingerprint-auth, smartcard-auth, switchable-auth, postlogin). Pliki usług w /etc/pam.d/ (sudo, login, gdm-password, kde) są zwykłymi plikami, więc ręczne zmiany w nich zostają. Wyjątek: plik z /usr/lib/pam.d/ (np. plasmalogin) nadpisze aktualizacja pakietu — najpierw skopiuj go do /etc/pam.d/, który ma pierwszeństwo, i tam edytuj.

Rozwiązywanie problemów​

Sprawdzanie statusu YubiKey​

ykman list # podłączone klucze
ykman info # firmware, aktywne aplikacje
ykman fido info # PIN FIDO2, wolne miejsce na passkeys
ykman otp info # stan slotów OTP
gpg --card-status # karta OpenPGP

journalctl -b | grep -i pam_u2f # błędy modułu PAM

Typowe problemy​

Problem: YubiKey nie jest rozpoznawany

lsusb | grep Yubico # czy system w ogóle widzi urządzenie
systemctl status pcscd # dla PIV/OpenPGP
ykman info # czy aplikacje są włączone na USB

Problem: GPG nie widzi YubiKey — patrz „Podstawowa konfiguracja GPG” (disable-ccid).

Problem: pamu2fcfg zwraca FIDO_ERR_OPERATION_DENIED — u mnie pojawiało się, gdy polecenie działało bez interaktywnego terminala; w zwykłym terminalu z dotknięciem klucza rejestracja przeszła.

Problem: sudo przy każdym użyciu wymaga YubiKey — ustaw timestamp_timeout w /etc/sudoers.d/ (sekcja „Sudo z YubiKey”). Nie dopisuj nic do /etc/sudoers przez echo | tee — błąd składni zablokuje sudo całkowicie, a visudo -f sprawdzi plik przed zapisem.

Problem: po zmianach nie mogę się zalogować — konsola tekstowa (Ctrl+Alt+F3) albo otwarta wcześniej powłoka roota, potem authselect backup-list i authselect backup-restore <nazwa> (albo authselect disable-feature with-pam-u2f).

Backup i bezpieczeństwo​

Konfiguracja zapasowego klucza​

Zawsze konfiguruj drugi YubiKey — klucz może się zepsuć albo zgubić:

  • pam-u2f — drugi klucz w tej samej linii u2f_keys (sekcja „Metoda 1”).
  • Yubico OTP — użytkownik:id1:id2 w ~/.yubico/authorized_keys.
  • SSH FIDO2 — osobny klucz ssh-keygen -t ed25519-sk na każdym YubiKey, oba klucze publiczne w authorized_keys.
  • TOTP — dodaj konto na obu kluczach od razu przy włączaniu 2FA, póki masz sekret (kod QR) pod ręką.

Testowanie konfiguracji​

Zawsze testuj w nowym terminalu, zanim zamkniesz bieżący:

sudo -k && sudo true # sudo
ssh localhost # jeśli zmieniałeś sshd
# GDM: zablokuj i odblokuj ekran

Podsumowanie​

  1. Najpierw sprawdź, co jest na kluczu — PIV, OTP challenge-response i OpenPGP nadpisują sloty.
  2. pam-u2f przez authselect enable-feature, nie select, z kopią -b i otwartą powłoką roota.
  3. Zapasowy klucz w tej samej linii u2f_keys i osobny klucz SSH na każdym YubiKey.
  4. Klucze SSH ed25519-sk zamiast PIV, jeśli serwer ma OpenSSH 8.2+.
  5. Cache sudo w minutach, w pliku w /etc/sudoers.d/.

Powiązane: Cyberbezpieczeństwo to inżynieria, a nie moralizatorstwo — o FIDO2 jako obronie przed przejęciem sesji (AiTM), oraz OSINT numeru telefonu — o phishingu SMS, przed którym klucz FIDO2 chroni, bo podpisuje logowanie tylko dla właściwej domeny.