Väčšina serverov, ku ktorým sa pripájam, má nastavenie PasswordAuthentication na no, čo znamená, že pomerne často vidím chybu:

Permission denied (publickey).

Dôvodov je viac, ale v mojom prípade sa to stáva, pretože v SSH agentovi nie sú prítomné žiadne identity (kľúče).

SSH agent #

SSH agent uchováva OpenSSH kľúče používané na autentifikáciu pomocou verejného kľúča (táto metóda je výrazne lepšia ako autentifikácia pomocou plain-text hesla a mala by byť preferovaná vždy, keď je to možné) a odovzdáva správny kľúč serveru počas pripojenia. Pojem OpenSSH kľúče je pomerne široký. Pre účely tohto článku odkazuje na kontext autentifikácie pomocou verejného kľúča. Autentifikácia pomocou verejného kľúča v skutočnosti vyžaduje pár kľúčov – samozrejme verejný kľúč a jeho zodpovedajúci náprotivok, súkromný kľúč.

Predvolený SSH agent dodávaný s OpenSSH je ssh-agent. Má pomerne základnú sadu funkcií, ako sa očakáva. Existujú softvérové balíčky, ktoré môžu fungovať ako SSH agent a ich sady funkcií sa líšia. V systéme môže byť v danom čase aktívny len jeden SSH agent.

Kľúčenky a správcovia hesiel #

Mnohé distribúcie dodávajú Gnome Keyring, správcu hesiel/kľúčenku (označovanú aj ako User Credentials Manager, čo naznačuje, že dokáže spravovať viacero typov poverení). Tieto dva pojmy nie sú totožné, ale pre jasnosť tento článok označuje Gnome Keyring ako kľúčenku a KeePassXC ako správcu hesiel. Oba softvérové balíčky sa vo funkciách tu diskutovaných výrazne prekrývajú, preto sa termíny objavujú spolu.

Oba – KeePassXC aj najmä Gnome Keyring – dokážu spravovať viacero typov tajomstiev alebo poverení používateľa (niektoré sa prekrývajú), ako sú heslá, bezpečnostné certifikáty a Freedesktop.org secrets, okrem kľúčov ako GnuPG kľúče a jadro tejto témy, OpenSSH kľúče. Schopnosť kľúčenky/správcu hesiel spravovať OpenSSH kľúče znamená, že obsahuje aj implementáciu SSH agenta.

Prístupová fráza súkromného kľúča #

Súkromný kľúč môže a (pokiaľ neexistuje platný dôvod na opak) by mal byť dodatočne chránený prístupovou frázou. Ak je chránený, pred použitím kľúča na skutočnú autentifikáciu je potrebná platná prístupová fráza.

Rozšírením predchádzajúcej definície, schopnosť kľúčenky/správcu hesiel spravovať OpenSSH kľúč tiež znamená, že dokáže uložiť a neskôr vyvolať uloženú prístupovú frázu súkromného kľúča.

Výzvy na zadanie prístupovej frázy #

V najzákladnejšom zmysle ssh-agent vyzve na zadanie prístupovej frázy pri pridaní kľúča chráneného prístupovou frázou do neho. Tento proces je synchrónny v tom zmysle, že terminál čaká na zadanie prístupovej frázy pred vydaním ďalšieho príkazu. Agent zabraňuje opakovaným výzvam pre rovnaký kľúč, ktorý je už v ňom pridaný, kým kľúč nie je nakoniec z neho odstránený. Zníženie počtu výziev na prístupovú frázu je v skutočnosti hlavnou zodpovednosťou agenta.

Kľúčenka a Gnome Keyring fungujú odlišne v porovnaní s ssh-agent pri pridávaní kľúčov do ich príslušných implementácií agenta. Keď je to nakonfigurované, používateľ nie je vyzvaný zadávať prístupové frázy pre jednotlivé kľúče, pretože prístupové frázy sú uložené v databáze kľúčenky/správcu hesiel. Namiesto toho je používateľ vyzvaný na zadanie jediného hlavného hesla pri odomykaní kľúčenky (pri Gnome Keyring zvyčajne nie je viditeľná žiadna výzva na prístupovú frázu SSH vôbec. Je to zámerné, pretože heslo účtu používateľa sa používa ako hlavné heslo kľúčenky, čím sa kľúčenka automaticky odomkne po prihlásení používateľa) alebo databázy.

Problém nastáva v situáciách, kde je výzva vyvolaná asynchrónne – keď k nej nie je priradený žiaden terminál. To je všeobecne prípad programov s grafickým rozhraním (GUI). Keďže Gnome Keyring aj KeePassXC majú vlastné grafické rozhrania, oba sú ovplyvnené.

SSH_ASKPASS a ssh-add #

Manipulácia s kľúčmi v agente sa vykonáva pomocou ssh-add. Hoci je momentálne dostupných viacero agentov, existuje len jeden široko používaný ssh-add. Všetky spomínané OpenSSH agenty sa snažia byť kompatibilné s príkazom ssh-add, inak by neboli veľmi užitočné.

Obzvlášť problematickým scenárom s výzvou na prístupovú frázu a oboma diskutovanými GUI programami je parameter -c príkazu ssh-add (hoci by KeePassXC a Gnome Keyring fungovali dostatočne dobre ako agenti aj bez implementácie tejto funkcionality, postupom času ju implementovali kvôli požiadavkám komunity na plnú kompatibilitu s ssh-agent), ktorý označí kľúč pridaný do agenta na potvrdenie pred použitím. Takto označený kľúč je stále pridaný do kľúčenky/správcu hesiel, ale očakáva výzvu na zadanie prístupovej frázy v plávajúcom dialógu v momente, keď je kľúč skutočne použitý. Táto funkcionalita zase vyžaduje aspoň správne nakonfigurovanú premennú prostredia SSH_ASKPASS, odkazujúcu na fungujúcu implementáciu grafickej výzvy.

KeePassXC a potvrdenie používateľa #

V KeePassXC existuje dôležité a užitočné nastavenie v zázname na záložke SSH, ktoré odstráni kľúče z agenta po zamknutí databázy (kvôli tesnej väzbe s prihlasovacou reláciou používateľa, Gnome Keyring neponúka možnosť odstrániť kľúče z agenta, čo môže teoreticky zvýšiť potenciál ich zneužitia. Pôvodný ssh-agent a konkrétne KeePassXC, oba fungujúce oddelene od prihlasovacieho sezamu používateľa, majú možnosti automatického odstraňovania kľúčov z agenta). Aktivuj ho zaškrtnutím:

  • Remove key from agent when database is closed/locked

Stojí za zmienku, že KeePassXC okrem uloženia prístupovej frázy ponúka aj možnosť uložiť samotný súkromný kľúč v databáze ako prílohu. Pri povolenom vyššie uvedenom nastavení je ďalšie zapnutie potvrdenia používateľa na rovnakej záložke SSH veľkou prekážkou, keď sú kľúč aj jeho prístupová fráza uložené v tej istej databáze. Pre zvýšenie bezpečnosti by sa mal každý vždy snažiť ukladať rôzne bezpečnostné faktory na rôznych miestach (je bezpečnejší prístup ukladať rôzne faktory bezpečnosti na rôznych miestach. Napríklad pri použití hesla + 2FA/MFA vo forme TOTP, heslo uložiť v správcovi a druhý faktor v telefóne. To platí aj pre SSH kľúče, napríklad uloženie súkromného kľúča v súborovom systéme /niečo, čo vlastním/ a jeho prístupovej frázy v pamäti /niečo, čo viem/. V praxi je ukladanie každého dostupného faktoru v jednej zabezpečenej databáze .kdbx so silným hlavným heslom stále o trochu lepšie ako vynechávanie niektorých dostupných faktorov, napríklad použitie len hesla bez TOTP alebo ssh kľúča bez prístupovej frázy).

Ďalej, keď je potvrdenie používateľa povolené, ale askpass je nesprávne nakonfigurovaný, SSH prestane fungovať so zobrazením chyby:

sign_and_send_pubkey:
signing failed for RSA "peter@peterbabic.com" from agent: agent refused operation

S ohľadom na vyššie uvedené by som odporučil zvážiť povolenie potvrdenia používateľa iba keď platí aspoň jedno z:

  • Skutočný súkromný kľúč a jeho prístupová fráza sú uložené v rôznych databázach
  • Kľúče sa automaticky neodstraňujú z agenta po zamknutí databázy

Príprava #

Pred tým, ako príkazy vyžadujúce ssh automaticky vyvolajú dialóg na odomknutie databázy KeePassXC, je potrebných niekoľko ďalších krokov. Keďže môže byť aktívny len jeden SSH agent naraz, iné prípadne bežiace agenty musia byť vypnuté alebo nakonfigurované inak, aby bolo možné používať implementáciu agenta KeePassXC.

chmod -x /usr/bin/gnome-keyring-daemon

General > Startup

  • Start only a single instance of KeePassXC
  • Minimize window after unlocking database
  • Remember previously used databases
    • Load previously open databases on startup

Security > Convenience

  • Lock databases when session is locked or lid is closed

SSH Agent

  • Enable SSH Agent integration
  • Nakonfiguruj skutočný SSH záznam zodpovedajúcim spôsobom:

Edit entry > Entry

Password: [KEY_PASSPHRASE]

Edit entry > SSH Agent

  • Add key to agent when database is opened/unlocked
  • Remove key from agent when database is closed/locked

Edit entry > SSH Agent > Private key

Vlož buď platný [Attachment] ALEBO [External file]

Otestuj nastavenie #

Pred pokračovaním otestuj, že všetko funguje správne. Začni odomknutím databázy KeePassXC a spustením ssh-add -l, výstup by mal byť:

4096 SHA256:9k/Nfk7fijei+JFj8F7YfyF7fhFHElSmpuFuew9+8f3 email@example.com (RSA)

Zamknutie databázy a spustenie ssh-add -l by malo vrátiť presne toto:

The agent has no identities.

Ak to tak nie je, pozri sekciu Ďalšie čítanie na konci. Tam sú užitočné odkazy od iných ľudí, ktorí KeePassXC využívajú naplno.

Výzva na odomknutie KeePassXC pomocou ssh #

Keď je všetko pripravené a otestované, konkrétna vec je implementovať skript, ktorý sa zavolá pred spustením akéhokoľvek príkazu využívajúceho ssh. Na to vytvor nasledujúce dva súbory:

  • Vlož nasledujúci riadok do ~/.ssh/config:
ProxyCommand $HOME/.ssh/keepassxc-prompt %h %p
  • Nakoniec vytvor spustiteľný skript ~/.ssh/keepassxc-prompt odkazovaný vyššie:
#!/bin/bash

until ssh-add -l &> /dev/null
do
  echo "Waiting for agent. Please unlock the database."
  keepassxc &> /dev/null
  sleep 1
done

/usr/bin/nc "$1" "$2"

Hotovo! Pri spustení akéhokoľvek príkazu využívajúceho ssh, keď je databáza ešte zamknutá, sa vyvolá dialóg na odomknutie KeePassXC. Po odomknutí sa kľúče automaticky pridajú do agenta a príkaz uspeje. Žiadne ďalšie Permission denied (publickey). pre platné kľúče!

Toto je 30. príspevok série #100daystooffload.

Často kladené otázky (FAQ) #

Prečo je skript keepassxc-prompt taký jednoduchý?

Slúži ako proof of concept. Uprav podľa potreby. Jednou dobrou úpravou je pridanie timeoutu.

Nie je ProxyCommand určený na SSH forwarding?

Áno, ale zdá sa, že s týmto prístupom funguje bez problémov.

Prečo jednoducho nevytvoriť alias ssh na wrapper skript?

Existujú iné príkazy, ktoré sa spoliehajú na ssh. S aliasom by každý iný príkaz nevyvolal výzvu na odomknutie, napríklad git pull.

Prečo nenahradiť /usr/bin/ssh wrapper skriptom?

Mnoho dôvodov. Bráni to správnym aktualizáciám a pri niečom bezpečnostne citlivom ako OpenSSH sa odporúča používať aktualizovaný softvér. Ďalej sa spolieha na súbor jediného používateľa, takže by to vyplo ssh pre ostatných používateľov v systéme. Okrem toho je to jednoducho škaredé.

Môžem použiť D-Bus na detekciu, či je databáza zamknutá/odomknutá?

Samozrejme. Ak sú v agente aj iné kľúče spravované oddelene od KeePassXC, jednoducho použi toto namiesto ssh-add -l v keepassxc-proxy:

qdbus org.keepassxc.KeePassXC.MainWindow /org/freedesktop/secrets/collection/Passwords org.freedesktop.Secret.Collection.Locked

Dá sa na tento účel použiť /etc/sshrc alebo, keď je povolený, ~/.ssh/rc?

Nie. Tieto hook súbory sa spúšťajú na serveri pri nadviazaní spojenia. Aby to fungovalo, hook musí bežať na klientovi. Ten druhý musí byť tiež povolený pomocou PermitUserRC yes v /etc/ssh/sshd_config.

V akých iných situáciách KeePassXC automaticky vyzve na odomknutie?

  1. Pri použití globálnej klávesovej skratky Auto-type
  2. Keď je povolená služba KeePassXC Freedesktop.org Secret Service a program potrebuje prístup
  3. Pri akejkoľvek klávesovej skratke browser pluginu, ak je nainštalovaný a správne nakonfigurovaný

Settings > Browser Integration

  • Enable browser integration
    • Request to unlock database if it is locked

Odkazy #