ssh intimně aneb úvod do paranoii 2

1. 4. 2003
Doba čtení: 14 minut

Sdílet

Dnes se uz opravdu dostaneme k tomu, co jsou to ssh klíče, a k podrobnému BFUnesnímu návodu k použití :)

[kecy]

Disclaimer: Tento článek čtete na vlastní nebezpečí. Pokud se vám první díl nelíbil, mohu vás ujistit, ze se vám nebude líbit ani tento, ale vaše poznámky v diskusi budou ignorovány, protože jste byli varováni a měli jste se poučit. Naopak pokud se vám to minule líbilo, bude se vám to tentokrát líbit ještě víc! :) Mimochodem – tag [kecy] neznamená, že to jsou nesmysly, které nemáte číst, nýbrž, že to jsou informace, které si stačí přečíst právě jednou, a až někdy za rok budete hledat návody, můžete je směle přeskočit.

Takže milé děti, doufám, že prudiči nás již po přečtení disclaimeru opustili, zůstali jsme v přátelském kruhu věřících, a tedy se konečně můžeme věnovat vážné práci :).

[/kecy][data]

K minulému dílu: Kromě spousty řečí se v diskusi objevilo i pár zajímavých informací, tak jsem si dovolila je zde vytáhnout na světlo, ať neupadnou v zapomnění.

1) Seriály, které jsem sama před psaním tohoto seriálu nenašla (oba jsou už lehce obsoletní, takže např. aktuální ekvivalent dnešního návodu na klíče tam nenajdete, ale určite se tam dozvíte mnoho věcí, ke kterým se já vůbec nedostanu):

1a) Lemmingův seriál na Undergroundu: 1., 2., 3.4.

1b) Seriál na Kryptě 1., 2.,3.

2) Řešení domácího úkolu od uživatelů Mmm a Iany (děkuji!).
Putty si ukládá public klíče strojů do registry, a to sem:

HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys,

SSH 3.2.0 si je schovává do separátních souborů v adresáři

C:\ProgramFiles\SSH Communications
 Security\Users\[username]\HostKeys

Klíče se jmenují úplně stejně jako v linuxovém ekvivalentu SSH (~/ssh2/hostke­ys/*), však určitě poznáte, který k čemu patří :).
Filo ještě mimo diskusi doplňuje, že dříve oblíbený TeraTerm si ukládá klíče do

HKEY_CURRENT_USER\Software\Ayera\TTXSSH\SshHostKeys

a stále ještě oblíbené WinSCP do

HKEY_CURRENT_USER\Software\Martin Prikryl\WinSCP 2\SshHostKeys

věřit jsem zvládla pouze putty, Win nejsou mojí silnou stránkou, ale proto jsem také ten domácí úkol zadala, že :).

Lingvistická poznámka: Fakt nevím, jak správně lokalizovat termín passphrase, takže během článku střídavě osciluji mezi passphrase-passphraze-passphráze, přičemž se řídím lokálními morfologickými potřebami i citovým zabarvením :) Díky za pochopení.

Druhý akční paranoidní postup – vyrábíme si vlastní klíče

Autentizace (řekla jsem to správně? :)) ssh klíči je velmi zkráceně metoda, kdy si vyrobíme svůj klíč, jeho private část si necháme (obvykle zašifrovanou passphrází), public část dáme na všechna místa, kam se chceme pomocí tohoto klíče logovat, a pak nám k přihlášení stačí mít u sebe private část klíče a znát passphrazi. Funguje to tak, že server něco náhodného zašifruje naším public klíčem, my mu to podepíšeme private klíčem, čímž dokážeme, že jsme to my, a jedeme. Passphrase nikde necestuje, používá se pouze lokálně na rozšifrování private klíče před použitím a můžeme ji měnit, aniž bychom museli znova distribuovat public klíče. Obecně asi může být o trochu slabší než heslo (NO WARRANTY), ale prázdná se nedoporučuje.

[uplný_kecy – výchova]

ssh klíče jsou dobrá věc, hlavně proto, ze nikomu při vzdáleném logování neříkáme své heslo. Za svůj pohnutý život matfyzačky už jsem se setkala s několika případy patchnutých ssh a sshd, a to se potom taková johanka dost vyděsí, protože vládce nad hacknutým strojem mohl odchytit nejen její heslo tamní, ale i všechna hesla, kterými se logovala odtamtud někam pryč. Lze tomu předejít buď vlastním staticky zkompilovaným ssh (ale patchnutí sshd asi jako user nepředejdete nikdy), nebo tím, že heslo vůbec nikde neříkáte, protože používáte klíče. Pak v případě hacknutého stroje pouze smažete public klíče vašeho tamního účtu, které máte rozseté na různých serverech, a nemusíte se obávat, že se nákaza bude šířit dál :).

Další situace, kde jsou ssh klíče velmi užitečné – stane se, že N lidí by mělo mít rootovská práva na nějakém stroji. Říct všem heslo je jedna možnost, která je ovšem nebezpečná – zvyšuje se pravděpodobnost, že heslo někudy uteče, dále pokud někoho přestaneme mít rádi nebo mu napadli stroj, musíme heslo měnit a zase to všem říkat, a když má mít takhle člověk přístup na 10 a více routerů různých lidí, tak je navíc otrava si všechna ta hesla pamatovat (pomiňme nyní, že skutečne existují routery v CZFree, které mají rootovské heslo „czfree“…). Druhá možnost (zdravíme Froda) je dát našim oblíbeným uživatelům vyšší práva (skupina wheel a příbuzné metody). To mi přijde jako zvěrstvo, protože tím zbytečne povyšujeme user hack na root hack bez námahy. Takže opět zbývají naše oblíbené ssh klíče.

[/uplný_kecy – výchova]

Konec keců :), tady je návod (připomínám, že pro Protokol 2, o jedničce se letmo zmíním závěrem).

[/kecy][data]

Mějme dva počítače, řekněme klienta krtecek a server pikatchu, na obou vhodnou verzi ssh (= pro začátek všude stejnou, OpenSSH nebo SSH) a účet jménem johanka :). Chceme se z krtečka logovat na pikatchua pomocí klíče (krtecek a pikatchu neexistují, kdo uhodne, na kterých strojích (celkem čtyři) jsem generovala příklady, dostane lízátko :)).

OpenSSH

johanka@krtecek:~$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/johanka/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:

Místo -t dsa můžeme dát -t rsa. S defaultním umístěním klíče souhlasíme, passphrazi si nějakou vymyslíme, tou, kterou řekneme, se budeme logovat z tohoto počítače, kamkoli si to umožníme.

Your identification has been saved in /home/johanka/.ssh/id_dsa.
Your public key has been saved in /home/johanka/.ssh/id_dsa.pub.
The key fingerprint is:
fb:8e:8f:d4:f3:5d:8e:90:ef:a3:2e:c6:0e:b2:6d:03 johanka@krtecek

právě jsme vygenerovali klíč

johanka@krtecek:~$ cd .ssh
johanka@krtecek:~/.ssh$ ls
id_dsa  id_dsa.pub
johanka@krtecek:~/.ssh$ scp id_dsa.pub
 johanka@pikatchu:.ssh/johanka@krtecek.pub

kopírujeme public část klíče na server

The authenticity of host 'pikatchu (197.121.273.10)'
 can't be established.
RSA1 key fingerprint is
 43:e6:48:70:e1:87:58:1f:62:91:13:f6:02:67:d9:15.
Are you sure you want to continue connecting (yes/no)?
Warning: Permanently added 'pikatchu, 197.121.273.10'
 (RSA1) to the list of known hosts.

zatím můžete hádat, proč jsem tady tyhle blbý otázky nechala :)

johanka@pikatchu.some.domain's password:
id_dsa.pub      100% |***********************|   603   00:00

johanka@krtecek:~/.ssh$ ssh pikatchu
johanka@pikatchu's password:

Last login: Fri Mar 21 17:59:57 2003 from arc.ms.mff.cuni.cz
johanka@pikatchu:~$ cd .ssh
johanka@pikatchu:~/.ssh$ ls
johanka@krtecek.pub
johanka@pikatchu:~/.ssh$ cat johanka@krtecek.pub
 >> authorized_keys

Právě jsme si umožnili přihlášení na server pomocí klíče z krtečka. Některé (starší) verze OpenSSH mohou místo authorized_keys vyžadovat authorized_keys2.

johanka@pikatchu:~/.ssh$ rm johanka\@krtecek.pub
johanka@pikatchu:~/.ssh$ exit
logout
Connection to pikatchu closed.

johanka@krtecek:~/.ssh$ ssh -2 pikatchu
The authenticity of host 'pikatchu (197.121.273.10)'
 can't be established.
RSA key fingerprint is
 44:30:d2:89:dd:f8:8a:af:d0:b4:46:73:9f:2e:9f:5c.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'pikatchu,197.121.273.10'
 (RSA) to the list of known hosts.

a modří už vědí, bylo to proto, abych vám ukázala, že opravdu různé protokoly ukazují různé fingerprinty stejného stroje (viz minulý díl)

Enter passphrase for key '/home/johanka/.ssh/id_dsa':
Last login: Fri Mar 21 18:13:55 2003 from krtecek.some.domain
johanka@pikatchu:~$

A ani to nebolelo, co? :) Pokud to nechodí tak, jak má, viz sekce Troubleshooting.

[/data][kecy]

Co se týče toho, co musíme nechat na klientovi. Private klíč tam nechat musíme a musí se jmenovat id_dsa (a být v ~/.ssh), jinak to (defaultně) nebude chodit. Potřebujeme-li udržovat více private klíču (obecně pro to není důvod, ale např. pro více uživatelů téhož účtu) nebo z libovolného důvodu chceme, aby se náš private klíč jmenoval jinak, pojmenujeme si ho jakkoli a přinutíme OpenSSH použít daný klíč parametrem -i jmeno_klice. Co se týče public klíče, pokud ten pojmenujeme jinak než jmeno_odpovida­jiciho_private_kli­ce.pub (defaultně tedy id_dsa.pub) nebo ho přímo odsmahneme, bude nám to sice chodit, ale bude se to při každé konexi (ssh –2) blbě ptát na passphrazi i v případech, kdy ji to následně nevyužije (= na remote hostu svůj public klíč nemáme). Tedy smazat ho můžeme, na funkčnosti to neubere, ale ubere to na uživatelské přívětivosti :). Je to proto, že má-li OpenSSH po ruce public klíč ke svému private klíči, pokusí se nejprve dohodnout se serverem ve stylu „Máš tam tenhle public key? Jestli jo, tak s ním něco zašifruj a já to zkusím podepsat“, pokud ho nemá, musí hned natvrdo použít private klíč.

Chceme-li zprovoznit i opačný směr, vygenerujeme si (ssh-keygen) klíč i na pikatchuovi, zkopírujeme ~/.ssh/id_dsa.pub coby johanka@pikatchu.pub na krtečka a tam catneme do souboru ~/.ssh/authori­zed_keys

[/kecy][data]

SSH

johanka@krtecek:~$ ssh-keygen2

případně s parametrem -t rsa

Generating 2048-bit dsa key pair
   5 oOo..oOo.oOo
Key generated.
2048-bit dsa, johanka@krtecek.another.domain,
 Sat Mar 22 2003 19:10:49 +0100
Passphrase :
Again      :
Private key saved to /home/johanka/.ssh2/id_dsa_2048_a
Public key saved to /home/johanka/.ssh2/id_dsa_2048_a.pub

právě jsme vygenerovali klíč, ptalo se nás to jen na passphrazi, tou, kterou jsme zadali, se budeme logovat z tohoto počítače, kamkoli si to umožníme

johanka@krtecek:~$ cd .ssh2
johanka@krtecek:~/.ssh2$ ls
hostkeys  id_dsa_2048_a  id_dsa_2048_a.pub  random_seed
johanka@krtecek:~/.ssh2$ mv id_dsa_2048_a johanka@krtecek
johanka@krtecek:~/.ssh2$ mv id_dsa_2048_a.pub johanka@krtecek.pub
johanka@krtecek:~/.ssh2$ vi identification

Do souboru identification napíšeme/přidáme následující řádek:

IdKey johanka@krtecek

"identification" [New] 1L, 26C written
johanka@krtecek:~/.ssh2$ scp johanka\@krtecek.pub
 johanka@pikatchu:.ssh2/.

kopírujeme veřejnou část klíče na server

Host key not found from database.
Key fingerprint:
xokib-fibus-veper-zuriv-lefak-kesyn-dypih-nagod-rumis-cecef-bixix
You can get a public key's fingerprint by running
% ssh-keygen -F publickey.pub
on the keyfile.
Are you sure you want to continue connecting (yes/no)? yes
Host key saved to /home/johanka/.ssh2/hostkeys/key_22_pikatchu.pub
johanka@pikatchu's password:
johanka@krtecek.pub   | 1.2kB |  1.2 kB/s | TOC: 00:00:01 | 100%

johanka@krtecek:~/.ssh2$ ssh pikatchu
johanka's password:
Authentication successful.
Last login: Sat Mar 22 2003 19:36:08 +0100 from krtecek
[johanka@pikatchu johanka]$ cd .ssh2
[johanka@pikatchu .ssh2]$ ls
johanka@krtecek.pub
[johanka@pikatchu .ssh2]$ vi authorization

Do souboru authorization napíšeme/přidáme následující řádek:

Key johanka@krtecek.pub

právě jsme si umožnili logovat se na pikatchua z krtečka pomocí klíče

"authorization" [New] 1L, 28C written
[johanka@pikatchu .ssh2]$ exit

Connection to pikatchu closed.
johanka@krtecek:~/.ssh2$ ssh pikatchu
Passphrase for key "/home/johanka/.ssh2/johanka@krtecek"
 with comment "2048-bit dsa, johanka@krtecek.another.domain,
 Sat Mar 22 2003 19:10:49 +0100":
Authentication successful.
Last login: Sat Mar 22 2003 19:51:18 +0100 from krtecek
[johanka@pikatchu johanka]$

A jsme tam! Pokud nejsme, opět viz sekce Troubleshooting.

[/data][kecy]

Je vhodné si oba klíče zatepla přejmenovat na něco názorného a jednoznačného, abychom si ty veřejné nepletli, až jich budeme více najednou kompostovat na serveru (označení login@jmenostroje je nejlepší, ale je to skutečně čistě rozlišovací označení („Tak proč zrovna my jsme béčko?“), nikdo nás nenutí, aby to korespondovalo se skutečným loginem a jménem stroje, jen se v tom pak lépe vyznáme). Na rozdíl od OpenSSH se zde tedy i private klíč může jmenovat libovolně, protože SSH se jména všech private klíču dozví právě ze souboru identification. Leč máme zde také možnost použít při konexi parametr -i jmeno_klice, pokud se z nějakého důvodu chceme autorizovat klíčem, který v identification není uveden. Odpovídající public klíč v adresáři ~/.ssh2 však (opět rozdíl od OpenSSH) mít musíme a musí se jmenovat jmeno_private_kli­ce.pub, jinak nám to nebude chodit vůbec, ani náhodou :).

V souborech identification na klientovi a authorization na serveru nám časem budou přibývat řádky, pokud chceme používat víc private klíčů (obecně pro to není důvod), bude soubor identification časem vypadat třeba takto

IdKey klic1@krtecek
IdKey klic2@krtecek
IdKey klic3@krtecek
...

a pokud chceme akceptovat více public klíču (coz pravděpodobně budeme chtít), bude soubor authorization časem vypadat takto:

Key johanka@pikatchu.pub
Key drzka@maja.pub
Key root@ferda.pub
...

Musí zde být uvedena jména všech public klíčů, které v adresáři ~/.ssh2 máme a chceme pomocí nich umožnit přístup, jinak nám budou ony klíče houby platné (totéž platí o private klíčích a identification).

Chceme-li zprovoznit i opačný směr, vygenerujeme si (ssh-keygen2) klíč i na pikatchuovi, přiměřeně jeho části přejmenujeme (johanka@pikatchu, johanka@pikatchu.pub), do souboru identification na pikatchuovi napíšeme IdKey johanka@pikatchu, soubor johanka@pikatchu.pub zkopírujeme na krtecka do adresáře ~/.ssh2 a tam do souboru authorization napíšeme/přidáme řádek Key johanka@pikatchu.pub. A mělo by nám to chodit oběma směry.

Jak na práva – platí pro oba druhy ssh

Jediné, co je opravdu důležité – náš private klíč smí být čitelný pouze pro vlastníka, s těmito právy se také vyrobí. U zbytku obecně platí, že by nás jeho přečtením neměl nikdo ohrozit, ale přesto čím méně toho bude čitelného, tím lépe. Záleží ovšem na konfiguraci sítě a jejích paranoidních mechanismech, např. NFS a jiné zrůdné síťové filesystémy neumožňují číst z homu pred nalogováním (což ostatně není uplně nerozumné) a mohou tedy způsobit, že klíče nemůžete použít, pokud není přiměřená množina filů na cílovém stroji veřejně (nebo alespoň pro toho, pod kým běží sshd daemon) čitelná. Ještě perverznější síťové filesystémy dokonce mountují home až pri nalogování, tam nemáme šanci vůbec :(.

Pokud jste si jisti, že s žádnými síťovými filesystémy nemáte na žádné straně co do činění, bezostyšně dejte chmod 700 ~/.ssh* a dál se o to nestarejte. Ale pokud vám to poté nebude chodit, zkuste nejdřív změnit práva, často tam ten pes zakopaný je. V těchto zapeklitých případech je třeba mít (na serveru) 711 na home, 711 na adresáře ~/.ssh* a v nich (if OpenSSH) chmod 644 authorized_ke­ys, resp. (if SSH) chmod 644 pub authorization. Zkontrolujte pro jistotu, zda máte 600 id_dsa, resp. jmeno@private.klice a identification. Soubor random_seed by asi také čitelný být neměl, u known_kosts, resp. hostkeys/, je to asi úplně jedno. Pokud provozujete síťový filesystém s ACLky, je třeba se pohrabat také v nich.

Zastávka u protokolu 1

SSH verze, kterou mám já (3.2.0), vůbec výrobu klíčů pro protokol 1 neumožňuje, každopádně neexistuje jediný důvod, proč by vám to mělo chybet. Pokud z nějakého důvodu strašně toužíte po jedničkových klíčích v OpenSSH, musíte dát ssh-keygen -t rsa1, poté se vám nevytvoří id_dsa, ale identity + identity.pub. Další operace s těmito soubory jsou úplně stejné jako u ssh-dvojkových klíčů, takže se k tomu nebudeme nedejbože vracet :).

Troubleshooting

Nejde vám to? Buď se vás to vůbec nezeptá na passphrazi, nebo se vás to zeptá, dáte ji správně, ale potom se to ptá ještě na heslo? Ještě zajímavější je, když si takhle vytvoříte úplný klíčový graf mezi N stroji a odněkud někam to funguje, jinde zase ne…:) Tady je vhodné si nejprve udělat přehlednou tabulku, odkud kam to chodí, případně za jakých okolností (parametr –2, bez parametru apod.), to snadno pomůže vystopovat alespoň místo, kde je asi chyba.

Řekněme, že ze stroje krtecek na stroj pikatchu to nechodí. Aby to nevypadalo, ze z vás chci dělat BFUnesní windowsáře – téměř všechny níže popsané problémy mě uz potkaly :)

Ověřte si nejprve (ssh -V), zda máte na obou strojích stejné (OpenSSH nebo SSH) ssh přiměřených verzí. Pokud je jedna z nich výrazně starší, případně jsou obsoletní obě, proveďte upgrade nebo k němu někoho přinuťte :). Tento krok můžete vynechat, je-li zdrojový a cílový stroj totožný :). Mimochodem na OpenSSH 3.1p1 (mimo jiné default RedHatu 7.3) mi klíče občas chodí lokálně, ale ne zvenku, nepátrala jsem po tom, proč to tak je, prostě je potřeba OpenSSH updatnout :).
Nezapomněli jste na parametr –2 (příp. –1) [týka se OpenSSH]? Každý stroj má defaultní konfiguraci jinou, takže někde tento parametr potřebujete, někde ne. Přidáním aliasu ‚ssh‘=‚ssh –2‘ do .profilu (či úpravou config filu, viz někdy příště) nic nezkazíte. Zkuste na pikatchuovi změnit práva ~/.ssh* (nezapomeňte i na home) směrem k čitelnosti (čeho přesně, viz výše), práva na krtečkovi nemají vliv.
Pořád nic?
Zkontrolujte, jestli je ve všech souborech opravdu to, co v nich má byt, mně se ze začátku často pletly private a public klíče, mohli jste si omylem přepsat soubory stejných jmen apod. OpenSSH – je na krtečkovi id_dsa a id_dsa.pub? Je kopie id_dsa.pub umístěna na pikatchuovi v souboru authorized_keys (a nemáte starou verzi OpenSSH, která vyžaduje authorized_keys2)? Je tento soubor (i tranzitivně) čitelný? SSH (tady se to poplete daleko spíš) – jsou na krtečkovi klic.z.krtecka a klic.z.krtecka.pub? Je klic.z.krtecka uveden jako IdKey v souboru identification? Je na pikatchuovi klic.z.krtecka.pub a je uveden jako jako Key v souboru authorization? Jsou authorization a klic.z.krtecka.pub čitelné (i tranzitivně)? A (veeelmi oblíbená chyba :)) – není překlep v názvech souborů identification a authorization? :)
V této fázi můžete ještě zkusit debugovat konexi pomocí ssh -v, máte-li na pikatchuovi roota, podívat se do /var/log/secure, a nebo se zeptat admina pikatchua, jestli tam fakt neprovozuje nejaký pochybný filesystém (odpověď bude většinou ano :)).

Pokud budete mít nějaký problém (nebo už z dřívějška víte o něčem, co dělá problémy), šup s tím do diskuse.

Příště si povíme, jak používat klíče mezi OpenSSH a SSH, a podle toho, kolik zbyde místa, tak možná i něco dalšího :)

Extra special thanx to: Lace, Qiq

ict ve školství 24

Domácí úkol: Jak už jsem psala výše, kdo uhodne pravou identitu testovacích strojů, dostane lízátko. Je tředa buď uhodnout všechny čtyři bez zdůvodnění, nebo alespoň jeden se zdůvodněním (v tomto i předchozím dílu je sem tam rozsetá nějaká ta stopa, jsou zde ovšem stopy i falešné :)).

Domácí úkol č. 2: Vraťme se k minulému dílu. Mezitím jsem si uvědomila, že jsem se zapomněla zmínit o tom, že problémy s public klíčem stroje a nutnost ho opakovaně mazat může způsobovat i to, když se připojujeme na různé porty daného stroje, které jsou protunelované na nějaké ssh skrz maškarádu. SSH si u klíčů ukládá vedle adresy stroje i port, ale OpenSSH ne. Ví někdo, jak tohle řešit?