[Eisfair] [eisfair-1/eisfair-2/eisxen] brute_force_blocking (BFB) 0.3.9 released

Raphael Gradenwitz raphael at gradenwitz.ath.cx
Mo Jan 2 18:05:15 CET 2012


Hi Olaf,

Am 29.09.2011 23:40, schrieb Olaf Jaehrling:
> ich habe eine neue Version von BFB veröffentlicht. In dieser Version
> wurde ein schwere Fehler behoben, der Auftrat, wenn MONITOR_PORTSCAN=no
> und BFB_BLOCK_PROACTIVE_FROM_ATMA=yes stand. In dieser Konstellation
> lief das init-script ein eine Endlosschleife.

die Skripte sind leider immer noch mit Fehlern gespickt! Zu viel es hier
auf zu zählen, ich kann kaum ein Skript von dir öffnen ohne mindestens
einen mehr oder weniger schlimmen Fehler zu sehen. Sie kommen nur
einfach nicht nach oben, weil sie durch die falsche syntax sich selber
praktisch deaktivieren dessen Meldungen ja ausserdem fast überall nach
/dev/null umgeleitet werden. Oder es handelt sich einfach um Sinnfreie
zeilen.

Im Init-Script wird jetzt wieder nur bei 'monitor_portscan=yes' der
Verweis auf die BOTBLOCK-Chain aus der INPUT-Chain entfernt. Das hat zur
Folge das die BOTBLOCK-Chain selber nicht entfernt werden kann, sie
jedoch bei einem Restart neu angelegt wird. So hat man nach jedem
Restart des Dienstes einen zusätzlichen Verweis auf die BOTBLOCK-Chain
in der INPUT-Chain. Das ist irgendwie Unschön und aber auch wieder ein
typisches Beispiel für die Art der Fehler die ich oben meinte.

Was bezweckst du eigentlich im Stop-teil dieser Funktion? Es sollen doch
alle vom bfb gesetzten Änderungen in den iptables-Regeln zurückgesetzt
werden, oder?

Bitte merke:

- Eine Chain kann erst gelöscht
iptables -X $chain
  werden wenn keine Verweise mehr auf die Chain zeigen.

- Ein Verweis auf eine Chain kann erst entfernt
iptables -D INPUT -j $chain
  werden wenn die Chain leer (geflusht) ist

Also muss zuerst die Chain geflusht werden:

iptables -F $chain

dann muss der verweis aus der INPUT- (bzw. ggf. aus der FORWARD-) Chain
entfernt werden und dann erst kann die Chain selber entfernt werden.
Sonst bleibt sie einfach bestehen und dann hat man nach jedem restart
des bfb einen verweis mehr. (so wie jetzt bei 'monitor_portscan=no')

Gehe doch wie folgt vor:

Zuerst flushe deine Chains, egal ob es sie gibt oder nicht, wenn du eh
stdout und stderr nach /dev/null umleitest stört das nicht.

Dann räume die Inputchain etwa wie folgt auf:

Greife dir alle Regeln BFB-Betreffend mit Regel-Nummer (--line-numbers)
ab und lege die in einem Array. Ich benutze hier mal das Kürzel 'rn' für
Regel-Nummer:

rn=(`iptables -nL INPUT --line-numbers|grep "expr"|awk '{print $1}'`)

(die "expr" kann also z.B. grep -E "(BFB|BOTBLOCK)" sein. Suche dir halt
eine Expression aus die genau alle Regeln und Verweise abgreift die dein
Paket betreffen.)

Nun iterierst du das Array von Hinten her (also die grösste Regelnummer
zuerst) durch:

if [ ${#rn[*]} -gt 1 ], then
    rn_i=${#rn[*]}
    while [ $rn_i -gt 0 ]; do
        let rulenum_i--
        iptables -D INPUT ${rn[$rn_i]}
    done
fi

Von Hinten her deshalb, weil ansonsten sich ja automatisch die
Regelnummern der höheren ständig ändern und dann löscht du nicht die
Regeln die du eigentlich löschen willst.

So. Nun müsste deine INPUT- (bzw. gleich behandelte FORWARD-) Chain
aufgeräumt sein und nun kannst du die Chains löschen

iptables -X $chain

Wie gesagt, aus der Hüfte geschossen. Selber musst du jetzt natürlich
noch alles abklopfen und mit sinnvollen echo's versehen die z.B. beim
debuggen oder bei einem Argument '--verbose' (z.B.) sichtbar und
ausgegeben werden, nicht bedingungslos nach /dev/null 2>&1 umleiten. Ich
weiss, das hatte ich damals in meinen Änderungen auch so belassen aber
das geht auch anders:

if [ ${#rn[*]} -gt 1 ]; then
    v_echo -n "[ removing ${#rn[*]} old references: "
    rn_i=${#rn[*]}
    while [ $rn_i -gt 0 ]; do
        let rn_i--
        if iptables -D INPUT ${rn[$rn_i]}; then
            v_echo -n "${rn[$rn_i]} done "
        else
            v_etecho -n "${rn[$rn_i]} failed "
    done
    v_echo "]"
fi

die Funktion v_echo (von verbose-echo) müsste dann etwa so aussehen,
angenommen das Argument --verbose setzt verbose=true:

v_echo() {
    local arg
    $verbose && {
        case $1 in -*) arg=$1; shift;; *) arg=; esac
        echo $arg "$*"
    }||:
}

Wenn ich Zeit finde, werde ich dir u.U. auch ein Paar der anderen mir
aufgefallenen Fehlern kommentiert und mit Verbesserungsvorschläge
zukommen lassen. Das sind aber soweit ich sehen konnte keine Fehlern die
Schaden anrichten können, weil sie sich zum beispiel selber
neutralisieren. Eventuell findest du die ja auch selber, jetzt sollte
ich ja dein Ehrgeiz geweckt haben, hoffe ich ;-)

Bitte bemerke, dies ist eine auf die schnelle geschriebene email, kein
sorgfältig abgeklopftes Skript. Also sind sicherlich kleine Fehler
enthalten aber vom Grundsatz her sollte es verständlich sein denke ich mal.

Liebe Grüße,
Raphael Gradenwitz


Mehr Informationen über die Mailingliste Eisfair