Hlavní navigace

OpenSSH má vlastní obranu proti hádání hesel. Jak přesně funguje?

21. 8. 2024
Doba čtení: 6 minut

Sdílet

 Autor: OpenBSD
Nejnovější verze OpenSSH automaticky blokuje hádání hesel. Funkce je navíc automaticky zapnutá. V článku se podíváme na to, jak přesně blokování funguje, jak se dá jeho chování nastavit a zda automatická aktivace nové funkce může představovat problém.

Každý kdo na internetu provozuje server s přístupem pomocí SSH to zná: logy se plní záznamy o pokusech počítačů z celého světa připojit se k našemu serveru. Snaží se zkoušet nejrůznější kombinace jmen a hesel, třeba od zapomenutých účtů hosta nebo hůře dokonce zapomenuté jednoduché heslo administrátora.

Protože nejde o nic nového, bylo vymyšleno už mnoho způsobů, jak záškodníkům život přinejmenším zkomplikovat, od jednoduchých až po velmi sofistikované:

  • Přesunutí služby SSH na jiný port. I když taková akce samozřejmě žádnou reálnou bezpečnost nepřináší, rozhodně se projeví dramatickým úbytkem počtu pokusů o hádání hesel, protože spousta záškodníků se orientuje na kvantitu napadených strojů a nemá zájem zkoumat všech 65 tisíc portů na každé adrese.
  • Používání klíčů a následné vypnutí možnosti přihlášení heslem je velmi bezpečné, ale v závislosti na okolnostech nemusí každému vyhovovat.
  • Jednoduché omezování počtu nových spojení ke službě SSH ve firewallu.
  • Použití sofistikovaných nástrojů jako DenyHosts nebo Fail2Ban, které analyzují logy o neúspěšných přihlášeních a následně sestavují seznam zlobivých adres, které jsou blokovány.
  • Skrytí služby SSH do privátní sítě, dostupné z veřejného internetu jen pomocí VPN. V tomto případě jde v podstatě jen o přesunutí problému ze služby SSH na službu VPN.

Nejnovější verze OpenSSH 9.8, která vyšla 1. července 2024, přidává do arzenálu zbraní proti podobným záškodníkům vlastní implementaci blokování, která je navíc zapnutá ve výchozím stavu. Vývojáři si od této funkce slibují výrazné ztížení hádání hesel i zneužití případných chyb v samotném SSH serveru.

Nastavení blokování je možné upravit pomocí několika konfiguračních voleb začínajících na PerSource. Následující ukázka konfigurace představuje výchozí hodnoty:

PerSourcePenalties crash:90s authfail:5s noauth:1s grace-exceeded:10s
PerSourcePenalties min:15s max:10m max-sources4:65536 max-sources6:65536
PerSourcePenalties overflow:permissive overflow6:permissive
PerSourceNetBlockSize 32:128

Tresty za špatné chování

Blokování funguje na základě penalt, čili trestných sekund. Pro každého klienta, který se k SSH serveru připojí a způsobí, že instance serveru obsluhující tohoto klienta havaruje, se připíše 90 trestných sekund. Za nepovedené přihlášení (typicky po hádání hesla) dostane 5 sekund. Pokud se hned odpojí, aniž by se vůbec pokusil přihlásit, připíše si jednu sekundu a konečně pokud se připojí, ale neautentizuje (obdoba útoku Slowloris), dostane pokutu 10 sekund.

Dále je nastavena minimální a maximální doba blokování: pokud nasbíral klient méně než 15 trestných sekund, nebude blokován. Deset minut, tedy 600 sekund představuje strop, kterého je ovšem nejspíš velmi obtížné dosáhnout ve výchozím nastavení trestů.

Ochrana proti přetížení

Je jasné, že každé účtování aktivit jednotlivých adres spotřebovává systémové prostředky, zejména paměť. To je důležité si uvědomit zejména v případě IPv6, kde snad žádný počítač na světě nemá dostatek paměti k tomu, aby mohl vést evidenci o každé jednotlivé IPv6 adrese uvnitř byť jen jediné podsítě o délce prefixu /64. Z toho důvodu je množství sledovaných adres omezeno na 65536 zvlášť pro IPv4 a pro IPv6.

Volby overflow a overflow6 pak řeší, co se má stát s novými klienty v případě, že dojde k překročení počtu sledovaných adres. Výchozí nastavení je permisivní, to znamená, že v takovém případě není klient odmítnut a ze seznamu penalizovaných klientů jsou případně předčasně odstraněni ti s nejmenším zůstatkem trestných sekund.

Ve výchozím nastavení je posuzována každá IPv4 i IPv6 adresa nezávisle, to je možné změnit volbou PerSourceNetBlockSize, která určuje délku prefixu pro IPv4 a IPv6, které budou sdílet trestné sekundy.

Výjimky

Další dvě volby nejsou ve výchozím stavu nastavené. Volba PerSourceMaxStartups umožňuje omezit počet spojení ve fázi navazování pro konkrétního klienta. Pokud nastavená není, používá se globální hodnota MaxStartups, která má ve výchozím stavu hodnotu 10:30:100. Ta znamená, že je-li ve stavu navazování 10 spojení, začne server odmítat nová s pravděpodobností 30 procent. Tato pravděpodobnost poroste lineárně až do stovky navazovaných spojení; v tu chvíli začne server zahazovat všechna nová spojení.

Volba PerSourcePenaltyExemptList pak umožňuje vyjmenovat adresy a prefixy, které nemají být nikdy blokovány. To je dobrý nápad, zejména v případě zpřísnění výchozího nastavení, kdy se může stát, že blokování omylem postihne i legitimní provoz.

Testujeme

O tom, že blokování funguje, se dozvíme z logů pouze v případě, že se blokování uplatní. Server zaloguje informaci o zahozeném spojení:

sshd[206]: drop connection #0 from [203.0.113.116]:53447 on [192.0.2.1]:22 penalty: failed authentication

Zahození probíhá tak, že server místo standardního představení protokolu SSH napíše jen Not allowed at this time a ukončí spojení. Detailnější informace o udělování trestů jsou k dispozici po nastavení úrovně LogLevel na  VERBOSE:

srclimit_penalise: ipv4: new 203.0.113.116/24 active penalty of 90 seconds for penalty: failed authentication

Poznámka: jde o upravené výchozí hodnoty s 90 trestnými sekundami za neúspěšné přihlášení a počítáním po celých blocích /24.

Výchozí nastavení je velmi mírné

Během krátkého testování s reálným provozem se ukázalo, že při použití výchozího nastavení prakticky k žádnému blokování nedochází. Útočníci zkrátka nejsou obvykle tak rychlí, aby stihli udělat víc než tři marné pokusy o přihlášení během 15 sekund, čímž by se blokování začalo uplatňovat. Je také třeba si uvědomit, že k započítání trestných sekund dojde až po ukončení procesu, který obsluhuje klienta. Ten poskytne celkem šest pokusů o autentizaci – jde o volbu  MaxAuthTries.

Znamená to tedy, že aby byl příslušný klient aspoň na okamžik zablokován, musí zkoušet hesla rychleji než tempem 18 hesel za 15 sekund. Jde tedy o omezení skutečně velmi intenzivního útoku. Proti útočníkovi, který se připojí, vyzkouší šest hesel a přesně za minutu celou akci zopakuje, není blokování účinné vůbec. Zmíněný pomalý útočník není žádný hypotetický příklad, ale naopak velmi reálný příklad, který pozoruji v logu během psaní tohoto článku:

22:13:21 ssh-test sshd-session[12104]: Connection from 203.0.113.116 port 56281 on 192.0.2.1 port 22 rdomain ""
22:13:23 ssh-test sshd-session[12104]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=203.0.113.116  user=root
22:13:25 ssh-test sshd-session[12104]: Failed password for root from 203.0.113.116 port 56281 ssh2
22:13:28 ssh-test sshd-session[12104]: Failed password for root from 203.0.113.116 port 56281 ssh2
22:13:33 ssh-test sshd-session[12104]: Failed password for root from 203.0.113.116 port 56281 ssh2
22:13:35 ssh-test sshd-session[12104]: Received disconnect from 203.0.113.116 port 56281:11:  [preauth]
22:13:35 ssh-test sshd-session[12104]: Disconnected from authenticating user root 203.0.113.116 port 56281 [preauth]
22:13:35 ssh-test sshd-session[12104]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=203.0.113.116  user=root
22:13:35 ssh-test sshd[206]: srclimit_penalise: ipv4: new 203.0.113.116/24 active penalty of 90 seconds for penalty: failed authentication
22:14:22 ssh-test sshd[206]: drop connection #0 from [203.0.113.116]:24278 on [192.0.2.1]:22 penalty: failed authentication

Kromě příliš krátkých trestných intervalů, které se ostatně dají snadno změnit, zde chybí také aspoň nějaká progrese, která by umožnila trestat recidivisty přísněji než prvopachatele. Výše uvedený záškodník se tak i při nastavení 90 trestných sekund za špatné přihlášení může znovu a znovu pokoušet hádat hesla každé dvě minuty.

Krok správným směrem

Každé automatizované blokování požadavků je potenciálním nebezpečím pro DoS útoky, kdy zcela funkční služba přestane být dostupná jako vedlejší produkt boje proti zneužití. Konzervativní výchozí nastavení je tedy na místě, zvlášť když jde o funkci zapnutou ve výchozím stavu.

CS24 tip temata

I podle výchozího nastavení trestných sekund se zdá, že vývojářům jde především o omezení následků zneužití případné zranitelnosti, která by útočníkovi umožnila server shodit. Blokování hádání hesel je tedy spíše příjemným vedlejším efektem.

Integrace blokování přímo do procesu OpenSSH činí takové blokování mnohem jednodušším než provozování externích služeb, které následně automaticky manipulují s firewallem. Server navíc blokovaná spojení zdvořile odmítá, což sice vyzrazuje informaci o aktivním blokování, ale zároveň zásadním způsobem usnadňuje hledání problémů v případech, kdy blokování omylem zasáhne chtěný provoz.

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ě.