Používání klíčů v OpenSSH

1. 6. 2011
Doba čtení: 6 minut

Sdílet

Každý správný linuxák jistě zná a používá program SSH. Jeho primárním účelem je šifrované terminálové spojení na vzdálený UNIXový systém. Nabízí toho ale mnohem víc. V tomto seriálu si postupně představíme různé zajímavé možnosti balíku OpenSSH, který je nejpoužívanější implementací SSH protokolu.

Jak funguje SSH

Protokol SSH vytváří šifrované spojení mezi dvěma uzly, serverem a klientem. Takové spojení umí vytvořit po libovolném spolehlivém proudovém médiu. Této definici přesně odpovídá protokol TCP, ale stejně dobře by vyhověla i obyčejná sériová linka.

Při pokusu o navázání spojení proběhne nejprve výměna klíče. Ta u SSH verze 2 používá algoritmus Diffie-Hellman, který umožňuje libovolné množině uzlů vypočítat společný klíč, aniž by mezi těmito uzly musel předem existovat bezpečný kanál. Takto získaný klíč je použit pro symetrickou šifru, například 3DES nebo AES, pomocí které je šifrována veškerá další komunikace.

Když je šifrované spojení navázáno, zbývá poslední „drobnost“. Jednotlivé strany by si měly navzájem prokázat svoji totožnost, aby měly jistotu, že nedochází k útoku typu Man-in-the-Middle. O prokazování totožnosti serveru bude řeč v některém z příštích dílů, zabývejme se tedy prozatím prokazováním totožnosti klienta.

Autentizace heslem, klávesnicí

Jako nejednodušší se jeví možnost přihlásit se heslem. Šifrované spojení máme navázáno, nemusíme se tedy bát poslat serveru zprávu: „Chtěl bych se přihlásit jako uživatel pepa s heslem lokomotivaT3.“ Přesně tak funguje autentizace heslem. Kromě zřejmé nevýhody, že pepa musí při každém přihlášení vypisovat heslo, je tu ještě druhá nevýhoda, totiž že to samé může vytrvale zkoušet libovolný útočník. Máte-li SSH server na veřejné IP adrese, uvidíte takových marných pokusů v logu opravdu hodně.

Drobnou modifikací autentizace heslem je interaktivní autentizace klávesnicí (keyboard-interactive authentication). Liší se je v tom, že server může s klientem, potažmo s uživatelem, vést libovolně dlouhý rozhovor, například:

<klient> Rád bych se přihlásil jako pepa.
<server> Ahoj pepo, zadej prosím na svém kalkulátoru 123456.
<klient> Vyšlo mi 56789.
<server> V pořádku, jsi přihlášen.

Použití uživatelských klíčů

Namísto posílání hesla se klient může představit elektronickým podpisem. Nejprve si vygeneruje dvojici asymetrických klíčů, soukromý a veřejný. Poté sdělí serveru prostou zprávu: „Rád bych se přihlásil jako pepa.“ K této zprávě připojí svůj veřejný klíč a celou zprávu podepíše, tedy připojí hash zprávy, zašifrovaný svým soukromým klíčem. Server ověří platnost podpisu proti veřejnému klíči, který je součástí zprávy a pokud je v pořádku, zkontroluje, zda má pepa uveden v seznamu autorizovaných SSH klíčů veřejný klíč, kterým byla zpráva podepsána. Pokud ano, je přihlášení úspěšné.

Chceme-li začít SSH klíče používat, musíme nejprve vygenerovat pár klíčů. Než k tomu ale dojde, je třeba rozhodnout, jaký šifrovací algoritmus zvolíme. Od verze OpenSSH 5.7 máme na výběr kromě tradičních algoritmů DSA a RSA také nový algoritmus ECDSA, který má mít proti DSA větší účinnost při stejné délce klíče. Vytvořme tedy například DSA klíč o délce 1024 bitů:

$ ssh-keygen -t dsa -b 1024 -C uzivatel@stanice

Program se doptá název a umístění souboru s privátním klíčem a nepovinné heslo k zašifrování privátního klíče. Parametr -C určuje komentář klíče. Protože ve výchozím nastavení obsahuje jen cestu k souboru s klíčem, je vhodné jej přenastavit na nějaký smysluplnější ob­sah.

Obsah souboru s veřejným klíčem nyní musíme předat na server do souboru ~/.ssh/authori­zed_keys. To můžeme udělat buď ručně, nebo jednodušeji pomocí utilitky, která je součástí OpenSSH:

$ ssh-copy-id uzivatel@server

Při příštím pokusu o přihlášení by mělo přihlášení proběhnout pomocí klíče. Pokud server klíč stále odmítá, nejčastější příčinou jsou špatně nastavená práva k souborům. Opravíme je zadáním na serveru:

$ chmod go-w ~ ~/.ssh ~/.ssh/authorized_keys

SSH agent

Použití SSH klíče přináší větší bezpečí – můžeme vypnout autentizaci heslem a případný útočník nemá šanci hádat hesla. Z hlediska uživatelského komfortu je ale srovnatelné. Pouze místo hesla k serveru píšeme heslo k privátnímu klíči. Alternativa v podobě nezašifrovaného SSH klíče je zase velmi riskantní – takový klíč může lehce ukrást třeba zlomyslná webová stránka. SSH agent nabízí rozumný kompromis. Je to program, který slouží jako schránka pro bezpečné uložení klíčů v operační paměti. Do agenta nahrajeme svůj privátní klíč a následně jej necháme, aby vyřizoval všechny požadavky o vytvoření elektronického podpisu. Dokud agent běží, je v operační paměti počítače uložen privátní SSH klíč v nešifrované podobě. Agent je však navržen tak, aby za žádných okolností privátní klíč nevyzradil, je tedy na operačním systému a hardware počítače, aby jiným procesům znemožnil přístup do paměťového prostoru agenta.

Práci s agentem zahájíme tím, že zkontrolujeme, zda nám nějaký agent náhodou neběží. To zjistíme z obsahu proměnné prostředí SSH_AUTH_SOCK:

$ echo $SSH_AUTH_SOCK

Proměnná obsahuje cestu k UNIXovému soketu, kterým do agenta nahráváme klíče i požadavky k podpisu. Pokud agent neběží, spustíme jej takto:

$ eval $(ssh-agent)
Agent pid 10136

Co se stalo? Agent se spustil, otevřel unixový soket a přešel na pozadí. Ještě před tím vypsal na standardní výstup příkazy pro nastavení prostředí, které vyhodnotil příkaz eval:

SSH_AUTH_SOCK=/tmp/ssh-RjTIGZI10380/agent.10380; export SSH_AUTH_SOCK;
SSH_AGENT_PID=10381; export SSH_AGENT_PID;
echo Agent pid 10381;

Agent nyní běží, ale neobsahuje žádné klíče. Pro správu klíčů v agentovi slouží příkaz ssh-add. Spuštěný bez parametrů přidá do agenta klíče ze standardních cest ~/.ssh/id_{rsa­,dsa,ecdsa}, tedy za předpokladu, že zadáme správně heslo k rozšifrování soukromého klíče. Od této chvíle můžeme používat SSH zcela bez psaní hesel. Kdykoli SSH bude potřebovat prokázat se klíčem, požádá SSH agenta, který vygeneruje a obratem vrátí příslušný podpis.

Ve standardním nastavení zůstane klíč v agentovi neomezenou dobu. Toto chování můžeme v zájmu zvýšení bezpečnosti změnit, třeba na osm hodin, parametrem -t 8h, který můžeme zadat jak příkazu ssh-add, tak i samotnému SSH agentovi.

Příkazem ssh-add -l můžeme kdykoli vypsat seznam klíčů, které jsou aktuálně načteny v agentovi, při použití přepínače -L bude výpis ve formátu, který je přímo vhodný pro vložení do souboru authorized_keys. Přesně tak také funguje utilitka ssh-copy-id, pokud zjistí, že agent běží.

Automatické spouštění agenta

S agenty je potíž. Některé distribuce je spouštějí automaticky, jiné nikoli. Opustíme-li prostředí, ve kterém je definována proměnná SSH_AUTH_SOCK, agent se stane nepoužitelným, přestože stále běží a mohou v něm být i nahrány klíče. Takový případ nastává, například pokud spouštíme agenta při spuštění desktopového prostředí a toto prostředí poté násilím ukončíme. Také pokud spustíme agenta v prostředí, kde už nějaký běží, jsou proměnné přepsány novým a spojení ke starému je zahozeno.

bitcoin školení listopad 24

Řešení problému je přitom jednoduché, před spuštěním agenta ověřit, zda už nějaký neběží, a pokud ano, připojit se k němu. Přesně k tomuto účelu vznikl v distribuci Gentoo skript Keychain, který je dostatečně obecný, aby jej bylo možné používat i na jiných distribucích. Mně osobně připadal takový skript příliš složitý, navíc se mi nelíbilo, že nectil přesměrovaného agenta (o něm bude řeč v následujícím díle), proto jsem napsal skript vlastní. Ten spouštím příkazem source /path/to/agent při každém přihlášení. Pokud je prostředí nastaveno, ať už přesměrovaným agentem, nebo proto, že spouštíme vnořený shell, nedělá nic. Pokud prostředí nastaveno není, pokusí se skript vyvolat jeho nastavení z proměnných, uložených v souboru. Teprve v případě, že agent, jehož proměnné jsou uloženy v souboru, již neběží, je nastartován nový.

Obsah příští části

Používání SSH klíčů je dobrý základ, rozhodně tím však možnosti OpenSSH nekončí. V příštím dílu se podíváme na to, jakými způsoby je možné OpenSSH použít k tunelování v podstatě libovolného provozu.

Autor článku

Ondřej Caletka vystudoval obor Telekomunikační technika na ČVUT a dnes pracuje ve vzdělávacím oddělení RIPE NCC, mezinárodní asociaci koordinující internetové sítě.