SSH --- Secure shell
-=-=-=-=-=-=-=-=-=-=-=
Nearly every complex solution to a programming problem that I have
looked at carefully has turned out to be wrong.
-- Brent Welch
Jan Pazdziora, 7. března 1998
Secure shell slouží k přihlašování na vzdálený počítač po síti
a k přenosu dat. Od počátku je stavěn tak, aby umožnil bezpečnou
komunikaci po nedůvěryhodné síti pomocí šifrování a zabezpečil
vzájemnou autentizaci strojů i uživatelů.
Možnosti jeho nasazení
Secure shell můžeme použít místo programů telnet či rlogin
k interaktivnímu přihlášení na vzdálený stroj. Přitom je snadné
přenášet vytvořeným kryptovaným kanálem i X protokol spuštěných
programů pro X-Window System. Je také možné spustit na vzdáleném
počítači příkaz, kterému předáme na standardním vstupu data a z
výstupu převezmeme výsledek (obdoba rsh). Program scp, Secure copy,
je pak bezpečnou variantou rcp. Secure shell má ale mnohem více
možností, jak zadat, co který uživatel smí provést, a dokáže
například i kryptovaně forwardovat porty mezi stroji.
Na strojích, na jejichž bezpečnosti nám opravdu záleží,
je vhodné všechny možnosti vzdáleného přístupu kromě ssh zakázat,
donutíme tak uživatele (včetně superuživatele) používat výhradně
bezpečné spojení.
Verze pro systémy UNIX jsou free včetně zdrojových textů
pro nekomerční použití (i nekomerční použití v komerčních
firmách). Domovská stránka ssh s distribucí je na adrese
http://www.cs.hut.fi/ssh, na síti TEN-34 CZ je mirror na adrese
http://www.fi.muni.cz/ftp/pub/ssh obsahující mimo jiné i rpm balíky
od Yenyi Kasprzaka. Pro systémy z produkce společnosti Microsoft
existují komerční verze, více informací naleznete na adrese
http://www.datafellows.com/
Stabilní distribuce v době psaní tohoto článku má číslo verze
1.2.22.
Architektura klient--server
Abychom se mohli na vzdálený počítač pomocí ssh připojit,
musí na něm běžet sshd, Secure shell daemon. Tento daemon přijímá
požadavky, testuje jejich oprávněnost z hlediska identity stroje
i uživatele, a v případě úspěchu vytvoří kryptované spojení
požadovaného typu. Na straně klientské pak potřebujeme klienta,
program ssh, kterému parametry zadáme, kam a jaké spojení chceme
vytvořit.
Každý stroj, na kterém běží sshd, má vygenerovanou
dvojici RSA klíčů, které ho identifikují (/etc/ssh_host_key a
/etc/ssh_host_key.pub). Při startu daemona (typicky z rc skriptů při
bootu systému) daemon vygeneruje ještě klíč serveru, který posléze
mění každou hodinu.
Klient, který žádá server o spojení, obdrží od serveru
veřejný klíč stroje i serveru. Veřejné klíče strojů, se kterými
jsme už v minulosti komunikovali, jsou ukládány do souboru
/.ssh/known_hosts, případně správcem do /etc/ssh_known_hosts,
a při každém dalším přihlášení se ověřuje, zda se identifikace
vzdáleného stroje nezměnila. To by mohlo znamenat, že se někdo
snaží spojení odposlouchávat a vydává se za námi zamýšlený stroj
man-in-the-middle attack). V našem méně nepřátelském světě k
odmítnutí spojení z tohoto důvodu dochází typicky po reinstalaci
počítače -- řešením pak je po ověření situace odstranit veřejný klíč
vzdáleného stroje z lokální databáze known_hosts.
Klient po získání klíčů vygeneruje 256 bitový klíč (session
key), který bude použit pro šifrování dalšího spojení symetrickým
šifrovacím algoritmem. Tento klíč zakryptuje veřejnými klíči
serveru a stroje, na kterém běží server, a pošle zpět. Server tedy
musí nejen poslat správný veřejný klíč stroje pro ověření proti
known_hosts na klientské straně, musí samozřejmě znát i svůj správný
tajný klíč, aby byl schopen klíč od klienta rozšifrovat.
Poté, co klient věří, že komunikuje s tím, s kým požadoval,
je na serveru, aby ověřil, že klient má právo se přihlásit, případně
provést žádanou akci.
Ssh podporuje z důvodu zpětné kompatibility autentizaci shodnou
či podobnou s rsh, pomocí souborů /etc/hosts.equiv a .rhosts, resp.
.shosts. Naštěstí se tento způsob dá v konfiguraci daemona zakázat
a je to více než doporučeníhodné. Použití ssh dává totiž uživateli
jistý pocit bezpečí, který je ale při povoleném přihlašování jen na
základě .rhosts více než pochybný.
Nejčastěji používanou autentizací je autentizace protokolem RSA
(kryptografie s veřejným klíčem). Při něm server zná veřejný klíč
uživatele, ten je uveden v souboru /.ssh/authorized_keys v domovském
adresáři uživatele na vzdáleném stroji. Kdo se chce přihlásit, musí
prokázat, že zná tajný klíč k tomuto veřejnému. Server na požadavek
ssh klienta vrátí tzv. challenge, náhodné číslo zašifrované veřejným
klíčem. Klient se pokusí ho rozšifrovat za použití tajného klíče,
který může být ještě chráněn dodatečným heslem, passphrase. Pokud
výsledek od klienta souhlasí, server přihlášení povolí a provede
požadovanou akci -- spustí interaktivní shell, provede příkaz.
Jako poslední šance je uživateli nabídnut prompt k zadání hesla;
pokud ani toto neuspěje, je spojení zrušeno.
Instalujeme sshd a ssh
Při instalaci si můžeme zvolit buď kompilaci ze zdrojových
textů ( ./configure && make && make install) nebo nainstalovat
předkompilovanou binární distribuci či rpm. Obě formy instalace
zajistí mj. i vygenerování dvojice klíčů stroje. Poté zkontrolujeme,
jestli nám vyhovuje standardní nastavení konfigurace ssh daemona
uvedené v /etc/sshd_config, zvláště co se týče povolených forem
autentizace či způsobu přihlašování. Pak již můžeme daemon spustit,
nejlépe z nějakého rc skriptu.
Od této chvíle můžeme se strojem, na kterém běží sshd, již
komunikovat bezpečným způsobem. I když totiž nemáme povolenou RSA
autentizaci, můžeme se přihlásit zadáním hesla.
Chceme-li využít RSA autentizaci, musíme na klientské straně,
odkud se budeme přihlašovat, vygenerovat dvojici tajného a veřejného
klíče. K tomu použijeme program ssh-keygen. Jsme vyzváni, abychom
zadali jméno souboru pro uložení tajného klíče, veřejný klíč je
uložen vedle něho s příponou .pub. Při generování klíče uživatele
akceptujeme nabídnuté /.ssh/identity. Soubor /.ssh/identity.pub pak
zkopírujeme do /.ssh/authorized_keys na straně serveru a případně
rozšíříme o požadované podmínky. A nyní již můžeme spustit
ssh jméno_serveru
Odpovědí by měl být prompt na vzdáleném stroji. Ověřit, zda
opravdu používáme RSA autentizaci, můžeme spuštěním ssh s volbou -v.
Správný výpis bude přibližně takovýto:
faethon: Server refused our rhosts authentication or host key.
faethon: No agent.
faethon: Trying RSA authentication with key 'adelton@faethon'
faethon: Received RSA challenge from server.
faethon: Sending response to host key RSA challenge.
faethon: Remote: RSA authentication accepted.
faethon: RSA authentication accepted by server.
Pokud se přihlašujeme na stroj, jehož veřejný klíč ještě
neznáme, ssh se nás zeptá
Host key not found from the list of known hosts.
Are you sure you want to continue connecting (yes/no)?
Musíme odpovědět celým yes a ssh pak přidá veřejný klíč do
našeho lokálního seznamu known_hosts.
Secure shell daemon můžeme spustit i na stroji, na kterém nemáme
superuživatelská práva. Musíme ho ale volbou na příkazové řádce nebo
v lokálním konfiguračním souboru spustit na neprivilegovaném portu
a na tento port pak směrovat klienty.
Autorizované klíče a různé identity
Při autentizaci protokolem RSA server testuje, zda klient
zná tajný klíč k veřejnému klíči ze souboru /.ssh/authorized_keys.
Na každém řádku je uveden jeden veřejný klíč, a s ním i podmínky
a akce, pro které platí. Můžeme například klauzulí from omezit
přihlašování jen z určitých strojů či domén, můžeme zakázat
forwardování portů či nastavit dobu nečinnosti, po které bude
spojení ukončeno. Pomocí command specifikujeme příkaz, který se při
spojení s odpovídajícím tajným klíčem provede. Pokud údaj command
není uveden, spustí se buď interaktivní shell, nebo příkaz vyžádaný
klientem.
Běžný uživatel bude mít ve svých authorized_keys pravděpodobně
převážně svoje klíče pro interaktivní přihlašování, naproti tomu
na superuživatelský účet můžeme chtít mít různě omezené přístupy
z různých strojů. Takto by mohl vypadat řádek, který dovolí
vlastníkovi tajného klíče provést backup části disku na vzdáleném
stroji:
from="pinosol",command="tar czf -- /export/data" 1024 37 \
5867...spousta číslic veřejného klíče
(vše uvedeno na jednom řádku). Všimněme si, že tento příkaz,
stažení taru s obsahem adresáře, může provést kdokoli, kdo má
odpovídající tajný klíč, nikoli nutně superuživatel. Při spuštění
ssh na klientské straně volbou -i zadáme jméno souboru se správným
tajným klíčem:
ssh -i /.ssh/backupuj root@bromhexin >> \
backup.'date +'%y%m%d''.tgz
Autorizovaný klíč pro stažení či zápis jednoho pevně daného
souboru či zatarování obsahu adresáře je korektním způsobem,
jak zajistit přenos dat mezi dvěma běžnými uživateli, pokud nám
nevyhovuje otevřenost HTTP protokolu. Nesdělujeme totiž cizímu
člověku ani heslo, ani tajný klíč k neomezenému přihlašování na náš
účet, zpřístupňujeme mu pouze přesně vymezená data.
Pokud máme povolený neomezený přístup (například RSA autentizací
na svůj účet na jiném stroji), můžeme příkaz pro provedení zadat
samozřejmě i lokálně:
ssh bromhexin 'tar cf -- /export/data' >> out.tar
V tomto případě se použije standardní identity.
Forwardování protokolu X11 a portů
Pokud se přihlašujeme z klienta s X-Window (je nastavena
proměnná prostředí DISPLAY) a server tuto vlastnost umožňuje, bude
spojení od X klientů spuštěných na serverové straně ssh směrováno
do kryptovaného kanálu a teprve na klientské straně ssh předáno X
serveru. Proměnná DISPLAY bude na vzdálené straně ssh nastavena na
vzdálený stroj, s číslem displeje vyšším, než na jaké jsme zvyklí (>
0). Tento displej je právě vzdálený konec ssh spojení.
Doporučeným způsobem, jak spustit na vzdáleném stroji aplikaci
pro X-Window, je použít na příkazovém řádku volbu -n:
ssh -n pinosol xterm &
která zabrání čtení standardního vstupu a dovolí spuštění {\tt
ssh} na pozadí. Pokud potřebujeme při přihlašování zadat heslo
nebo passphrase, využijeme volbu {\tt -f}, která přesune {\tt ssh}
na pozadí, ale až po úspěšně proběhnuté autentizaci a po vytvoření
spojení. Tak budeme mít prompt shellu na lokálním stroji opět
k dispozici:
ssh -f pinosol xterm
Forwardování protokolu X11 funguje v posledních verzích ssh
(1.2.20 a výše) bez větších problémů. Ve starších verzích docházelo
k zatuhnutí, pokud klient zažádal o přenos velkého množství dat,
tato chyba ale byla opravena. Jediné, co v oblasti X-Window
nefunguje, je forwardování rozšíření OpenGL/DGL společnosti SGI.
Kryptovaný ssh kanál můžeme využít i pro jiná data, následující
příklad ukazuje, jak kryptovaně namountovat Samba disk ze stroje
bromhexin na stroj pinosol:
ssh -L 1234:bromhexin:139 bromhexin
smbmount //pinosol/adelton mnt -p 1234 -c pinosol
První příkaz kryptovaně propojí Samba port 139 na vzdáleném
stroji s lokálním portem 1234. Druhý příkaz pak namountuje službu
dostupnou již na lokálním portu.
Secure copy, ssh agent
Příkaz scp je prodloužením běžného cp na přenosy souborů mezi
stroji: pokud před jméno souboru uvedeme jméno stroje a případně
i jméno uživatele, provede se vzdálený ssh přenos. scp se v případě
potřeby zeptá na heslo a umožní i kopírování mezi dvěma vzdálenými
počítači.
Abychom se vyhnuli opakovaného zadávání passphrase například
ke svému tajnému klíči, můžeme pomocí programů ssh-agent a ssh-add
uložit tajné klíče do paměti, a posléze je využít při přihlašování
pomocí ssh. Agenta spustíme například při přihlašování do X-Window
tak, aby všechny další procesy byly jeho potomky. Ty pak zdědí
spojení k němu a následné příkazy mohou využít jeho tajných klíčů.
Protože při startu X-Window systémů většinou ještě nemáme terminál,
na kterém by se ssh-add mohl zeptat, spouští se v takové situaci
jednoduchá aplikace ssh-askpass, od níž pak {\tt ssh-add} zadanou
passphrase převezme.
Distribuce veřejných klíčů
Secure shell je klient a server určitého protokolu, spolu
s obslužnými programy typu ssh-keygen. Protokol ale nedefinuje,
jakým způsobem si organizace či jednotlivci zajistí distribuci
potřebných veřejných klíčů či backupování klíčů tajných. Aby
ale usnadnili alespoň evidenci veřejných klíčů, zahrnuli autoři
v distribuci perlovský skript make-ssh-known-hosts, který podle
záznamů v nameserveru projde všechny stroje v doméně a pokusí se od
nich získat jejich veřejný ssh klíč. Výsledek je ve formě souboru
ssh_known_hosts a po jeho kontrole ho můžeme rovnou použít.
Na co dát pozor
Při přihlašování pomocí ssh je potřeba mít na paměti, že řetěz
je tak slabý jako jeho nejslabší článek. Ssh odstraňuje přenos
hesel v otevřené podobě, musíme ho ale používat důsledně: pokud se
nejprve přihlásíme telnetem a teprve dále pomocí ssh, jde po části
sítě otevřeně nejen heslo k prvnímu telnetu, ale i všechna případná
další.
Důležité soubory
/usr/local/bin/ssh, ssh-keygen, ssh-agent, ssh-add Klient,
generování klíčů, ssh agent
/etc/ssh_config /.ssh/config, /.ssh/identity,
/.ssh/identity.pub, /.ssh/authorized_keys
Standardní konfigurační soubor klienta, jeho lokální
konfigurační soubor, standardní identita uživatele (tajný a veřejný
klíč), seznam autorizovaných klíčů
/usr/local/sbin/sshd /etc/sshd_config, /etc/ssh_host_key,
/etc/ssh_host_key.pub Daemon, jeho konfigurační soubor, tajný a
veřejný klíč stroje
Konfigurační soubory mohou být na vaší lokální instalaci uloženy
místo adresáře /etc v /etc/ssh.
Závěr
Ukázali jsme, jak začít používat secure shell pro bezpečnější
komunikaci po počítačové síti. Nastínili jsme jeho filosofii
a uvedli několik příkladů. Uživatelé najdou podrobnější informace
v manuálové stránce ssh(1), správci by si měli přečíst sshd(8) a
samozřejmě i relevantní dokumentaci odtamtud odkazovanou.
Často kladené dotazy naleznete na adrese
http://www.uni-karlsruhe.de/ ig25/ssh-faq/ a o budoucnosti ssh
i netriviálních aplikacích je newsová skupina comp.security.ssh.
Za přípomínky a doplnění děkuji Petru Macháčkovi a Petru
Kolářovi.
výheň