Rozdíly
Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
| infrastruktura:bezpecnost:fail2ban [09.03.2026 20:11] – Migrace z it:server:fail2ban Petr Nosek | infrastruktura:bezpecnost:fail2ban [23.04.2026 11:58] (aktuální) – Doplnění stránky Fail2ban o SoftEther a praktické jail konfigurace Petr Nosek | ||
|---|---|---|---|
| Řádek 1: | Řádek 1: | ||
| ====== Fail2ban ====== | ====== Fail2ban ====== | ||
| - | Software k dynamickému | + | [[https:// |
| + | |||
| + | ===== Instalace ===== | ||
| <code bash> | <code bash> | ||
| apt install fail2ban | apt install fail2ban | ||
| - | |||
| cd / | cd / | ||
| cp jail.conf jail.local | cp jail.conf jail.local | ||
| </ | </ | ||
| - | zdroje k nastavení fail2ban: | + | ===== SoftEther VPN ===== |
| - | * https://www.czeo.com/ | + | Pro [[infrastruktura:vpn: |
| - | * https:// | + | |
| + | < | ||
| + | VPN Server/ | ||
| + | LogSwitchSet command - Set Log File Switch Cycle | ||
| + | Select Security or Packet: security | ||
| + | Specify sec, min, hour, day, month or none: none | ||
| + | </ | ||
| - | ===== Akce - složka action.d ===== | + | Výsledkem je soubor |
| - | + | ||
| - | + | ||
| - | Pro webserver jsem nastavoval, aby se zablokoval při portscanningu přístup na všechny porty, kromě 80 a 443. K tomu mi posloužil vytvoření | + | |
| - | + | ||
| - | V githubu je soubor ještě více předělaný, tak aby po zabanování zabil ještě existující spojení. Což můj skript neumí. Alespoň jsem se neodříznul od ssh: | + | |
| - | https:// | + | |
| - | + | ||
| - | Pokud bych provozoval ještě nějaké další služby, musel bych je přidat, abych do tohoto skriptu. Protože pokud někdo udělá portscan, tak se zaříznou všechny služby, kromě žádoucích 80 a 443. | + | |
| <code bash> | <code bash> | ||
| - | # Fail2Ban action configuration file for ufw | + | ls -l / |
| - | # | + | |
| - | # You are required to run "ufw enable" | + | |
| - | # | + | |
| - | # The insert position should be appropriate to block the required traffic. | + | |
| - | # A number after an allow rule to the application won't be of much use. | + | |
| - | + | ||
| - | [Definition] | + | |
| - | + | ||
| - | actionstart = | + | |
| - | + | ||
| - | actionstop = | + | |
| - | + | ||
| - | actioncheck = | + | |
| - | + | ||
| - | actionban = [ -n "< | + | |
| - | ufw prepend < | + | |
| - | ufw prepend allow proto tcp from <ip> to < | + | |
| - | #ufw insert < | + | |
| - | + | ||
| - | actionunban = [ -n "< | + | |
| - | ufw delete < | + | |
| - | ufw delete allow proto tcp from <ip> to < | + | |
| - | #ufw delete < | + | |
| - | + | ||
| - | [Init] | + | |
| - | # Option: insertpos | + | |
| - | # Notes.: | + | |
| - | insertpos = 1 | + | |
| - | + | ||
| - | # Option: blocktype | + | |
| - | # Notes.: reject or deny | + | |
| - | blocktype = deny | + | |
| - | + | ||
| - | # Option: destination | + | |
| - | # Notes.: The destination address to block in the ufw rule | + | |
| - | destination = any | + | |
| - | + | ||
| - | # Option: application | + | |
| - | # Notes.: application from sudo ufw app list | + | |
| - | application = | + | |
| - | + | ||
| - | # DEV NOTES: | + | |
| - | # | + | |
| - | # Author: Guilhem Lettron | + | |
| - | # Enhancements: | + | |
| </ | </ | ||
| + | Pak stačí filtr a jail. | ||
| + | Filtr ''/ | ||
| - | ===== Filtry - složka filter.d ===== | + | < |
| - | + | ||
| - | Tady je konfigurace k jednotlivým službám. Každá služba zapisuje do syslogu pokusy o přihlášení v různém formátu. Filtry skrz regulární výrazy ukazují, co hledat. Tím, si lze fail2ban rozšířit i na služby, pro které defaultně určen není. | + | |
| - | + | ||
| - | Přidáme **/ | + | |
| - | + | ||
| - | < | + | |
| - | # Fail2Ban filter for SoftEther authentication failures | + | |
| - | # Made by quixrick and jonisc | + | |
| - | # Thanks to quixrick from Reddit! https:// | + | |
| [INCLUDES] | [INCLUDES] | ||
| - | |||
| - | # Read common prefixes. If any customizations available -- read them from | ||
| - | # common.local | ||
| before = common.conf | before = common.conf | ||
| - | #Enable multi line support. Doesn' | ||
| [Init] | [Init] | ||
| - | maxlines = 2 | + | maxlines = 2 |
| - | # The regular expression filter follows | + | |
| - | [Definition] | + | |
| + | [Definition] | ||
| failregex =IP address: < | failregex =IP address: < | ||
| ignoreregex= | ignoreregex= | ||
| </ | </ | ||
| - | Dále **/ | + | Příklad '' |
| - | < | + | < |
| - | # Fail2Ban filter for portscan | + | [vpnserver] |
| - | # https://serverfault.com/questions/629709/trouble-with-fail2ban-ufw-portscan-filter | + | enabled = true |
| - | # https:// | + | logpath = /usr/vpnserver/security_log/DEFAULT/sec.log |
| - | # | + | port = all |
| - | # | + | protocol = all |
| + | banaction = iptables-allports | ||
| + | filter = vpnserver | ||
| - | [Definition] | + | [vpnserver-HUB2] |
| + | enabled = true | ||
| + | logpath = / | ||
| + | port = all | ||
| + | protocol = all | ||
| + | banaction = iptables-allports | ||
| + | filter = vpnserver | ||
| + | </ | ||
| - | failregex = .*\[UFW BLOCK\] IN=.* SRC=< | + | Po restartu služby lze jail ověřit takto: |
| - | + | ||
| - | ignoreregex = | + | |
| + | <code bash> | ||
| + | systemctl restart fail2ban | ||
| + | fail2ban-client status vpnserver | ||
| </ | </ | ||
| - | + | ===== Vyřazení IP adresy z banlistu ===== | |
| - | Dále pro **/ | + | |
| <code bash> | <code bash> | ||
| - | [INCLUDES] | + | fail2ban-client set vpnserver unbanip 89.24.33.115 |
| - | before = common.conf | + | fail2ban-client unban 89.24.33.115 |
| - | + | ||
| - | [Definition] | + | |
| - | _groupsre = (?: | + | |
| - | failregex = ^\{%(_groupsre)s,? | + | |
| - | datepattern = ,? | + | |
| - | ignoreregex = | + | |
| </ | </ | ||
| + | ===== Vypsání všech zabanovaných adres ===== | ||
| - | Našel jsem i vlastní ssh - **/ | + | < |
| - | + | fail2ban-client banned | |
| - | < | + | |
| - | ^Connection closed by < | + | |
| </ | </ | ||
| - | Tady obsah celého souboru. | + | ===== Akce v action.d ===== |
| - | < | + | |
| - | # Fail2Ban filter for openssh | + | |
| - | # | + | |
| - | # If you want to protect OpenSSH from being bruteforced by password | + | |
| - | # authentication then get public key authentication working before disabling | + | |
| - | # PasswordAuthentication in sshd_config. | + | |
| - | # | + | |
| - | # | + | |
| - | # " | + | |
| - | # | + | |
| - | [INCLUDES] | + | Na serverech s UFW jsem řešil i reakci na portscan. K tomu jsem si upravoval akci odvozenou z '' |
| - | # Read common prefixes. If any customizations available | + | Příklad akce '' |
| - | # common.local | + | |
| - | before = common.conf | + | |
| - | + | ||
| - | [DEFAULT] | + | |
| - | + | ||
| - | _daemon = sshd | + | |
| - | + | ||
| - | # optional prefix (logged from several ssh versions) like " | + | |
| - | __pref = (?: | + | |
| - | # optional suffix (logged from several ssh versions) like " \[preauth\]" | + | |
| - | __suff = (?: \[preauth\])? | + | |
| - | __on_port_opt = (?: port \d+)?(?: on \S+(?: port \d+)?)? | + | |
| - | + | ||
| - | # for all possible (also future) forms of "no matching (cipher|mac|MAC|compression method|key exchange method|host key type) found", | + | |
| - | # see ssherr.c for all possible SSH_ERR_..._ALG_MATCH errors. | + | |
| - | __alg_match = (?:(?:\w+ (? | + | |
| + | <code ini> | ||
| [Definition] | [Definition] | ||
| - | prefregex | + | actionban |
| + | ufw prepend | ||
| + | ufw prepend allow proto tcp from <ip> to < | ||
| - | cmnfailre | + | actionunban |
| - | ^User not known to the underlying authentication module for < | + | ufw delete |
| - | ^Failed \S+ for invalid user < | + | ufw delete allow proto tcp from <ip> to <destination> port 80, |
| - | ^Failed \b(? | + | |
| - | ^<F-USER> | + | |
| - | ^[iI](?: | + | |
| - | ^User < | + | |
| - | ^User <F-USER> | + | |
| - | ^User < | + | |
| - | ^Connection closed by <HOST> port \d+ \[preauth\]$ | + | |
| - | ^refused connect from \S+ \(< | + | |
| - | ^Received < | + | |
| - | ^User < | + | |
| - | ^User < | + | |
| - | ^pam_unix\(sshd: | + | |
| - | ^(error: )?maximum authentication attempts exceeded for < | + | |
| - | ^User < | + | |
| - | ^< | + | |
| - | ^< | + | |
| - | ^< | + | |
| - | ^< | + | |
| - | mdre-normal | + | [Init] |
| + | insertpos | ||
| + | blocktype = deny | ||
| + | destination = any | ||
| + | application = | ||
| + | </ | ||
| - | mdre-ddos | + | ===== Filtry ve filter.d ===== |
| - | ^Connection < | + | |
| - | ^< | + | |
| - | ^Read from socket failed: Connection < | + | |
| - | mdre-extra = ^Received < | + | Kromě SoftEtheru jsem používal i vlastní filtry pro Nextcloud, UFW portscan |
| - | ^Unable to negotiate with < | + | |
| - | ^Unable to negotiate | + | |
| - | ^no matching < | + | |
| - | mdre-aggressive = %(mdre-ddos)s | + | Filtr pro portscan: |
| - | %(mdre-extra)s | + | |
| - | + | ||
| - | cfooterre = ^< | + | |
| - | + | ||
| - | failregex = %(cmnfailre)s | + | |
| - | < | + | |
| - | %(cfooterre)s | + | |
| - | + | ||
| - | # Parameter " | + | |
| - | # Usage example (for jail.local): | + | |
| - | # | + | |
| - | # mode = extra | + | |
| - | # # or another jail (rewrite filter parameters of jail): | + | |
| - | # | + | |
| - | # | + | |
| - | # | + | |
| - | mode = normal | + | |
| - | + | ||
| - | #filter = sshd[mode=aggressive] | + | |
| - | + | ||
| - | ignoreregex = | + | |
| - | + | ||
| - | maxlines = 1 | + | |
| - | + | ||
| - | journalmatch = _SYSTEMD_UNIT=sshd.service + _COMM=sshd | + | |
| - | + | ||
| - | datepattern = {^LN-BEG} | + | |
| - | + | ||
| - | # DEV Notes: | + | |
| - | # | + | |
| - | # " | + | |
| - | # it is coming before use of < | + | |
| - | # and later catch-all' | + | |
| - | # | + | |
| - | # | + | |
| - | # Author: Cyril Jaquier, Yaroslav Halchenko, Petr Voralek, Daniel Black and Sergey Brester aka sebres | + | |
| - | # Rewritten using prefregex (and introduced " | + | |
| + | <code ini> | ||
| + | [Definition] | ||
| + | failregex = .*\[UFW BLOCK\] IN=.* SRC=< | ||
| + | ignoreregex = | ||
| </ | </ | ||
| - | **/ | + | Filtr pro Nextcloud: |
| - | < | + | < |
| [INCLUDES] | [INCLUDES] | ||
| before = common.conf | before = common.conf | ||
| [Definition] | [Definition] | ||
| - | # | + | _groupsre |
| - | failregex = UFW BLOCK.* SRC=< | + | failregex = ^\{%(_groupsre)s,? |
| + | datepattern = ,? | ||
| ignoreregex = | ignoreregex = | ||
| - | |||
| </ | </ | ||
| - | ==== Testování regulárního výrazu vlastního | + | U SSH jsem měl vlastní variantu |
| - | Tady je ukázka, jak lze otestovat vlastní filtr. | + | < |
| - | + | ^Connection closed by < | |
| - | < | + | |
| - | fail2ban-regex | + | |
| </ | </ | ||
| + | ===== Nastavení jail.local ===== | ||
| - | ===== Editace fail2ban.conf ===== | + | Základ globální konfigurace: |
| - | Tady popisuji hodnoty, které jde oproti defaultnímu nastavení změnil. | + | < |
| - | + | bantime | |
| - | < | + | findtime = 10m |
| - | dbpurgeage | + | maxretry |
| </ | </ | ||
| - | ===== Editace jail.local ===== | + | Na některých strojích jsem používal '' |
| - | + | < | |
| - | Nejprve je třeba v souboru jail.local nastavit banaction i na ipv6 a bannování skrz ipset. V provozu může vzniknout docela dost ip adres, které je třeba bannovat, tak bude rozumné kvůli rychlosti firewallu použít ipset místo defaultního nastavení: | + | |
| - | + | ||
| - | < | + | |
| banaction = iptables-ipset-proto6 | banaction = iptables-ipset-proto6 | ||
| banaction_allports = iptables-ipset-proto6-allports | banaction_allports = iptables-ipset-proto6-allports | ||
| </ | </ | ||
| - | Zkoušel jsem zvolit banaction = ufw, ale tady se zabanovala celá ip adresa a já chci blokovat pouze konkrétní službu. Zejména co se ssh týče. | + | SSH s agresivnějším módem |
| - | + | ||
| - | Služby, na kterých má fail2ban vyset se musí zapnout pomocí enabled = true. U SSH jsem volil mód aggressive. Blokace je 10 minut pro všechny služby, pokud zkusí 3 a více pokusů za posledních 10 minut. | + | |
| - | + | ||
| - | < | + | |
| - | # " | + | |
| - | bantime | + | |
| - | + | ||
| - | # A host is banned if it has generated " | + | |
| - | # seconds. | + | |
| - | findtime | + | |
| - | + | ||
| - | # " | + | |
| - | maxretry = 3 | + | |
| - | </ | + | |
| - | + | ||
| - | + | ||
| - | Tady se odehrává zbytek nastavení fail2ban. Sepisuji zejména změny, které jsem provedl. U SSH jsem si změnil port a to je potřeba promítnout i v konfiguraci. Je tam vidět port 3333. | + | |
| - | + | ||
| - | < | + | |
| - | + | ||
| - | ignoreip = 127.0.0.1/8 ::1 | + | |
| + | <code ini> | ||
| [sshd] | [sshd] | ||
| - | |||
| - | # To use more aggressive sshd modes set filter parameter " | ||
| - | # normal (default), ddos, extra or aggressive (combines all). | ||
| - | # See " | ||
| mode = aggressive | mode = aggressive | ||
| port = ssh,3333 | port = ssh,3333 | ||
| Řádek 329: | Řádek 166: | ||
| backend = %(sshd_backend)s | backend = %(sshd_backend)s | ||
| enabled = true | enabled = true | ||
| - | |||
| - | [nextcloud] | ||
| - | |||
| - | enabled | ||
| - | port = http,https | ||
| - | filter | ||
| - | logpath | ||
| - | maxretry = 6 | ||
| - | |||
| - | |||
| - | #[ufwban] | ||
| - | #enabled = false | ||
| - | #port = ssh, http, https | ||
| - | #filter = ufwban | ||
| - | #logpath = / | ||
| - | #action = ufw | ||
| - | |||
| </ | </ | ||
| - | Dále jsem přidal sshd-slow, který zabanuje ssh pro případ, že se za 1 den někdo zkusí celkem 10x přihlásit. V tomto případě zablokuje na 1week. To už je docela problematický prohřešek. | + | Pomalejší dlouhodobý ban pro opakované pokusy: |
| - | + | ||
| - | < | + | |
| + | <code ini> | ||
| [sshd-slow] | [sshd-slow] | ||
| - | filter | + | filter |
| - | port = ssh, 3333 | + | port |
| maxretry = 6 | maxretry = 6 | ||
| findtime = 1d | findtime = 1d | ||
| Řádek 361: | Řádek 180: | ||
| backend | backend | ||
| enabled | enabled | ||
| + | </ | ||
| + | Nextcloud: | ||
| - | [vpnserver] | + | <code ini> |
| - | enabled = true | + | [nextcloud] |
| - | port | + | enabled |
| - | protocol | + | port |
| - | logpath | + | filter |
| - | banaction = iptables-allports | + | logpath |
| - | # Uncomment the following line if you want to be notified about banned IP's | + | maxretry |
| - | action= %(action_mwl)s | + | |
| - | filter=vpnserver | + | |
| - | + | ||
| - | + | ||
| - | [vpnserver-securenat] | + | |
| - | enabled = true | + | |
| - | logpath = / | + | |
| - | port = all | + | |
| - | protocol = all | + | |
| - | banaction = iptables-allports | + | |
| - | # Uncomment the following line if you want to be notified about banned IP's | + | |
| - | action= %(action_mwl)s | + | |
| - | filter=vpnserver | + | |
| </ | </ | ||
| - | Pozapínal jsem další smysluplné věci, jako apache, fakegoogle boty atp. | + | Recidive jail: |
| - | Zapnul jsem i recidive. Pokud někdo bude mít ban 3x za 12 hodin, bude celá IP adresa zablokovaná na 1 týden. Tady budu muset být opatrný a kontrolovat, | + | < |
| - | + | [recidive] | |
| - | < | + | enabled |
| - | [recidive] | + | logpath |
| - | enabled = true | + | |
| - | logpath | + | |
| banaction = %(banaction_allports)s | banaction = %(banaction_allports)s | ||
| - | bantime | + | bantime |
| - | findtime = 12h | + | findtime |
| </ | </ | ||
| - | Poslední, co jsem aplikoval je ochrana na portscan. Tady je to opět potenciálně nebezpečná záležitost u webserveru. V praxi to prochází log, hledá jednoduchý | + | Portscan přes UFW: |
| - | Problémy jsou tam tyto: | + | < |
| - | * Nečíslovaný seznamNečíslovaný seznamufw mám na loglevel = low, takže když někdo oskenuje všechny porty, tak se neprovedou tisíce záznamů do logu, ale jenom pár. Zvyšovat hodnotu zase nemá smysl kvůli zpomalení sítě a serveru. | + | |
| - | * pokud mi tam bude padat moc IP adres, tak ufw nebude dobrá volba, kvůli velkému počtu IP adres. Může pak dojít ke zpomalení. Tady je řešení vytvořit v **action.d/ | + | |
| - | + | ||
| - | < | + | |
| [ufw-port-scan] | [ufw-port-scan] | ||
| - | enabled = true | + | enabled |
| - | filter | + | filter |
| - | logpath = / | + | logpath |
| banaction = ufw-portscan | banaction = ufw-portscan | ||
| - | bantime | + | bantime |
| - | maxretry | + | maxretry |
| - | findtime | + | findtime |
| </ | </ | ||
| + | ===== Testování filtrů ===== | ||
| - | zdroje ohledně aplikace portscanu: | + | Pro ověření regulárního výrazu se hodí: |
| - | + | ||
| - | * https:// | + | |
| - | * https:// | + | |
| - | + | ||
| - | ===== Vyřazení IP adresy z banlistu ===== | + | |
| <code bash> | <code bash> | ||
| - | fail2ban-client set vpnserver unbanip 89.24.33.115 | + | fail2ban-regex / |
| - | fail2ban-client unban 89.24.33.115 | + | |
| </ | </ | ||
| - | ===== Vypsání všech zabanovaných adres ===== | + | ===== Zdroje |
| - | <code bash> | + | * [[https:// |
| - | fail2ban-client banned | + | * [[https:// |
| - | </code> | + | * [[https:// |
| + | * [[https:// | ||
| + | * [[https:// | ||