fail2ban durch den Linux-Agenten ersetzen
Wie ein Host ohne Lücke von fail2ban zum Agenten wechselt: zuerst prüfen, was die Firewall-Objekte schon besitzt, eine Weile beides betreiben, dann fail2ban endgültig abschalten, und wie es in Sekunden zurückgeht, falls es sein muss.
fail2ban ersetzen
Der Agent stellt sich nicht neben fail2ban, er übernimmt. fail2ban bleibt als eine Quelle unter vielen verfügbar, ein Host, der es noch betreibt, meldet seine Sperren also weiter, und ein Host ohne fail2ban verliert nichts: für jede Angriffsart, die früher über ein Jail kam, liest jetzt ein Detektor das Originallog.
Gemessen über elf Tage auf einem Produktionshost: der Agent fand 187 der 189 Adressen, die fail2ban
auf derselben Maschine gesperrt hatte, die zwei fehlenden waren von Hand eingespeiste Testadressen,
er meldete 78 weitere Adressen, die unter den Schwellwerten von fail2ban geblieben waren, und er traf
die FTP-Sperren drei von drei. Die Eskalation für Wiederholungstäter kommt aus der eigenen
Bann-Historie des Agenten, und reportedip-agent test <file> tritt an die Stelle
von fail2ban-regex.
Zuerst prüfen, ob schon etwas diese Namen besitzt
Das hat auf einer Produktionsflotte einen Nachmittag gekostet, deshalb steht es vor allem anderen.
Ein handgeschriebenes Firewall-Skript der Art, wie diese Seite es früher dokumentiert hat, kann
genau die Namen benutzen, die der Agent benutzt. Vorgefunden wurden die Sets
rip-whitelist, rip-ssh, rip-mail, rip-web,
rip-ftp und rip-edge sowie eine Kette rip-blacklist, mit
-A INPUT -j rip-blacklist eingehängt, stündlich von einem Cronjob neu gebaut und
nahezu zeichengleich mit der Kette, die der Agent selbst aufbaut.
Auf so einem Host ist die übliche Reihenfolge in beide Richtungen falsch. Der erste Sync des Agenten
baut die Kette neu und ersetzt die bestehenden DROP-Regeln. Auf einem
Host, der mit --mode log installiert wurde, ersetzt er sie durch LOG-Regeln,
und damit ist der Host ungeschützt, bis der alte Cronjob wieder läuft, also bis zu eine Stunde später. Und wenn dieser Job läuft, baut er die Kette auf seine Weise neu und
entfernt dabei die rip-local-Regel des Agenten. Zwei Programme, eine Kette, und jedes
hebt stündlich die Arbeit des anderen auf.
Prüfen Sie also vor dem ersten Sync, und wenn die Namen kollidieren, installieren Sie diesen Host
nicht mit --mode log. Installieren Sie den Agenten, was keine Regel anfasst,
übernehmen Sie die alte Whitelist, schalten Sie den alten Cronjob ab, und lassen Sie erst dann den
ersten Sync laufen, mit mode: drop, dem Default. Eine Beobachtungsphase mit
--mode log gehört auf Hosts, auf denen keine Namen kollidieren.
# 1. Does something already own these names?
ipset list -n | grep "^rip-"
iptables -S INPUT | grep rip-
iptables -S rip-blacklist 2>/dev/null | head
crontab -l | grep -iE "ipset|blacklist|reportedip"
ls -l /etc/cron.d/ /etc/cron.hourly/ 2>/dev/null
# 2. If yes, take the old whitelist over FIRST. The feed can be
# downloaded again; that list cannot.
ipset list rip-whitelist | sed -n "/^Members/,\$p" | tail -n +2 > /tmp/rip-wl
ipset list rip-whitelist-v6 | sed -n "/^Members/,\$p" | tail -n +2 >> /tmp/rip-wl
wc -l /tmp/rip-wl
while read -r a; do
[ -n "$a" ] && reportedip-agent whitelist add "$a" "imported from the old script"
done < /tmp/rip-wl
reportedip-agent whitelist list | wc -l
# 3. Disable the old job, then hand the chain over in one step.
crontab -l | grep -v blacklist | crontab - # or: rm /etc/cron.d/<job>
# Only if the agent was installed with --mode log:
sed -i "s/^mode: log/mode: drop/" /etc/reportedip-agent/config.yaml
reportedip-agent sync
reportedip-agent status
reportedip-agent whitelist list zurück.
Eine Weile beides betreiben
Beides zu betreiben ist gefahrlos und der sinnvolle Weg einer Migration. Der Agent schreibt nie nach
/etc/fail2ban, und fail2ban weiß nichts von rip--Sets, die zwei nutzen also
getrennte Ketten und getrennte Zustände. Zwei Regeln, die dieselbe Adresse verwerfen, kosten einen
Paketvergleich.
Das eine, was Sie nicht tun sollten, ist dasselbe Ereignis zweimal zu melden. Wenn Sie die fail2ban-Action, die Sperren über HTTP schickt, behalten und fail2ban als Agent-Quelle konfigurieren, verlässt jede Sperre den Host zweimal und wird zweimal aus Ihrem Tageskontingent bezahlt. Nehmen Sie den Agenten oder die Action.
Installieren Sie mit REPORTEDIP_FAIL2BAN_SOURCE=0, wenn Sie fail2ban
ersetzen. Der Installer erkennt ein laufendes fail2ban und schreibt es als Quelle, was für
einen Host richtig ist, der es behält, und für eine Migration falsch: ist fail2ban weg, ist auch das
Log weg, auf das diese Quelle zeigt. Die Variable lässt die Quelle weg, und ohne sie druckt die
Installation eine Zeile, die sagt, dass die Quelle da ist und was nach dem Entfernen mit ihr zu tun
ist. Auf einem Host, der schon installiert ist, nehmen Sie den Eintrag fail2ban unter
sources von Hand heraus und stoppen und starten dann den Watch-Dienst.
# What did fail2ban ban, and what does the agent make of the
# same logs? Same file, same window, two verdicts.
fail2ban-client status sshd
reportedip-agent test /var/log/auth.log
# Per jail, then the agent over the file behind it
for j in $(fail2ban-client status | sed -n "s/.*Jail list:\t*//p" | tr -d " " | tr "," " "); do
echo "== $j"; fail2ban-client status "$j" | grep -E "Total banned|Currently banned"
done
reportedip-agent status | sed -n "/^sources:/,/^queue:/p"
fail2ban endgültig abschalten
Machen Sie das, wenn Sie die zwei ein paar Tage verglichen haben und die Quellenliste des Agenten jedes Jail abdeckt, das Sie hatten.
# 1. Stop it and keep it stopped.
systemctl stop fail2ban
systemctl disable fail2ban
# 2. Remove the fail2ban source from the agent config, then stop
# and start the daemon. A restart is not enough for a removed
# source: the daemon keeps tailing the old file.
$EDITOR /etc/reportedip-agent/config.yaml
systemctl stop reportedip-agent.service
systemctl start reportedip-agent.service
# 3. Check what fail2ban left in the kernel, in both address
# families. Stopping it does not always clean up: a jail that
# once used an iptables action leaves old-style f2b- chains behind.
nft list tables | grep f2b || echo "no f2b table"
iptables -S | grep "f2b-" || echo "no f2b chain (v4)"
ip6tables -S | grep "f2b-" || echo "no f2b chain (v6)"
ipset list -n | grep f2b || echo "no f2b set"
# 4. Remove the leftovers from the RUNNING ruleset. The jump rule
# carries -p and --dports, so it is deleted by its full text; a
# plain -D INPUT -j f2b-sshd does not match it, and the chain then
# refuses to go ("Device or resource busy"). Measured on a fleet:
# the v6 leftover was the one that stayed.
nft delete table inet f2b-table 2>/dev/null
for T in iptables ip6tables; do
$T -S INPUT | grep "f2b-" | sed "s/^-A INPUT //" | while read -r rule; do eval "$T -D INPUT $rule"; done
for c in $($T -S | awk "/^-N f2b-/{print \$2}"); do $T -F "$c" && $T -X "$c"; done
done
# 5. And from the SAVED one, or they come back at the next boot.
# Save without the rip- lines as well: the agent rebuilds its chain
# at every sync, and a saved rule that names a rip- set which does
# not exist yet at boot makes iptables-restore fail as a whole.
iptables-save | grep -v -e "f2b-" -e "rip-" > /etc/iptables/rules.v4
ip6tables-save | grep -v -e "f2b-" -e "rip-" > /etc/iptables/rules.v6
# 6. Confirm the agent is happy without it.
reportedip-agent status | grep -i fail2ban
reportedip-agent status; echo "exit $?"
f2b--Ketten nur
aus dem laufenden Ruleset löschen, stellt netfilter-persistent sie bei jedem Boot
aus /etc/iptables/rules.v4 und aus /etc/iptables/rules.v6
wieder her. Sie kommen leer zurück, verwerfen also nichts und sehen harmlos aus, und in einem
Jahr stehen sie noch da und verwirren den Nächsten, der das Ruleset liest. Prüfen Sie beide
Dateien: auf einem Host lagen die Reste nur in der v6-Datei, und wer allein
rules.v4 durchsucht, läuft daran vorbei. Erst das laufende Ruleset aufräumen, dann
speichern, und nach einem Reboot nachsehen.
Ein Rollback ist ein Befehl und dauert Sekunden, denn der Agent hat /etc/fail2ban nie
angefasst: systemctl enable --now fail2ban bringt jedes Jail und seine eigene Tabelle
zurück, und der Agent bleibt davon unberührt. Auf einem Live-Host gemessen waren alle elf Jails nach
acht Sekunden wieder da.
Zuletzt aktualisiert: · Betreut vom ReportedIP-Team