Linux E X P R E S

Facebook

SSH receptem na bezpečnost 2

Unixová roura je velmi mocným nástrojem a SSH ji dokonale podporuje. Díky tomu můžeme snadno odesílat výstup libovolného programu kamkoliv na síť, nebo naopak. Může se stát, že máme vypalovačku na jiném počítači než na tom, na kterém jsme připojeni a kvůli firemním pravidlům se takový počítač ani nemůže dostat na internet (třeba kvůli riziku vypalování warezu ve firmě). Nám, pokročilým uživatelům, nic takového nevadí.


Rourujeme

Unixová roura je velmi mocným nástrojem a SSH ji dokonale podporuje. Díky tomu můžeme snadno odesílat výstup libovolného programu kamkoliv na síť, nebo naopak. Může se stát, že máme vypalovačku na jiném počítači než na tom, na kterém jsme připojeni a kvůli firemním pravidlům se takový počítač ani nemůže dostat na internet (třeba kvůli riziku vypalování warezu ve firmě). Nám, pokročilým uživatelům, nic takového nevadí. A navíc díky šifrování a skutečnosti, že ISO nikam neuložíme, nezjistí náš správce, jinak milovník Debianu, že jsme si vypálili ISO distribuce CentoOS.

michal@localhost ~$ curl http://mirror.org/CentOS-4.2.ServerCD-i386.iso \\
| ssh vypalovacka "cdrecord -v speed=12 dev=0,0,0 fs=8m data -"

Směrování portů

Jak jsem již uvedl, tak SSH umí jen jedinou věc. Vytvořit šifrovaný a zabezpečený kanál, kterým mohou proudit data. Navíc je z hlediska oněch dat zcela transparentní, takže vyžaduje pouze minimální zásahy do systému. Směrování, nebo také tunelování (forwarding, tunneling) portů, je dalším využitím schopností SSH. Díky transparentnímu šifrování přenášených dat můžeme velmi jednoduše zabezpečit přenos samotných dat, tak i uživatelského hesla. Bohužel z hlediska aplikací není toto zabezpečení zcela transparentní, protože SSH pracuje na aplikační vrstvě modelu ISO/OSI a je nutné změnit číslo portu, na který se mají posílat data. Navíc pracuje výhradně s protokoly, které jsou založené na TCP, takže nelze použít pro protokoly vystavené na UDP (NFS, DNS, DHCP) a už vůbec ne nad těmi, které nejsou založeny na IP.

Lokální směrování

ssh -L1430:localhost:143 uzivatel@server_domena_com

Argument -L říká klientovi, že používáte lokální směrování, 1430 je místní port, 143 je adresa portu na serveru, kam bude směrován provoz z portu 1430 klienta. 143 je standardní port, na kterém naslouchá služba IMAP, takže posledním krokem je nastavení poštovního klientu tak, aby místo na server,143 poslouchal na localhost,1430.

  1. Poštovní klient se připojí na localhost,1430.
  2. SSH data zašifruje a tunelem odešle na server.
  3. Tam čeká sshd, který data rozšifruje a předá IMAP démonu.
  4. Odpověď běží stejnou cestou.

Vzdálené směrování

ssh -R1430:localhost:143 michal@mujpocitac_doma_com

Argument -R říká klientovi, že používáme vzdálené směrování, 1430 je adresa vzdáleného portu, který bude směrován na lokální port 143. Toto je používané v případě, že chceme, aby se klienti k serveru připojili zabezpečeným tunelem pomocí SSH.

  1. Poštovní klient na počítači mujpocitac se připojí na localhost,2001.
  2. SSH data zašifruje a odešle na server.
  3. Na serveru se data rozšifrují a přidají na port 143.
  4. Odpověď běží stejnou cestou.

Místní versus vzdálené připojení

Rozdíly mezi místním a vzdáleným směrováním nemusí být na první pohled zřejmé. Pokaždé zde máme dvojici SSH serverů a SSH klientů, přes něž jde tunel. Důležité je vědět, která strana připojení naslouchá a která strana iniciuje připojení. Označme místní počítač písmenem M a vzdálený server S. Místní připojení je tedy takové, které iniciuje M k serveru S. Vzdálené je takové, které iniciuje server S k místnímu počítači M.

# mistni pripojeni z (localhost,mistni_port) -> (S,vzdaleny_port)
# jsme na mujpocitac.doma.com
ssh -Lmistni_port:localhost:vzdaleny_port S
# vzdalene pripojeni z (localhost,mistni_port) -> (M,vzdaleny_port)
# jsme na server.domena.com
ssh -Rvzdaleny_port:localhost:mistni_port M

Zatím jsme pořád na místě druhého parametru psali localhost. To není úplně nutné, protože je možné sem napsat libovolnou jinou adresu. Ale z bezpečnostních důvodů to není dobré, protože relace mezi serverem a klientem potom poběží cestou server -> (TCP) -> ssh_klient -> (ssh) -> ssh_server -> (TCP) -> klient. Taková relace potom spotřebuje celkem tři TCP připojení a zabezpečeně se data přenáší pouze část cesty!

Směrování protokolu X11

SSH obsahuje speciální podporu pro směrování protokolu X11. Na unixových pracovních stanicích se stal X Window System standardem pro grafické aplikace. Mezi jeho vlastnosti patří i podpora sítí, X server a X klient nemusí běžet na stejném počítači a protokol X11 se postará o všechny záležitosti sám. Jak již jistě tušíte, X11 protokol se datuje do stejných časů jako protokoly FTP nebo telnet. To znamená do časů, kdy se správci snažili počítače propojit tak, aby spolu vůbec komunikovaly a bezpečnost byla tou poslední věcí, kterou řešili. Ano, ani protokol X11 není bezpečný a navíc v jistých situacích vyžaduje více TCP spojení, a proto je jeho zabezpečení i přes SSH komplikované.

Základním prvkem v X je entita displej, což je obrazovka, kterou spravuje X server. Klienti potom potřebují vědět, ke kterém displeji se mají připojit. To zjistí jednak z obsahu proměnné DISPLAY, anebo může být použitý displej zadán explicitně na příkazovém řádku. Formát proměnné je x_server:cislo_displeje.cislo_zobrazeni, kde

  1. x_server je adresa počítače, na kterém běží X server a kam se bude vykreslovat grafika;
  2. cislo_displeje je číslo fyzického displeje, X server umožňuje obsluhu více zobrazovacích zařízení;
  3. cislo_zobrazeni je číslo virtuálního displeje, X server umožňuje, aby na jednom fyzickém displeji bylo více virtuálních.

Materiály, které se zabývají vzdáleným přihlašováním pomocí X11, na tomto místě začnou hovořit o nástrojích xauth, nebo MIT-MAGIC-COOKIE-1 a souboru ~/.Xauthority. Naštěstí díky SSH můžeme podobné nástroje svěřit minulosti, protože SSH se postará jak o bezpečný přenos dat, tak i o silnou autentizaci, takže nemusíme studovat nástroje, které poskytuje samotný X Window. Dokonce ani nemusíme nastavovat proměnnou DISPLAY, také o to se SSH postará samo.

Samotné směrování funguje následovně. Je důležité podotknout, že předpokládáme, že jak vzdálený server, tak i klient SSH mají směrování protokolu zapnuto. Klient zažádá o směrování protokolu X11. Démon SSH během přihlašování, mimo autentizace a obsluhy terminálové relace, ještě vytvoří X server a ve vzdáleném shellu nastaví DISPLAY tak, aby ukazovala právě na tohoto zástupce.

michal@localhost ~$ ssh uzivatel@server_domena_com
uzivatel@server_domena_com's password:
Last login: Mon Mar 27 16:31:51 2006 from gateway.isp.com
uzivatel@server:~$ echo $DISPLAY
localhost:15.0
uzivatel@server:~$ xclock &

Proměnná DISPLAY ukazuje na zástupný displej, který vytvořil SSH server. Je jasné, že podobný displej na serveru vůbec neexistuje, ale to není podstatné. Důležité je, že se server SSH chová jako skutečný X server, takže z pohledu aplikace xclock to vypadá stejně, jako když byla spuštěná lokálně. Protokol X11 se tedy přenáší pomocí relace SSH ke klientovi, který se zase tváří jako X11 klient a posílá lokálnímu serveru příkazy, které vyvolal xclock. Daný příklad tedy spustí na lokálním stroji hodiny, které ovšem běží na vzdáleném serveru.

Komprese dat v SSH

Především při směrování X11 se vyplatí komprimovat přenášená data, což SSH také umí, používá stejný algoritmus jako gzip. Komprese probíhá ještě před vlastním šifrováním, takže může v jistých případech zrychlit celý přenos. Důležité je nastavit takové hodnoty, které zrychlí přenos, ale vlastní kompresní režie nebude celkový čas naopak prodlužovat. Komprese se zapíná parametrem -C, standardně je vypnuta. Její velikost můžeme nastavit číslem od 0 (žádná komprese) do 9 (maximální stupeň), ale nedá se nastavit přímo z příkazového řádku; musí být zapsána v konfiguračním souboru ~/.ssh/config. Pro tento soubor platí přísná bezpečnostní pravidla, smí jej číst a modifikovat pouze vlastník, skupina ani ostatní žádná práva mít nesmí.

# Povolení komprese
Compression yes
# Nastavení stupně komprese
CompressionLevel 4

Klíče a ssh-agent

Pokud jste si zkoušeli všechny příklady, určitě vás unavovalo věčné zadávání hesla. Máte štěstí, SSH podporuje mnoho různých způsobů autentizace.

  • Heslem – základní zabezpečení, které závisí na znalosti hesla.
  • Veřejným klíčem – ověřená prostřednictvím kryptografických klíčů. Bezpečnější než přihlašování heslem.
  • Rhosts – podle důvěryhodných hostitelů, povoluje připojení na základě adresy hostitelského počítače. Nepovažuje se za bezpečné.
  • RhostsRSA – varianta předcházejícího, hostitelé se navíc musí autorizovat kryptografickým klíčem RSA.
  • Kerberos – MIT-Kerberos je silný systém pro autentifikaci uživatelů. Ovšem pro menší sítě je nevhodný, protože vyžaduje speciální server s identitami.
  • Ostatní způsoby – SSH podporuje další způsoby jako například SecurID, S/Key, PAM a podobně.

Většina způsobů jde mimo rámec tohoto článku, ale právě veřejné klíče jsou tím, co nás zajímá. Jistou nevýhodou autorizací heslem je skutečnost, že se v případě útoku man-in-the-middle útočník ono heslo dozví. Navíc veřejné klíče ve spolupráci s programem ssh-agent umožní velmi příjemnou věc, automatické a bezpečné přihlášení pomocí SSH, a to bez hesla!

Klíče

V reálném životě je klíč malý kovový předmět, jehož výstupky jsou unikátní a musí zapadat do zámku, čímž vlastně provedeme autentizaci a dveře se otevřou. Ve vašem virtuálním životě klíče zajišťují stejnou věc, oznamují serveru „To jsem skutečně já“. Ovšem na rozdíl od přesně opracovaného kousku kovu se tu používá matematický aparát a kryptografie, přesněji asymetrické šifrování.

Váš klíč je rozdělen na dvě části, soukromou (což musí být vaším pečlivě střeženým tajemstvím) a veřejnou, ze které se nedá soukromý klíč odvodit. Tento klíč si zkopírujeme na všechny servery, na které se chceme přihlásit. Klient SSH a server SSH potom provedou kryptografické ověření shody soukromého a veřejného klíče, přičemž je podstatné, že soukromý klíč v žádném případě není přenášen přes síť.

Při vlastním přenosu je server požádán klientem o připojení určitého uživatele. Server pošle výzvu, což je jistá posloupnost dat, kterou žádá klienta, aby prokázal svoji identitu. Klient data výzvy zašifruje pomocí privátního klíče a odešle serveru odpověď. Ten ji rozšifruje pomocí veřejného klíče a pokud je vše v pořádku, povolí přihlášení. Podstatné je, že bez znalosti soukromého klíče není možné výzvu správně zašifrovat.

Generování klíčů programem ssh-keygen

Příkazem ssh-keygen -t rsa (-t dsa) si vygenerujeme dvojici klíčů RSA (DSA). Důležitým pojmem je passphrase, což je heslo, kterým se rozšifruje uložený soukromý klíč. Je vhodné, aby tato fráze byla bezpečná a já doporučuji využít služeb programu apg(1) – Advanced Password Generator, který umožňuje navíc generovaná hesla kontrolovat pomocí cracklib.

michal@localhost ~ $ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/michal/.ssh/id_rsa):
Created directory '/home/michal/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/michal/.ssh/id_rsa.
Your public key has been saved in /home/michal/.ssh/id_rsa.pub.
The key fingerprint is:
18:43:56:11:2c:01:59:02:61:34:d7:ac:c6:2c:37:6b michal@localhost

Právě jsme vygenerovali dvojici klíčů, které jsou uloženy v souborech ~/.ssh/id_rsa (soukromá část) a ~/.ssh/id_rsa.pub (veřejná část) a navíc je soukromá část chráněná pomocí passphrase. Veřejný klíč musíme uložit na server, což provedeme třeba takto

michal@localhost ~ $ scp .ssh/id_rsa.pub server:~/.ssh/id.michal
uzivatel@server_domena_com's password:
michal@localhost ~ $ ssh uzivatel@server_domena_com \\
“mkdir -p .ssh; chmod 0700 .ssh; \\
cat ~/.ssh/id.michal >> ~/.ssh/authorized_keys2“
uzivatel@server_domena_com's password:

Při dalším přihlášení vás již přivítá výzva:

michal@localhost ~ $ ssh uzivatel@server_domena_com
Enter passphrase for RSA key 'michal ':
Last login: Mon Mar 27 19:01:27 2006 from gateway.isp.com
uzivatel@server:~$

Automatické přihlášení pomocí ssh-agent

Bohužel málo koho přesvědčíte k tomu, aby místo relativně krátkého hesla zadával delší passphrase. Ale naštěstí SSH poskytuje způsob, jak to odstranit. Jednak můžeme zvolit prázdnou passphrase, ale to není moc bezpečné. Mnohem lepší je využít služeb ssh-agenta. Ten se zavede do paměti a v okamžiku, kdy SSH potřebuje rozšifrovat privátní klíč, zeptá se agenta. Ten načte zašifrovaný klíč, pomocí passphrase jej rozšifruje a výsledek opět vrátí SSH. Důležité je, že passphrase nikdy neopustí počítač a dokonce ani samotného ssh-agenta.

Bohužel samotné spuštění agenta není triviální. Jako nejlepší metoda se mi osvědčilo přidat do startovacího skriptu (např. ~/.bashrc) následující příkaz: ssh-agent $SHELL .

Poté již všechny procesy SSH již budou potomky tohoto ssh-agenta, který nastaví odpovídající systémové proměnné. Pokud vás zajímá jaké, spusťte toto

michal@localhost ~ $ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-QAeWx15806/agent.15806; export SSH_AUTH_SOCK;
SSH_AGENT_PID=15807; export SSH_AGENT_PID;
echo Agent pid 15807;

Alternativním způsobem spuštění je tedy příkaz: eval `ssh-agent` .

Pokud pracujeme v grafickém režimu, bývá nejlepší spouštět ssh-agent již při startu X serveru. Proto je dobré spuštění napsat do souboru /etc/X11/xinit/xinitrc, anebo do ~/.xinitrc. Každá distribuce má trochu jiné startovací skripty X serveru, ale ve všech bývá řádek jako exec /bin/sh "$HOME/.xinitrc". A ten změňte na

exec /usr/bin/ssh-agent '/bin/sh "$HOME/.xinitrc"'

Nevýhodou je, že se při pádu ssh-agenta musíte odhlásit z X serveru a znovu přihlásit. Když jsme ve fázi, kdy jsme úspěšně spustili ssh-agenta, můžeme do něj zavést passphrase. K tomu slouží program ssh-add:

michal@localhost ~ $ ssh-add
Enter passphrase for /home/michal/.ssh/id_rsa:
Identity added: /home/michal/.ssh/id_rsa (/home/michal/.ssh/id_rsa)

Od této chvíle už nemusíme programu ssh (ani scp, sftp) zadávat heslo. Agent a klíče provedou bezpečné přihlašování s minimem námahy. Také jsme vyřešili problém používání SSH ve skriptech a v cronu.

michal@localhost ~ $ ssh uzivatel@server_domena_com
Last login: Mon Mar 27 21:43:11 2006 from gateway.isp.com
uzivatel@server:~$

Navíc agent umí další skvělou věc, a to je směrování. Pokud to mají klienty a servery povolené, můžeme se snadno přihlásit ze serveru na další server, přičemž identitu ověří agent na lokálním počítači. Pouze je nutné, aby další server měl uloženou kopii veřejného klíče.

uzivatel@server:~$ ssh novy-server
uzivatel@novy-server~$

Závěrem

Představili jsme si SSH a možnosti jeho použití. Navzdory délce tohoto článku jsme vynechali mnoho věcí, jako jsou hashovací algoritmy, algoritmy RSA/DSA pro technologii klíčů, různé šifrovací metody jako 3DES, Blowfish, RC4 a podobně. Rovněž jsme se nezabývali nastavením SSH klienta a serveru. Ale doufám, že jsem vám SSH představil jako velice silný, bezpečný a snadno použitelný (což se někdy neslučuje s bezpečným) nástroj pro vzdálenou komunikaci po internetu. SSH samozřejmě není jediná použitelná metoda a třeba pro ochranu FTP protokolu jej není možné vůbec použít. Velká slabina i při používání klíčů je v jejich distribuci, což samotné SSH neumí a ani nemůže řešit, pokud má být pořád oním jednoduchým nástrojem. Ale díky podpoře různých způsobů autentifikace můžeme používat SSH třeba ve spolupráci s MIT-Kerberos, který mimo jiné řeší i problém neustálého kopírování veřejných klíčů.

Diskuze (0) Nahoru