Správa linuxového serveru: Praktické rady pro zabezpečení SSH II
Minule jsem probral některé metody zabezpečení SSH, dnes v tom budu pokračovat. Proberu elementární zabezpečení SSH firewallem a představím nástroj Denyhosts.
Začnu velmi zlehka něčím, co se sice obvykle považuje za naprostou samozřejmost, a sice pravidelnou aktualizací a sledováním hlášení o bezpečnostních problémech. Bohužel se i na takovou samozřejmost v některých případech zapomíná, což mívá za následek úspěšný průnik útočníka, který se dříve či později skoro jistě dostaví. V případě distribuce Debian naleznete základní informace o bezpečnosti na stránkách distribuce. Hodit se vám může také e-mailová konference, do které se můžete přihlásit, abyste dostávali informace o bezpečnostních aktualizacích a problémech.
S aktualizacemi souvisí i vývojový cyklus distribuce, kterou používáte na serveru. Pokud se jedná o distribuci s pravidelným vývojovým cyklem, jako třeba Debian (resp. jeho stable větev), pak vás během používání určitého vydání čeká řada drobných aktualizací, v rámci kterých se obvykle nemění verze aktualizovaných komponent. Takové aktualizace by neměly narušit fungování vašich služeb (snad s výjimkou restartu při aktualizaci), i když výjimky potvrzující pravidlo samozřejmě existují. Jednou za nějaké období vás pak čeká velká aktualizace, kde se poměrně dramaticky mění verze komponent, díky čemuž může dojít k narušení fungování některých komponent či démonů (došlo ke změnám v konfiguračních souborech či ve funkcionalitě).
Některé aktualizace během života konkrétního vydání mohou vyžadovat nějaký zásah správce (namátkouprůšvih Debianu s OpenSSL knihovnou), takže i když je teoreticky možné provádět aktualizace automaticky cronem, nelze tento postup doporučit, alespoň ne na produkčních serverech. Abyste věděli, kdy máte na serveru k dispozici nové aktualizace, můžete použít v případě Debianu nástroj Apticron, o kterém se dočtete více v článku na debian-administration.org. Funguje tak, že jednou denně zjistí dostupné aktualizace a pošle vám o nich e-mail, pokud nějaké k dispozici jsou. Vy se pak můžete rozhodnout, zdali aktualizaci provedete nebo ne.
Upgrade na novější verzi distribuce je vhodné dělat opatrně a s rozmyslem, ideálně až nějakou dobu po vypuštění nové verze, po pečlivém prostudování poznámek k vydání (release notes), kde se obvykle nachází většina známých problémů, na které můžete při upgradu narazit. Bývá dobré si připravit půdu pro případný rollback provedením kompletní zálohy dat i konfigurace, a nebo ještě lépe, provést zkušební upgrade na jiném počítači se stejnou konfigurací (konfiguraci i data z produkčního serveru můžete na zkušební server zkopírovat).
Provozu firewallu v Linuxu se budu blíže věnovat v některém z příštích dílů. V tuto chvíli pro potřeby zabezpečení SSH postačí následující jednoduchá sada pravidel. V tomto příkladu nevyužívám možnosti stavového firewallu, což příklad trošku zjednoduší, a hlavně to bude fungovat i na virtuálních serverech, kde není k dispozici příslušný modul pro stavový firewall:
# povolení přístupu k SSH z IP adresy 1.2.3.4
iptables -A INPUT -s 1.2.3.4 -p tcp --dport 22 -j ACCEPT
# zamezení přístupu k SSH z IP adresy 5.4.3.2
iptables -A INPUT -s 5.4.3.2 -p tcp --dport 22 -j DROP
# zamezení přístupu k SSH z rozsahu adres 10.0.0.0/8
iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 22 -j DROP
Akci DROP
můžete pochopitelně vyměnit za REJECT
s příslušnou ICMP zprávou, pokud chcete. V případě, že potřebujete řídit přístup k SSH třeba na routeru, kde je více síťových rozhraní, můžete být specifičtější a vzít dané rozhraní v úvahu:
# zákaz přístupu na SSH z rozhraní eth0
iptables -A INPUT -i eth0 -p tcp --dport 22 -j DROP
# zákaz přístupu na SSH z rozhraní eth1
iptables -A INPUT -i eth1 -p tcp --dport 22 -j DROP
# povolení přístupu k SSH na rozhraní eth2 z IP adresy 10.0.1.5
iptables -A INPUT -i eth2 -s 10.0.1.5 -p tcp --dport 22 -j ACCEPT
# zamezení přístupu k SSH ze všech ostatních adres na rozhraní eth2
iptables -A INPUT -i eth2 -p tcp --dport 22 -j DROP
Pro úplnost uvádím trošku elegantnější řešení s použitím stavového firewallu a vlastního řetězce, kde pak můžete zpracovávat pouze žádosti o nové spojení se standardním SSH portem:
# vytvoření řetězce pro ssh
iptables -N ssh
# přesměrování paketů s žádostí o vytvoření spojení na SSH port do řetězce ssh
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ssh
# v rámci řetězce SSH povolení paketů z IP adresy 1.2.3.4
iptables -A ssh -s 1.2.3.4 -j ACCEPT
# v rámci řetězce SSH povolení paketů z rozsahu 10.0.0.0/8
iptables -A ssh -s 10.0.0.0/8 -j ACCEPT
# zahození ostatních paketů
iptables -A ssh -j DROP
# někde jinde pak musí být řádka propouštějící pakety náležející již vytvořeným spojením:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Dodám ještě, že nemusíte využívat Netfilter (a nástroj iptables
) přímo, nýbrž můžete použít některou z nadstaveb jako třeba Shorewall, o kterém zde vyšel dvoudílný seriál (první díl, druhý díl).
Do této chvíle byly probrány především prvky pasivní ochrany SSH serveru. To jsou bez zásahu správce neměnná opatření, např. přístup k SSH pouze z IP určité adresy nebo naopak zamezení přístupu k SSH z určité IP adresy nebo rozsahu IP adres. Aktivní opatření jsou naopak taková, která reagují na vzniklou situaci, kupříkladu na sadu neúspěšných pokusů o přihlášení zablokováním dané IP adresy.
Výhodou takových opatření je právě možnost rychlé reakce na nějakou vzniklou situaci (zejména pak neúspěšný pokus o přihlášení). Nevýhody těchto opatření vyplývají především z faktu, že tato reakce na vzniklou situaci je sice předem definovaná, ale automatizovaná a nepodléhá schválení správcem. Mezi potenciální problémy aktivních opatření patří možnost zablokování sebe sama, popřípadě jejich využití útočníkem, ať již k DoS útokům nebo, v horším případě, k průniku do systému.
Nejtypičtější nástroje aktivní obrany jsou parsery logů (např. Denyhosts a Fail2ban). Ty monitorují záznamy v příslušném logu a vyhledávají záznamy jistého typu. Jakmile se takové záznamy objeví, jsou prohnány parserem (nebo spíše nějakým regulárním výrazem) a jsou z nich získány požadované informace. Na jejich základě je pak vyprodukována nějaká reakce (obvykle shellový příkaz nebo přidání záznamu do souboru). Princip je to relativně jednoduchý, avšak skýtá jistou potenciální zranitelnost - log injection. Stejně jako je možné využít nekorektně ošetřený SQL vstup ke změně prováděného SQL příkazu, je možné podobným způsobem upravit akci prováděnou daným nástrojem prostřednictvím vhodně "upraveného" záznamu v logu. Dodám, že známé zranitelnosti tohoto typu byly již z oněch dvou zmíněných nástrojů odstraněny a příslušné regulární výrazy byly podstatně zpřesněny. Více informací o těchto zranitelnostech naleznete na ossec.net.
Pokud budete nasazovat vlastní parser, popřípadě budete upravovat funkci stávajícího vlastním regulárním výrazem, určitě mějte na paměti tuto možnost útoku spolu s faktem, že záznamy v logu může v Linuxu běžně generovat jakýkoliv program, včetně interpretru PHP (pokud to samozřejmě správce nezakáže).
Ať už budete nasazovat jakýkoliv nástroj aktivní obrany, vždy zůstane ten nejjednodušší možný vektor útoku - Denial of Service. Útočník se možná k SSH nedostane, ale může za určitých okolností znemožnit vzdálený přístup i správci či například zákazníkům (kteří využívají SSH/SCP ke kopírování souborů na server apod.). Ze způsobů provedení přichází v úvahu jak možné falšování zdrojové IP adresy, tak log injection či prosté sdílení IP adresy nebo jejího rozsahu s útočníkem nebo počítačem pod jeho kontrolou (viz botnety). Vzhledem k tomu, že dostupných IPv4 adres ubývá a řada poskytovatelů používá NAT, jsou možné následky tohoto typu útoku citelnější.
Denyhosts je parser logů, který hlídá neúspěšné pokusy o přihlášení k SSH a dle nastavení po určitém počtu neúspěšných pokusů zařadí příslušnou IP adresu do /etc/hosts.deny
. Využívá TCP Wrapper, tedy jednu z metod probraných v minulém díle. Abyste zabránili možnému odstřihnutí sebe sama při neúspěšných pokusech o přihlášení, zapište příslušné IP adresy nebo rozsahy, ze kterých se na server chcete hlásit, do souboru /etc/hosts.allow
. Pokud bude IP adresa současně v obou souborech, přístup z ní se povolí, neboť se při kontrole přístupu postupuje v pořadí hosts.allow
a hosts.deny
. Tato metoda umožňuje blokovat přístup jak na SSH, tak na všechny služby využívající knihovnu libwrap
(u síťových démonů si to můžete ověřit nástrojem ldd
).
Výhodou, respektive možná spíše vlastností Denyhosts, je nezávislost na firewallu, který v tomto případě není vůbec využíván. Při práci tohoto nástroje nedochází ke spouštění shellových příkazů s právy roota a parametry získanými regulárním výrazem z logu. Hlavní konfigurační soubor Denyhosts se nachází v/etc/denyhosts.conf
. Mezi podstatné volby konfigurace patří následující:
BLOCK_SERVICE = ALL
Tato část řídí typ záznamu, který se vytvoří v hosts.allow
. Hodnota "ALL
" způsobí, že se přístup z dané IP adresy zamezí na všechny služby využívající TCP Wrapper na daném serveru. Pokud chcete útočníkům zamezit pouze přístup k SSH, použijte hodnotu "sshd
". Primární nastavení chování Denyhosts řídí následující volby:
DENY_THRESHOLD_INVALID = 5
DENY_THRESHOLD_VALID = 10
DENY_THRESHOLD_ROOT = 1
Toto jsou počty neúspěšných pokusů, které jsou třeba k zablokování dané IP adresy.DENY_THRESHOLD_INVALID
udává počet pokusů pro neplatného uživatele, DENY_THRESHOLD_VALID
udává počet pokusů u platného uživatele a DENY_THRESHOLD_ROOT
udává počet pokusů pro uživatele root
. Máte-li podobně "citlivé" účty jako root
, u kterých byste chtěli specifikovat jiný počet pokusů než pro ostatní uživatele, podívejte se na dokumentaci k volbě DENY_THRESHOLD_RESTRICTED
. Počítadla neúspěšných pokusů se po určité době vynulují. Tuto dobu je možné nastavit následujícími volbami:
AGE_RESET_VALID=5d
AGE_RESET_ROOT=25d
AGE_RESET_INVALID=10d
Zde uvedené hodnoty by znamenaly, že se počet neúspěšných pokusů pro platného uživatele vynuluje za pět dní, u neplatného uživatele za 10 dní a v případě uživatele root
bude muset uběhnout 25 dní. Velmi podstatnou volbou je pak RESET_ON_SUCCESS
, který příslušné počítadlo vynuluje při úspěšném přihlášení, je-li nastaven na "yes
".
Chcete-li dostávat zprávy o zablokovaných IP adresách e-mailem, zapište svůj e-mail jako hodnotu volbyADMIN_EMAIL
. Nezapomeňte zkontrolovat nastavení SMTP (implicitní nastavení využívá místní SMTP server). Upozorňuji, že na jediném serveru dochází obvykle k zablokování několika IP adres denně. Můžete tedy spíše preferovat shrnutí za každý den, o což se vám postará třeba nástroj Logwatch (o tom se v tomto seriálu určitě ještě podrobněji zmíním).
Denyhosts umožňuje výměnu dat o útočnících s centrálním serverem, který spravuje projekt Denyhosts. Chcete-li využívat této možnosti, musíte nejprve odkomentovat řádek s volbou SYNC_SERVER
. Můžete specifikovat i jednosměrnou komunikaci (pouze zasílání dat o útočnících či pouze stahování dat o útočnících) pomocí parametrů SYNC_UPLOAD
a SYNC_DOWNLOAD
. Délku periody pro synchronizaci řídí volbaSYNC_INTERVAL
. Je logické předpokládat, že počet záznamů všech uživatelů této služby bude obrovský. Z tohoto důvodu se běžně nestahují všechny IP adresy, ale pouze takové, které útočily na několik serverů (výchozí hodnota je 3). Toto nastavení můžete ovlivnit volbou SYNC_DOWNLOAD_THRESHOLD
. Spolu s touto volbou vystupuje ještě jedna volba omezující počet stažených záznamů, a sice SYNC_DOWNLOAD_RESILIENCY
. Ta specifikuje, jak "čerstvé" příslušné útoky z daných IP adres jsou - výchozím nastavením je "5h
", tedy 5 hodin. Tato volba funguje tak, že se propustí pouze takové IP adresy, kde útočník zaútočil vícekrát během této doby. Tzn. pokud mezi posledními dvěma útoky uběhlo 5 a více hodin, daná IP adresa se stahovat nebude, pokud uběhlo méně, daná IP adresa se stáhne.
Pokud vás v tuto chvíli napadlo, že byste mohli této funkcionality využít centrálně pro své spravované servery, na některém ze svých serverů si zřídit úložiště a to pak využívat k synchronizaci pouze mezi vašimi servery, není to možné - Denyhosts toto v tuto chvíli bohužel neumí.
Tím bych tento díl ukončil. Příště se podívám na konkurenci Denyhosts, projekt Fail2ban, a na některé další zajímavé metody zabezpečení SSH.