Správa linuxového serveru: Praktické rady pro zabezpečení SSH

SSH je mocný nástroj a SSH server je obvykle také první věc, kterou správce na server instaluje. Jak jej ale zabezpečit proti častým útokům nebo proti případnému zneužití ze strany uživatelů serveru?

Proti čemu se bránit

Útoky na SSH můžeme rozdělit do dvou kategorií - útoky vnější a útoky vnitřní. Vnějším útokem je útok neoprávněného uživatele, někoho, kdo na serveru SSH účet nemá. Vnitřním útokem je útok oprávněného uživatele, který přístup k SSH má. Cílem obrany proti vnějšímu útoku je, aby útočník nebyl schopen získat přístup na server, ať již zkoušením často používaných slovníkových hesel nebo využitím nějaké zranitelnosti v SSH.

Cílem obrany proti vnitřnímu útočníkovi je nastavit oprávnění tak, aby byl daný uživatelský účet schopen provádět vše, co uživatel požaduje, ale současně aby minimalizoval dopad případného útoku (ten útok samozřejmě nemusí být iniciován daným uživatelem, ale i útočníkem, který zcizí jeho přihlašovací údaje nebo se mu je podaří uhádnout). V tomto dílu "nakousnu" převážně zabezpečení SSH serveru proti vnějšímu útočníkovi.

Útoky na SSH

Nejčastější útoky na SSH provádí automatizované nástroje, které prohledávají určitý rozsah IP adres, hledají SSH server (většinou pouze na standardním portu) a pokud ho najdou, zkouší nejtypičtější kombinace uživatelských jmen a hesel ve snaze získat přístup přes nezabezpečený účet. Pokud SSH server nenajdou, tak jdou o dům dál. Tuto aktivitu poznáte velice snadno nahlédnutím do logu:

auth.log:May 10 14:14:22 hyperion sshd[8182]: Invalid user test from 218.56.61.114
auth.log:May 10 14:14:27 hyperion sshd[8216]: Invalid user guest from 218.56.61.114
auth.log:May 10 14:14:31 hyperion sshd[8254]: Invalid user admin from 218.56.61.114
auth.log:May 10 14:14:40 hyperion sshd[8328]: Invalid user admin from 218.56.61.114
auth.log:May 10 14:14:44 hyperion sshd[8362]: Invalid user user from 218.56.61.114
auth.log:May 10 14:15:04 hyperion sshd[8530]: Invalid user test from 218.56.61.114

Tento typ útoků je na provedení velice triviální a je momentálně typem, se kterým se zcela jistě setkáte, pokud neomezíte přístup na svůj SSH port. Obrana bývá triviální - jedna útočící IP adresa a mnoho neúspěšných pokusů za jednotku času, to lze odfiltrovat velmi dobře (nástroje pro tento účel představím níže).

Někteří útočníci jsou ale chytřejší - útoky jsou pak vleklejší (doba mezi pokusy je podstatně delší), popřípadě ještě navíc pocházejí z mnoha různých IP adres (nejčastěji z nějakého botnetu). Sofistikovanější útočníci pak nezkoušejí kombinace jmen a hesel, ale hledají starší, neaktualizované SSH servery, u kterých mohou využít dostupných exploitů objevených zranitelností.

Nejhorším typem útoku je útočník, který si opatří velký seznam serverů se SSH a čeká na 0-day SSH exploit, který až se objeví, celý seznam rychle projede. Proti tomu se brání těžko (leda citelně omezit přístup k SSH). Mimochodem, zálohujete, že?

Elementární zabezpečení

Zkontrolujte si, že v konfiguračním souboru SSH serveru (pro OpenSSH je to nejspíše/etc/ssh/sshd_config) je povolen pouze protokol verze 2, verzi 1, která má řadu bezpečnostních zranitelností, byste měli mít zakázanou:

Protocol 2

Z bezpečnostních důvodů je vhodné využívat tzv. striktní režim, který zkontroluje práva v domovském adresáři uživatele, zdali do kritických míst není umožněn přístup jiným uživatelům (a pokud ano, přihlášení odmítne):

StrictModes yes

Pokud nepotřebujete spouštět na serveru Xkové aplikace, rozhodně zakažte X11Forwarding:

X11Forwarding no

Pokud nechcete, nehodláte nebo nepotřebujete využívat tunelování v rámci SSH, raději jej zakažte:

PermitTunnel no

To platí dvojnásob pro servery, kde se k SSH přihlašují běžní uživatelé a ne pouze administrátoři - příslušní uživatelé by pak mohli server využít jako proxy, třeba k anonymnímu surfování, stahování torrentů, apod.

Elementární řízení přístupu uživatelů k SSH serveru

Předně je třeba zvážit, kdo skutečně potřebuje SSH účet. Je skutečně potřeba, aby každý uživatel, který má třeba na serveru poštovní schránku, měl současně i SSH účet s možností přístupu k shellu? Potřebuje zákazník webhostingu SSH konto? Je nutné, aby správce serveru měl možnost k němu přistupovat z libovolné IP adresy? Zabezpečení SSH serveru by určitě mělo začít analýzou, kdo skutečně potřebuje přístup k SSH a odkud.

AllowUsers, AllowGroups

Já osobně řeším na svých serverech tento problém tak, že vytvořím skupinu, třeba sshusers, kterou přiřadím jako parametr volby AllowGroups v konfiguračním souboru SSH serveru a do které zařadím všechny uživatele, kteří mají mít přístup k SSH. Pokud je těchto uživatelů velmi málo, není třeba to řešit přes skupiny, postačí jednotlivé uživatele vypsat, oddělené mezerou, jako parametr volby AllowUsers. Jakmile v konfiguraci SSH serveru použijete některou z těchto voleb, nikdo jiný než specifikovaní uživatelé či skupiny se k SSH již nepřihlásí. Pro názornost ilustruji obě varianty pro dva uživatele:

/etc/ssh/sshd_config:
AllowGroups sshusers
 
bash ~# useradd -G sshusers michal
bash ~# useradd -G sshusers honza

A druhá varianta:

/etc/ssh/sshd_config:
AllowUsers michal honza

OpenSSH má k dispozici adekvátní protějšky k oběma volbám - DenyUsers a DenyGroups, které fungují přesně opačně (zabrání daným uživatelům a skupinám přihlásit se k SSH). OpenSSH prochází tyto volby v rámci řízení přístupu v následujícím pořadí:

PermitRootLogin

Další zajímavou volbou je PermitRootLogin, která určuje, zdali se k SSH smí přihlásit uživatel root. Obvykle se doporučuje vytvořit jiného, neprivilegovaného uživatele, a administrátorské úkony řešit přes sudo, popřípadě su. Je to dáno jednak všemocností uživatele root, a jednak tím, že v případě uživatelského účtu se musí případný útočník strefit jak do hesla, tak do uživatelského jména. V případě uživatele rootpotřebuje útočník pouze jediný údaj - heslo.

Volba PermitRootLogin má tři možné hodnoty, yes, no a without-password. Nejzajímavější je právě ona třetí hodnota, without-password, která způsobí, že se uživatel root nebude moci přihlásit heslem, ale pouze některou z jiných metod (tj. třeba SSH klíčem).

PermitEmptyPasswords

Pokud používáte ověřování heslem, rozhodně se vyplatí vypnutí přihlašování u účtů bez hesla, aby případnému útočníkovi nestačilo pouze uhádnout heslo:

PermitEmptyPasswords no

Vypnutí ověřování přístupu heslem

Pokud všichni administrátoři, popřípadě uživatelé, využívají k přístupu na server SSH klíče, pak není důvod, proč povolovat autentikaci heslem. Tu je pak možné z bezpečnostních důvodů vypnout úplně:

PasswordAuthentication no

To je vůbec jeden z nejideálnějších způsobů zabezpečení SSH, protože pak veškeré pokusy o uhádnutí hesla skončí podobně jako tento:

# ssh uzivatel@magnetar.cz
Permission denied (publickey).

Útočník ani nedostane příležitost zadat heslo, natož jej uhádnout. Samozřejmě byste měli příslušné SSH klíče střežit jako oko v hlavě a mít na paměti, že pokud příslušné SSH klíč(e) ztratíte, ztratíte i možnost přihlášení na server, protože heslem se tam už pak nedostanete.

Elementární řízení přístupu k SSH serveru

ListenAddress

Nechte SSH server naslouchat jen tam, kde je to třeba. Máte-li někde kupříkladu firewall, a nechcete se k jeho SSH serveru připojovat zvenčí, pak upravte volbu ListenAddress tak, aby SSH server poslouchal jen tam, kde potřebujete, třeba na nějaké adrese místní sítě (tato IP adresa musí být přidělena konkrétnímu síťovému rozhraní firewallu):

ListenAddress 10.0.1.15

Přesun SSH portu

Toto je mezi správci velmi kontroverzní záležitost. Vždy, když uvedete přesměrování SSH portu jako bezpečnostní opatření, rozdělí se přítomní správci do dvou nesmiřitelných táborů, kde jeden tuto metodu za zabezpečení považuje, zatímco druhý nikoliv. Já patřím k těm, kteří neuznávají vliv tohoto opatření na zabezpečení serveru a myslím si, že ani vy byste se na toto opatření neměli dívat jako na opatření jakkoliv zvyšující bezpečnost (získali byste jen falešný pocit bezpečí, který je tím nejhorším, co se vám při zabezpečování serveru může stát).

Jediný přínos tohoto opatření spočívá v tom, že se vám vyhne většina automatizovaných útoků, které testují pouze port 22 na přítomnost SSH serveru. Problémem je, že automatizované útoky tohoto rázu jsou ty nejméně nebezpečné, a vaše konfigurace by měla SSH server před těmito útoky spolehlivě zabezpečit, a to zcela bez ohledu na toto opatření. Navíc inteligentní útočník může váš server proskenovat a port objevit, popřípadě může daný port objevit nasloucháním na nějakém uzlu mezi vaším serverem a klientem. Nicméně, pokud máte dobrý důvod toto opatření nasadit, pomůže vám volba Port:

Port 61582

hosts.allow a hosts.deny

Kromě firewallu je možné omezit přístup k SSH prostřednictvím souborů /etc/hosts.allow a/etc/hosts.deny. Tyto dva soubory řídí přístup k řadě služeb využívajících TCP Wrapper metodu řízení síťového přístupu. Tato metoda spočívá v tom, že daný démon využívá jisté knihovny (libwrap), která pak samotné řízení přístupu provádí. Pokud provozujete síťové služby, které tuto knihovnu nevyužívají, pak je touto metodou přirozeně neochráníte, a nezbyde vám než je chránit jinak (třeba firewallem).

Více informací naleznete v manuálových stránkách příslušných souborů. Základy práce s nimi jsou následující. V souboru hosts.allow se nastavuje povolení přístupu k jednotlivým službám, zatímco v souboru hosts.deny se nastavuje zamezení přístupu ke službám. Při řízení přístupu se upřednostňujehosts.allow, tj. pokud v tomto souboru nějaký počítač nebo síť povolíte, pak se přístup povolí bez ohledu na obsah hosts.deny. Jako příklad uvedu následující situaci:

/etc/hosts.allow:
ALL: localhost
ALL: 10.0.5.15
sshd: 12.34.56.78
 
/etc/hosts.deny:
ALL: 1.2.3.4
sshd: 5.6.7.8

V tomto příkladu bude jednoznačně povolen přístup ke všem službám z localhostu a 10.0.5.15 a k SSH z IP adresy 12.34.56.78. Zakázán bude přístup ke všem službám adrese 1.2.3.4 a jen k SSH adrese 5.6.7.8. Je samozřejmě možné specifikovat rozsahy i různé zástupné výrazy (jako třeba ALL. Více informací se dozvíte v manuálových stránkách.

Pokročilé řízení přístupu uživatelů k SSH serveru

access.conf

V tuto chvíli víte, jak omezit přístup k SSH, ale co když budete potřebovat omezit přístup k SSH třeba jen pro některé uživatele s tím, že u jiných uživatelů vám třeba nevadí, odkud se hlásí? V takovém případě byste se měli podívat blíže do souboru /etc/security/access.conf, kde je možné specifikovat, kteří uživatelé se smí přihlašovat z jakých IP adres nebo sítí. Ukažme si to na příkladu:

+ : root : 127.0.0.1
+ : root : 10.0.0.0/8
+ : root : 12.34.56.78
- : root : ALL
+ : michal : example.com
+ : michal : 1.2.3.4
+ : @admini : 5.6.7.8
- : ALL : ALL

Plus nebo mínus na začátku udává, zdali se má přístup povolit nebo zakázat. Oddělovačem je dvojtečka, následuje uživatel či skupina (skupina je uvozena zavináčem) a posledním parametrem je síť, doména nebo IP adresa, která je předmětem řízení přístupu. V prvních třech řádkách je povolen přístup uživateli root z localhostu, místního rozsahu 10.0.0.0/8 a vnější IP adresy 12.34.56.78. Na čtvrtém řádku je pravidlo, které zamezí přístup k SSH uživateli root z jakéhokoliv jiného umístění. Následuje povolení přístupu uživatelimichal z domény example.com a IP adresy 1.2.3.4. Předposlední řádek povoluje přístup skupině admini z IP adresy 5.6.7.8. Úplně poslední řádek pak funguje jako "vykopávač", zamezí jakýmkoliv jiným přístupům odjinud. Více informací viz manuálová stránka souboru access.conf