postfix: "gehackte" Benutzer automatisch sperren?

mkr

Registered User
Hallo zusammen

Mein Setup ist recht einfach: Postfix, User in MySQL, postfwd für die Limits.

In letzter Zeit kommt es hin und wieder vor, dass die Accounts von Benutzern gehackt werden. Also nicht auf dem Server gehackt und kein Brute-force (Benutzer werden zu "komplexen" Passwörtern gezwungen), sondern per Virus vom Outlook auf dem Client "geklaut".

Mit postfwd ist nach 500 Mails pro Benutzer Schluss und ich werde über die volle Warteschlange informiert.

Aber was fehlt, wofür ich immer noch keine Lösung habe, ist die automatische Sperrung des Benutzers. Man könnte fail2ban auf das Logfile von postfwd ansetzen und dann das Passwort auf einen Zufallswert setzen. Oder die Warteschlange auf Absender überprüfen und einen Benutzer sperren, wenn er mehr als x Einträge hat. Aber gibt es keine einfachere Möglichkeit? Wie macht ihr das?

Vielen Dank für Eure Vorschläge!
 
Hallo,

ich würde ein ähnliches Vorgehen wählen. Anstatt das Passwort zu ändern würde ich in der MySQL-Tabelle ein Feld hinzufügen und dieses auf 0 bzw. 1 setzen. In Postfix kannst du diese zusätzliche Condition hinzufügen.
 
Hallo bibabu

Vielen Dank für Deine Hilfe! Ich habe dies nun so umgesetzt.

Falls es jemand brauchen kann:
Die Regel für postfwd:
Code:
id=dailylimit; sasl_username=~/./; action=rate(sasl_username/500/86400/REJECT only 500 messages per day for $$sasl_username)

Der Filter für fail2ban:
Code:
failregex = .*rule=0, id=dailylimit, client=.*\[<HOST>\], user=.*REJECT only 500.*

Die Action für fail2ban:
Code:
actionban = /usr/bin/php -f /etc/fail2ban/disablemail.php <ip>

fail2ban kann leider nur auf den Host matchen, nicht auf den User. Deshalb liest das Script disablemail.php das Log rückwärts, bis es den Benutzernamen findet. Dann deaktiviert es den Benutzer und löscht alle Mails von ihm aus der Warteschlange:
Code:
<?php
// spammendes Konto deaktivieren
$ip = $argv[1];
$filename = '/var/log/mail.log';
$handle = @fopen($filename, 'r');
$pattern = "/.*postfwd2\/policy.*rule=0, id=dailylimit, client=.*\[$ip\], user=([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}),.*REJECT only 500.*/i";
$account = '';

// Logdatei rückwärts durchgehen, bis Adresse gefunden
for($i = 0; $i < 10000; $i++)
{
        $buffer = rfgets($handle);
        if(preg_match($pattern, $buffer, $matches))
        {
                $account = $matches[1];
                break;
        }
}
echo $account."\n";

if($account == '')
{
        exit('Benutzer nicht gefunden');
}

// Account in MySQL deaktivieren (SMTP, POP3, IMAP)
disableAccount($account);

// Mails von diesem Account aus der Warteschlange löschen
$cmd = 'mailq | tail -n +2 | awk '."'".'BEGIN { RS = "" } / '.$account.'/ { print $1 }'."'".' | tr -d '."'".'*!'."' | postsuper -d -";
shell_exec($cmd);

// Mail an Admin
mail("admin@domain.ch", "Konto deaktiviert", "Konto $account wurde deaktiviert wegen Spam.");

function disableAccount($account)
{
        $host = 'localhost';
        $db = 'postfix';
        $user = 'username';
        $pw = 'geheim';
        $link = mysql_connect($host, $user, $pw);
        $rs = mysql_select_db($db, $link);

        $query = "UPDATE postfix_users SET disabled=1 WHERE email='$account';";
        $result = mysql_query($query);
}

function rfgets($handle) {
    $line = null;
    $n = 0;

    if ($handle) {
        $line = '';

        $started = false;
        $gotline = false;

        while (!$gotline) {
            if (ftell($handle) == 0) {
                fseek($handle, -1, SEEK_END);
            } else {
                fseek($handle, -2, SEEK_CUR);
            }

            $readres = ($char = fgetc($handle));

            if (false === $readres) {
                $gotline = true;
            } elseif ($char == "\n" || $char == "\r") {
                if ($started)
                    $gotline = true;
                else
                    $started = true;
            } elseif ($started) {
                $line .= $char;
            }
        }
    }

    fseek($handle, 1, SEEK_CUR);
 return strrev($line);
}
?>

Falls jemand eine elegantere Lösung kennt: nur her damit! ;-)
 
Moin

Nur als Hinweis. Die Mails darfst Du nicht so ohne weiteres löschen (§ 206 Abs. 2).

Thorashh
 
@mkr
Benutzer deaktivieren mag ja noch angehen, aber dessen schon angenommene Mails löschen ist nicht erlaubt.
Die Mails sind nicht dein Eigentum.
 
Danke für eure Hinweise. Habe da gar nicht daran gedacht, denn Massenmails sind per AGB verboten und die Benutzer halten sich daran. Wenn ich 500 Mails von einem User in der Queue hatte, war es bis jetzt immer Spam. Werde die Mails nun auf "hold" setzen statt sie zu löschen, oder es gleich ganz sein lassen.
 
Moin

Nur als Hinweis. Die Mails darfst Du nicht so ohne weiteres löschen (§ 206 Abs. 2).

Thorashh

Ja das Thema ist schon eine alte Socke. Dennoch fand ich diesen Beitrag interessant und hätte dazu gleich eine Frage. Was ist mit der Löschung von E-Mails die Viren enthalten? Lieber nicht löschen und an den Empfänger sauber durchschicken? Das kann doch nicht sein.
 
@Mutschas: Du kannst sie bei einem Virenfund regulär abweisen. Dann nimmt sie der Server nicht an und hat gar nichts, was er löschen könnte. Und der Absender erfährt es wenigstens. Dafür muss der Virenscanner aber richtig eingebunden sein, während die SMTP-Sitzung noch aktiv ist.

Das funktioniert übrigens auch prima, wenn man die ausgehenden Mails scannt. Ist ein Virus drinnen, wird sie gar nicht angenommen und der User erhält in seinem Mailprogramm eine Fehlermeldung. Das könnte man natürlich auch in Kombination mit einem Spamfilter machen, der ab einem bestimmten Score anschlägt.


MfG Christian
 
Moin
Was ist mit der Löschung von E-Mails die Viren enthalten?
Das ist eine andere Situation.

Gehen wir mal davon aus, das Du die E-Mails scannen darfst.
In dem Fall darfst Du gefährliche E-Mails zurückhalten und musst diese nur an den Empfänger weiterreichen, wenn er das ausdrücklich wünscht (Stw.: Gefahrenabwehr). Dazu must Du ihn natürlich darüber informieren.
Löschen darfst Du die Mail trotzdem erst, wenn der Empfänger Dir das erlaubt hat. (Auch sowas kann man in seine AGB schreiben)

Deshalb ist ablehnen von E-Mails, also Scannen vor der Annahme (Stw.: Milter) immer die bessere Lösung.
 
Back
Top