Problema
Hai utenti che vuoi bannare/bloccare dai tuoi server web usando Fail2Ban ma i tuoi server web sono dietro un proxy, quindi tutto il traffico sembra provenire dall'IP/interfaccia del server proxy.
Idealmente dovresti avere regole di apprendimento sul tuo proxy o sul sistema di bilanciamento del carico in cui puoi filtrare/valutare/intraprendere automaticamente azioni, ma potrebbe non essere sempre così.
La maggior parte delle persone che incontrano questo problema arrivano fino alla prima parte della soluzione, ma poi rimangono sconcertate quando usano Fail2Ban e ancora non funziona.
Per il resto di questo post mi riferirò a Proxy/Load Balancer semplicemente come LB, principalmente perché questa soluzione è stata sviluppata per tre server Web dietro un sistema di bilanciamento del carico.
Modifica il tuo LB
Assicurati che il tuo LB sia impostato per aggiungere l'intestazione http "X-Forwarded-For".
Il modo in cui lo abiliti dipenderà dal tuo LB e non rientra nell'ambito di questo post.
Modifica le configurazioni di Apache del server Web
In particolare sulla registrazione. Vogliamo assicurarci che Fail2Ban possa identificare l'IP "corretto" per bannarlo con successo.
Di solito uso un formato di registro personalizzato e aggiungo i dettagli X-Forwarded-For alla fine in un blocco facile da identificare, questo appare nei registri alla fine come "[XF www.xxx.yyy.zzz]"
Per fare ciò, utilizzo le seguenti direttive nella definizione di vhost in Apache:
CustomLog /path/to/logs/access_log "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\" \"[XF %{X-Forwarded-For}i]\""
Inizierai quindi a vedere i log come segue:
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]"
Quindi quello che ci interessa qui è che la richiesta provenga dall'IP esterno 10.10.1.1 (sì, lo so che è uno spazio di indirizzi privato ma per questo post non userò indirizzi IP "reali")
Crea la tua ricetta per il filtro Fail2Ban
Ci sono tre parti di questo, il filtro, la "prigione" e l'azione IPTable personalizzata.
Filtro
Crea il tuo filtro in fail2ban/filter.d di conseguenza:
# 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 =
Azione
Crea la tua azione IPtables personalizzata in fail2ban/action.d di conseguenza:
# 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
La differenza tra questo e un normale IPTables DROP è che dobbiamo eseguire un'ispezione dei pacchetti dove cerchiamo l'X-Forwarded-For e l'indirizzo IP pertinente nel pacchetto prima di eliminarlo. In genere dovrebbe funzionare, ma il tuo chilometraggio potrebbe variare.
Carcere
Ora puoi mescolare insieme la tua ricetta e inserirla nel tuo fail2ban/jail.local file
[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
Quindi qui consentiremo 5 tentativi di accesso in un minuto, dopodiché sarai bloccato dal server per 15 minuti.
Ricarica fail2ban e il gioco è fatto!