.. _ssh-server: Základy konfigurace SSH serveru (openssh) ----------------------------------------- Sice existuje více implementací protokolu SSH, v Unixu včetně Linuxu má v současné době dominantní postavení balík OpenSSH distribuovaný pod licencí typu BSD. Hlavní klientské programy (ssh, ssh-agent, ssh-keygen) byly stručně popsány v předchozí kapitole. Zde stručně popíšeme **sshd** - **SSH server daemon** - včetně zabezpečení konfigurace. V srpnu 2018 byla vydána verze 7.8, v jednotlivých distribucích Unixu a Linuxu je ale obvykle k dispozici starší verze programy. Následující popis bude zaměřen na verzi 7.4p1, která je v Debian Stretch. Podrobnou dokumentaci získáte z manuálových stránek pomocí příkazů: .. code-block:: bash :emphasize-lines: 1-2 man sshd man sshd_config Daemon sshd ~~~~~~~~~~~ Daemon ``sshd`` standardně poslouchá na portu 22, což lze ověřit příkazem ``netstat`` s přepínači ``-at``, který vypíše otevřená tcp spojení (pomocí ``grep`` omezím výpis na port 22): .. code-block:: bash :emphasize-lines: 1 netstat -atn | grep ':22' tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 146.102.18.87:22 146.102.93.146:50387 ESTABLISHED tcp 0 0 146.102.18.87:22 217.112.172.43:58602 ESTABLISHED tcp 0 0 146.102.18.87:22 146.102.93.145:60033 ESTABLISHED tcp 0 0 146.102.18.87:22 217.112.172.43:58604 ESTABLISHED Ve výpisu je vidět, že naslouchá na port 22 a dále že jsou otevřena spojení z 3 různých IP adres. Z IP adresy 217.112.172.43 jsou otevřena dvě souběžná spojení. Program ``ps -ef`` vypisuje spuštěné procesy, pomocí ``grep`` omezím výpis na daemon sshd: .. code-block:: bash :emphasize-lines: 1 ps -ef | grep sshd root 6111 1 0 Sep21 ? 00:00:07 /usr/sbin/sshd -D root 30035 6111 0 12:26 ? 00:00:00 sshd: pavlicek [priv] pavlicek 30046 30035 0 12:26 ? 00:00:00 sshd: pavlicek@pts/1 root 14569 6111 0 14:30 ? 00:00:00 sshd: test99 [priv] test99 14575 14569 0 14:30 ? 00:00:00 sshd: test99@pts/14 root 14697 6111 0 14:35 ? 00:00:00 sshd: test99 [priv] test99 14703 14697 0 14:35 ? 00:00:00 sshd: test99@pts/15 root 21220 6111 0 Sep21 ? 00:00:00 sshd: xabcd01 [priv] xabcd01 21230 21220 0 Sep21 ? 00:00:01 sshd: xabcd01@pts/0,pts/5 Při nastartování serveru se spustí program **/usr/sbin/sshd** a tím se vytvoří proces (zde s číslem procesu ``6111``). Tento proces poslouchá na portu **22** a čeká na navázání spojení od nějakého klienta. Pro tento typ procesů se používá označení **daemon**. Když se připojí uživatel, tak se pro toto spojení vytvoří dva procesy. První proces vytvoří daemon a tento proces běží též pod uživatelem **root** (u spojení uživatele ``pavlicek`` je to proces ``30035``). Tento proces vytváří a spravuje transportní vrstvu protokolu ssh (viz kapitola 2.3). Po vytvoření transportní vrstvy a autentizaci uživatele spustí další proces, nyní **s právy přihlášeného uživatele** (proces ``30046`` pro spojení uživatele ``pavlicek``). Tento proces obsluhuje jednotlivá spojení (jednotlivé kanály), např. spouští shell (příkazovou řádku) konkrétního uživatele. Samostatné procesy umožňují minimalizovat škody v případě úspěšného útoku na implementaci sshd. Jak upravit konfiguraci pro sshd ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Konfigurace daemonu sshd se mění v souboru **/etc/ssh/sshd_config**. Úpravy může provádět pouze uživatel root. Na svém serveru můžete získat toto oprávnění např. příkazem: .. code-block:: bash :emphasize-lines: 1 sudo -i U následujících příkazů předpokládám, že jste tento příkaz úspěšně spustili, tj. že máte oprávnění uživatele root. Před změnami si udělejte zálohu, např. příkazem .. code-block:: bash :emphasize-lines: 1 cp /etc/ssh/sshd_config /etc/ssh/sshd_config_zaloha Pro editaci použijte editor nano (jednodušší pro začátečníky) či editor vim (mnohem více možností, barevná syntaxe). .. code-block:: bash :emphasize-lines: 1,3 nano /etc/ssh/sshd_config # či vi /etc/ssh/sshd_config Po úpravě a uložení souboru zkontrolujte syntaxi úprav pomocí příkazu ``sshd -t``. V následující ukázce se vypíší chyby .. code-block:: bash :emphasize-lines: 1 sshd -t /etc/ssh/sshd_config: line 105: Bad configuration option: llowUsers /etc/ssh/sshd_config line 105: Directive 'llowUsers' is not allowed within a Match block Pokud nejsou syntaktické chyby, tak restartujte sshd pomocí příkazu .. code-block:: bash :emphasize-lines: 1 systemctl restart sshd **Nezavírejte otevřené ssh spojení.** I když příkaz ``sshd -t`` nevypsal chyby syntaxe, tak **stále mohou být v sshd_config chyby**, které způsobí, že se nebudete moci přihlásit. Např. zakážete přihlašování heslem i klíčem. **Otevřete nové ssh spojení** a ověřte, že se můžete úspěšně přihlásit. Pokud se nemůžete přihlásit, tak zkontrolujte, zda je spuštěn proces sshd pomocí příkazu: .. code-block:: bash :emphasize-lines: 1 ps -ef | grep sshd root 3680 1 0 17:12 ? 00:00:00 sshd: root@pts/0 root 3824 1 0 17:35 ? 00:00:00 /usr/sbin/sshd -D root 3876 3689 0 17:41 pts/0 00:00:00 grep --color=auto sshd Ve výpisu musíte najít ``/usr/sbin/sshd -D``. Pokud tento řádek nenajdete, tak se při restartu nespustil proces ``sshd``. Důvod najdete ke konci logu ``/var/log/daemon.log``. .. code-block:: bash :emphasize-lines: 1 less /var/log/daemon.log Pokud proces ``/usr/sbin/sshd`` běží, tak důvod, proč se nemůžete přihlásit najdete ke konci souboru ``/var/log/auth.log``. .. code-block:: bash :emphasize-lines: 1 less /var/log/auth.log Struktura konfiguračního souboru, podmíněné sekce ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Parametry v konfiguračním souboru se skládají z klíčového slova a jedné či více hodnot, na řádku může být pouze jedno klíčové slovo. Komentáře začínají znakem ``#``. V následující ukázce je začátek konfiguračního souboru: .. code-block:: bash # Package generated configuration file # See the sshd_config(5) manpage for details Port 22 AddressFamily inet Na začátku konfiguračního souboru /etc/ssh/sshd_config se uvádějí **parametry s globální platností**. Za nimi následují **podmíněné (Match) bloky** - zadává se podmínka a na dalších řádcích parametry pro spojení odpovídají podmínce. Blok je ukončen buď následujícím podmíněným blokem či koncem souboru. .. code-block:: bash ... PermitRootLogin no ... Match address 146.102.0.0/16,127.0.0.1/32 PermitRootLogin without-password V globální části konfiguračního souboru je zakázáno přihlášení uživatele root. Podmínkou v sekci je spojení ze školních IP adres (146.102.0.0/16) či z přímo z vlastního serveru (127.0.0.1). Pokud je podmínka splněna, tak se povolí přihlášení uživatele **root** pomocí klíče. Vedle IP adres klienta se v podmínkách často používá uživatelské jméno (user) či skupina (group) - oboje např. pokud část uživatelů nemá mít možnost vytvářet tunely či pokud některý uživatel může pouze kopírovat soubory. Zabezpečení SSH serveru ~~~~~~~~~~~~~~~~~~~~~~~ Následují doporučení pro zabezpečení SSH serveru. Zákaz přihlášení pomocí hesla +++++++++++++++++++++++++++++ Pokud mají správci a uživatelé ověřeno přihlašování klíčem, tak je vhodné zakázat přihlašování pomocí hesla. U parametru ``PasswordAuthentication`` změňte hodnotu na ``no``: .. code-block:: bash PasswordAuthentication no Následující pokusy o přihlášení pomocí hesla poté skončí chybou, viz následující ukázka: .. code-block:: bash :emphasize-lines: 1 ssh bis145.vse.cz Permission denied (publickey). Je vhodné též zakázat ChallengeResponseAuthentication, která se používá při např. při vícefaktorové autentizaci pro zadání hodnoty druhého faktoru. V závislosti na konfiguraci knihovny PAM může totiž umožnit přihlašování pomocí hesla. .. code-block:: bash ChallengeResponseAuthentication no Na bis.vse.cz je povoleno přihlašování heslem pouze ze školní sítě. V konfiguraci využita podmíněná sekce (a jak si určitě pamatuje z předchozí části, tak podmíněné sekce musí být až na konci konfiguračního souboru): .. code-block:: bash # ... část globální konfigurace PasswordAuthentication no # ... další část globální konfigurace # Match address 146.102.0.0/16 PasswordAuthentication yes Zákaz přihlášení uživatele root +++++++++++++++++++++++++++++++ Pokud se správci mohou stát privilegovanými pomocí sudo, tak ve většině případů neexistují důvody pro povolení přihlašování pod uživatelem root. Výjimkou mohou být nástroje po vzdálenou administraci serveru jako je ansible. Ale i v těchto případech byste měli povolit přihlášení uživatele root pouze z vybraných IP adres (viz příklad v předchozí kapitole). | Parametr **PermitRootLogin** určuje možnosti přihlášení uživatele root. Podporuje hodnoty: | ``yes`` (může se přihlašovat bez omezení), | ``no`` (nemůže se přihlásit), | ``without-password`` (nemůže se přihlásit heslem), | ``forced-commands-only`` (lze spustit pouze vybrané příkazy, např. zálohování). Omezení tunelů ++++++++++++++ Na serveru obvykle nepotřebujete spouštět Xkové (grafické) aplikace a proto zakažte X11Forwarding: .. code-block:: bash X11Forwarding no Na serveru často nepotřebujete ani ostatní typy tunelů. Zakážout se pomocí: .. code-block:: bash PermitTunnel no Vhodné je to na serverech, kam se přihlašuje větší množství uživatelů. Zákazem tunelů omezíte možnosti zneužití serveru jako proxy např. k anonymnímu surfování či ke stahování torrentů. Pro vybrané uživatele může povolit tunely v podmíněném (Match) bloku. Omezení uživatelů (AllowUsers, AllowGroups) +++++++++++++++++++++++++++++++++++++++++++ Pomocí parametrů **AllowUsers**, **AllowGroups**, **DenyUsers** a **DenyGroups** můžete omezit přihlášení na konkrétní uživatele či uživatelské účty. **Doporučuji použít pouze jeden z těchto parametrů** - před použitím dvou či více si předem pečlivě prostudujte v dokumentaci, jak se vzájemně ovlivňují (logická operace AND). Osobně preferuji použití AllowGroups a včetně vytvoření speciální skupiny uživatelů, kteří se mohou hlásit. Na bis.vse.cz je následující řádek: .. code-block:: bash AllowGroups root sudo users Mohou se hlásit členové skupin ``root`` (obsahuje uživatele root), ``sudo`` (uživatelé s možností stát se privilegovaní pomocí příkazu sudo) a členové skupiny ``users``. Naslouchání na jiném portu ++++++++++++++++++++++++++ Tuto radu považuji za kontroverzní. Je potřeba zvážit výhody a nevýhody pro konkrétní situaci. Pokud je server otevřen do Internetu, tak v logu najdete mnoho pokusů o hádání hesla. Za den to jsou tisíce pokusů, zvlášť pokud máte povoleno přihlašování pomocí hesla. Změnou čísla portu se počet pokusů výrazně sníží, obvykle na jednotky pokusů. Tím snížíte zátěž serverů i pravděpodobnost náhodného úspěchu útočníka. Změna portu není účinná vůči útočníkovi, který se zaměří na Váš server. Jednoduchým skenem najde port, na kterém SSH daemon poslouchá. Změna portu je též nepříjemná pro uživatele - pokud mají přistupovat k většímu počtu serverů a na každém je jiné číslo SSH portu, tak budou zmateni a se nebudou schopni přihlásit. V podstatě jim neúmyslně omezíte přístup ke službám. Změna portu v sshd_config je jednoduchá: .. code-block:: bash Port 2244 Omezit počet pokůsů o přihlášení ++++++++++++++++++++++++++++++++ Útočníci se pomocí skriptů neustále snaží o přihlášení na dostupné servery - pro různé účty a s různými hesly. I když je vypnuté přihlašování pomocí hesla, tak to zbytečně zatěžuje server. Používají se různé metody a jejich kombinace. Omezení počtu pokusů může vést k odmítnutí služby, kdy se nepřihlásí ani legální uživatel. Pomocí parametru **MaxAuthTries** v sshd_config lze omezit počet pokusů o přihlášení v průběhu jednoho připojení. Defaultní hodnota je 6, takže uživatel může zkusit šest chybných hesel, než server ukončí spojení. Přestože najdete mnohá doporučení na snížení této hodnoty na 3 či méně, tak to příliš nedoporučuji, neboť to může zablokovat přihlášení pomocí klíčů. Když má uživatel v agentovi např. 4 klíče, tak se postupně zkouší pomocí nich přihlásit. A pokud by bylo omezení na tři pokusy, tak se čtvrtý klíč nikdy nezkusí. Další metody stručně: * omezení ve firewallu - lze omezit počet souběžných spojení z IP adresy i počet navázaných spojení z IP adresy za určitou dobu. * specializované aplikace jako file2ban - tyto aplikace průběžně čtou logy a pokud je z nějaké IP adresy více neúspěšných pokusů o přihlášení, tak tuto IP adresu na určitou dobu (např. 12 hodin) zablokují. * PAM moduly - pro PAM existuje více modulů, které ovlivňují přihlašování. Lze omezit počet souběžných přihlášení od jednoho uživatele. Modul Pam_Tally2 umožňuje blokovat na určitou dobu (např. 3 hodiny) IP adresy, ze kterých byl větší počet neúspěšných přihlášení (např. více než 5 za posledních 30 minut).