Fail2ban
Fail2ban je nástroj pro dynamické blokování IP adres na základě logů služeb. Typicky se používá pro ochranu proti brute-force útokům na SSH, VPN, webové přihlášení nebo pro reakci na portscan.
Instalace
apt install fail2ban cd /etc/fail2ban cp jail.conf jail.local
SoftEther VPN
Pro SoftEther VPN je nejdřív potřeba zajistit, aby se neúspěšná přihlášení zapisovala do jednoho stabilního logu. V vpncmd jsem pro konkrétní hub nastavil:
VPN Server/DEFAULT> logswitchset LogSwitchSet command - Set Log File Switch Cycle Select Security or Packet: security Specify sec, min, hour, day, month or none: none
Výsledkem je soubor sec.log, například:
ls -l /usr/vpnserver/security_log/DEFAULT/
Pak stačí filtr a jail.
Filtr /etc/fail2ban/filter.d/vpnserver.conf:
[INCLUDES] before = common.conf [Init] maxlines = 2 [Definition] failregex =IP address: <HOST>.*\n.*User authentication failed.* ignoreregex=
Příklad jail.local pro dva huby:
[vpnserver] enabled = true logpath = /usr/vpnserver/security_log/DEFAULT/sec.log port = all protocol = all banaction = iptables-allports filter = vpnserver [vpnserver-HUB2] enabled = true logpath = /usr/vpnserver/security_log/HUB2/sec.log port = all protocol = all banaction = iptables-allports filter = vpnserver
Po restartu služby lze jail ověřit takto:
systemctl restart fail2ban fail2ban-client status vpnserver
Vyřazení IP adresy z banlistu
fail2ban-client set vpnserver unbanip 89.24.33.115
fail2ban-client unban 89.24.33.115
Vypsání všech zabanovaných adres
fail2ban-client banned
Akce v action.d
Na serverech s UFW jsem řešil i reakci na portscan. K tomu jsem si upravoval akci odvozenou z ufw.conf, aby uměla pracovat i s IPv6 a současně nezablokovala žádoucí porty 80 a 443.
Příklad akce ufw-portscan.conf:
[Definition] actionban = [ -n "<application>" ] && app="app <application>" ufw prepend <blocktype> from <ip> $app ufw prepend allow proto tcp from <ip> to <destination> port 80,443 $app actionunban = [ -n "<application>" ] && app="app <application>" ufw delete <blocktype> from <ip> $app ufw delete allow proto tcp from <ip> to <destination> port 80,443 $app [Init] insertpos = 1 blocktype = deny destination = any application =
Filtry ve filter.d
Kromě SoftEtheru jsem používal i vlastní filtry pro Nextcloud, UFW portscan a agresivnější SSH.
Filtr pro portscan:
[Definition] failregex = .*\[UFW BLOCK\] IN=.* SRC=<HOST> ignoreregex =
Filtr pro Nextcloud:
[INCLUDES] before = common.conf [Definition] _groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*) failregex = ^\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed: datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?" ignoreregex =
U SSH jsem měl vlastní variantu filtru, která navíc banuje i preauth uzavření spojení:
^Connection closed by <HOST> port \d+ \[preauth\]$
Nastavení jail.local
Základ globální konfigurace:
bantime = 10m findtime = 10m maxretry = 3
Na některých strojích jsem používal iptables-ipset-proto6, aby se při větším počtu blokovaných IP nezpomaloval firewall:
banaction = iptables-ipset-proto6 banaction_allports = iptables-ipset-proto6-allports
SSH s agresivnějším módem a vlastním portem:
[sshd] mode = aggressive port = ssh,3333 filter = mysshd logpath = %(sshd_log)s backend = %(sshd_backend)s enabled = true
Pomalejší dlouhodobý ban pro opakované pokusy:
[sshd-slow] filter = sshd[mode=aggressive] port = ssh,3333 maxretry = 6 findtime = 1d bantime = 1w logpath = %(sshd_log)s backend = %(sshd_backend)s enabled = true
Nextcloud:
[nextcloud] enabled = true port = http,https filter = nextcloud logpath = /var/www/nextcloud/data/nextcloud.log maxretry = 6
Recidive jail:
[recidive] enabled = true logpath = /var/log/fail2ban.log banaction = %(banaction_allports)s bantime = 1w findtime = 12h
Portscan přes UFW:
[ufw-port-scan] enabled = true filter = portscan logpath = /var/log/ufw.log banaction = ufw-portscan bantime = 1w maxretry = 300 findtime = 3h
Testování filtrů
Pro ověření regulárního výrazu se hodí:
fail2ban-regex /var/log/ufw.log '.*\[UFW BLOCK\] IN=.* SRC=<HOST>'