Hallo,
wir haben ein Ressourcen-Cluster welches auf mehreren Servern über einen lighttpd statische Ressourcen ausliefert. Seit ein paar Tagen haben wir das Problem, dass täglich willkürlich auf einen diesen Server eine DOS Attacke gefahren wird. Es wird einfach eine Ressource mehrere tausend mal pro Sekunde angefragt. Von einer einzigen IP. Ok, normalerweise ist das kein Problem. Da wir auf den Servern eh schon fail2ban laufen haben, habe ich einfach ich mir einfach einen Filter und eine Regel erstellt, welche so etwas abwehren sollte:
In /etc/fail2ban/filter.d/ eine neue config mit folgendem Inhalt angelegt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # Fail2Ban configuration file # [Definition] # Option: failregex # Note: This regex will match any GET entry in your logs, so basically all valid and not valid entries are a match. # You should set up in the jail.conf file, the maxretry and findtime carefully in order to avoid false positives. failregex = <HOST>.*GET # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex = |
Die jail.local um folgenden Inhalt erweitert:
1 2 3 4 5 6 7 8 9 | [http-get-dos] enabled = true port = http,https filter = http-get-dos logpath = /var/log/lighttpd/access.log maxretry = 300 findtime = 300 bantime = 3600 action = iptables[name=HTTP, port=http, protocol=tcp] |
Um das ganz zu verifizieren ob das auch klappt habe ich mit JMeter auf die Server "geschossen". Ich wurde in weniger als 10 Sekunden vom fail2ban gebannt.
Also dachte ich mir es klappt alles. Ein paar Tage war auch Ruhe. Heute Morgen wieder das gleiche Spiel wie immer. Sogar gleich auf 2 Servern. Das access.log vom lighhtpd läuft voll. Wieder massenhafte Aufrufe einer Ressource.
fail2ban erzeugt auf der Maschine eine sehr hohe Load. Gebannt wird sie aber nicht. Was ist da los?
Weiterhin bin ich irritiert, dass wenn ich die IP von Hand über iptables banne nichts passiert:
1 | sudo iptables -I INPUT -s 1.2.3.4 -j DROP |
Die Angriffe fahren einfach munter weiter. Ich habe das Gefühl, das hat etwas mit unserem Firewall-Skript zu tun:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | #!/bin/sh ### BEGIN INIT INFO # Provides: firewall # Required-Start: $network # Required-Stop: $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: starts the iptables firewall ### END INIT INFO IPTABLES="/sbin/iptables" #LOCALNET="192.168.0.0/16" . /lib/lsb/init-functions start () { log_daemon_msg "Starting firewall..." # Chains leeren und initialisieren log_progress_msg "Flushing chains and setting default policies..." $IPTABLES -F $IPTABLES -F -t nat $IPTABLES -X $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP $IPTABLES -P OUTPUT ACCEPT # Eingang log_progress_msg "Setting rules for INPUT chain..." # Statuslogging $IPTABLES -A INPUT -m state --state INVALID -j LOG --log-prefix "DROP INVALID " --log-ip-options --log-tcp-options $IPTABLES -A INPUT -m state --state INVALID -j DROP # Erlaube Verbindungen mit den Flags ESTABLISHED und RELATED. $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Zugelassene Eingänge: # SSH $IPTABLES -A INPUT -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT # HTTP $IPTABLES -A INPUT -p tcp --dport 80 --syn -m state --state NEW -j ACCEPT ### ### usw. hier folgen die ganzen offenen Ports ### # Ping erlauben $IPTABLES -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # Lokalen Verkehr erlauben $IPTABLES -A INPUT -i lo -j ACCEPT # Standardregel für Eingang $IPTABLES -A INPUT ! -i lo -j LOG --log-prefix "DROP " --log-ip-options --log-tcp-options # IP-Forwarding aktivieren #echo 1 > /proc/sys/net/ipv4/ip_forward # Forwarding für OpenVPN Clients #$IPTABLES -A FORWARD -i tun+ -j ACCEPT #$IPTABLES -A FORWARD -o tun+ -j ACCEPT # Standardregel für FORWARD $IPTABLES -A FORWARD ! -i lo -j LOG --log-prefix "DROP " --log-ip-options --log-tcp-options log_end_msg 0 } stop () { log_daemon_msg "Stopping firewall..." $IPTABLES -F $IPTABLES -F -t nat $IPTABLES -X $IPTABLES -P INPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IPTABLES -P OUTPUT ACCEPT log_end_msg 0 } case "$1" in start) start ;; stop) stop ;; restart|reload|force-reload) stop start ;; status) $IPTABLES -L -n ;; *) echo "Usage: $0 start|stop|restart|status" exit 3 ;; esac |
Das Skript liegt einfach im /etc/init.d/ Ordner.
2 Fragen:
1. Warum wird die IP nicht geblockt, wenn ich sie händisch droppe? 2. Hat jemand eine Idee, was mit Fail2ban nicht stimmt, dass es auf den Angriff nicht reagiert?
Vielen Dank und Liebe Grüße, Arny