Problém
Máte uživatele, kterým chcete zakázat / zablokovat přístup na své webové servery pomocí Fail2Ban, ale vaše webové servery jsou za proxy serverem, takže se zdá, že veškerý provoz pochází z IP/rozhraní proxy serveru.
V ideálním případě byste měli mít na svém proxy serveru nebo nástroji pro vyrovnávání zátěže pravidla učení, kde můžete automaticky filtrovat/hodnotit/provádět akce, ale nemusí to tak být vždy.
Většina lidí, kteří narazí na tento problém, se dostane až k první části řešení, ale pak jsou zmateni, když použijí Fail2Ban a stále to nefunguje.
Ve zbytku tohoto příspěvku budu označovat Proxy/Load Balancer jednoduše jako LB, hlavně proto, že toto řešení bylo vyvinuto pro tři webové servery za load balancerem.
Upravte svůj LB
Ujistěte se, že váš LB je nastaven tak, aby přidal http hlavičku „X-Forwarded-For“.
Jak to povolíte, bude záviset na vašem LB a je mimo rozsah tohoto příspěvku.
Upravte konfiguraci webového serveru Apache
Konkrétně kolem těžby dřeva. Chceme zajistit, aby Fail2Ban dokázal identifikovat „správnou“ IP a úspěšně ji zakázal.
Obvykle používám vlastní formát protokolu a na konec přidám podrobnosti X-Forwarded-For ve snadno identifikovatelném bloku, který se na konci zobrazí v protokolech jako „[XF www.xxx.yyy.zzz]“
K tomu používám následující direktivy v definici vhost v Apache:
CustomLog /path/to/logs/access_log "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\" \"[XF %{X-Forwarded-For}i]\""
Poté se začnou zobrazovat protokoly takto:
192.168.1.2 - - [29/Sep/2014:10:56:31 +0100] "POST /login.php HTTP/1.1" 200 15 "-" "curl/7.19.7 " "[XF 10.10.1.1]"
Takže to, co nás zde zajímá, je, že požadavek přichází z externí IP 10.10.1.1 (ano, vím, že je to soukromý adresní prostor, ale pro tento příspěvek nebudu používat „skutečné“ IP adresy)
Vytvořte si recept na filtr Fail2Ban
To má tři části, filtr, „vězení“ a vlastní akci IPTable.
Filtrovat
Vytvořte svůj filtr v fail2ban/filter.d podle toho:
# Fail2Ban configuration file # # Author: Centos.Tips # # $Revision: 1$ # [Definition] # Option: failregex # Notes.: Regexp to catch Apache brute force login attempts (using X-Forwarded-For) # Values: TEXT # failregex = POST .*/login.php.*\[XF <HOST> # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
Akce
Vytvořte si vlastní akci IPTables v fail2ban/action.d podle toho:
# Fail2Ban configuration file # # Author: Centos.Tips # # [INCLUDES] before = iptables-blocktype.conf [Definition] # Option: actionstart # Notes.: command executed once at the start of Fail2Ban. # Values: CMD # actionstart = iptables -N fail2ban-<name> iptables -A fail2ban-<name> -j RETURN iptables -I <chain> -p <protocol> --dport <port> -j fail2ban-<name> # Option: actionstop # Notes.: command executed once at the end of Fail2Ban # Values: CMD # actionstop = iptables -D <chain> -p <protocol> --dport <port> -j fail2ban-<name> iptables -F fail2ban-<name> iptables -X fail2ban-<name> # Option: actioncheck # Notes.: command executed once before each actionban command # Values: CMD # actioncheck = iptables -n -L <chain> | grep -q 'fail2ban-<name>[ \t]' # Option: actionban # Notes.: command executed when banning an IP. Take care that the # command is executed with Fail2Ban user rights. # Tags: See jail.conf(5) man page # Values: CMD # actionban = iptables -I fail2ban-<name> 1 -p tcp --dport 80 -m string --algo bm --string 'X-Forwarded-For: <ip>' -j DROP # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the # command is executed with Fail2Ban user rights. # Tags: See jail.conf(5) man page # Values: CMD # actionunban = iptables -D fail2ban-<name> -p tcp --dport 80 -m string --algo bm --string 'X-Forwarded-For: <ip>' -j DROP [Init] # Default name of the chain # name = default # Option: port # Notes.: specifies port to monitor # Values: [ NUM | STRING ] Default: # port = http # Option: protocol # Notes.: internally used by config reader for interpolations. # Values: [ tcp | udp | icmp | all ] Default: tcp # protocol = tcp # Option: chain # Notes specifies the iptables chain to which the fail2ban rules should be # added # Values: STRING Default: INPUT chain = INPUT
Rozdíl mezi tímto a normálním DROP IPTables je v tom, že musíme provést kontrolu paketů, kde hledáme X-Forwarded-For a příslušnou IP adresu v paketu, než jej zahodíme. To by mělo obecně fungovat, ale váš počet najetých kilometrů se může lišit.
Vězení
Nyní můžete smíchat svůj recept a vložit ho do fail2ban/jail.local soubor
[apache-proxy] enabled = true filter = apache-proxy action = iptables-proxy[name = apache-proxy, port = http, protocol = tcp] sendmail-whois[name=LoginDetect, [email protected], [email protected], sendername="Fail2Ban"] port = http logpath = /path/to/your/access_log maxretry = 5 findtime = 60 bantime = 900
Zde tedy povolíme 5 pokusů o přihlášení za minutu, poté budete na 15 minut zablokováni na serveru.
Znovu načtěte fail2ban a máte hotovo!