ddm3ve wrote:damit der potentielle Angreifer erst nach Prüfung auf formale Kriterien und in diversen Blocklisten die Chance erhält sein Passwort zu erproben.[...]
Wie seht ihr das auch in Bezug auf Durchsatz und performance?
Das hängt davon ab, wie teuer die Authentifizierung bei Deinem Setup ist, und wie teuer die vorgelagerten Checks. Billig sind dabei Lookups in statischen Hash Tables, die ggf. auch noch im Arbeitsspeicher gecached werden. Teuer sind hingegen DNS-Abfragen, Datenbank- oder LDAP Lookups (je nach Konfiguration). So richtig teuer wären dann Virenscan oder Bayes-Filter. Ist die Authentifizierung über eine relativ günstige Technik realisiert (z. B. Hash Table), dann ist es unter Performance-Gesichtspunkten eine Prüfung, die früh (also z. B. vor eventuellen DSNBL Checks) erfolgen sollte.
Äh, definiere mal teuer...?!
Teuer (im Sinne von "reduziert/limitiert den Durchsatz") bedeutet, dass endlich vorhandene Ressourcen belegt/verbraucht werden, der Fortgang für eine gewisse Zeitspanne gestoppt oder ausgebremst wird - oder gleich beides. Endliche Ressourcen auf einem Rechner sind Rechenzeit, Arbeitsspeicher, Plattenzugriffe und File Pointer.
Ein DNS Lookup ist insofern teuer, als er einen File Pointer erzeugt (nämlich den Client Socket), und durch die Kommunikation mit einem Remote System einige zeitintensive (ggf. sogar timeout-behaftete) Operationen durchführt.
Kosten: Ein File Pointer und ggf. (sehr viel) Zeit, aber sehr wenig Rechenzeit und Arbeitsspeicher.
Ein Datenbank-Lookup benötigt bei Nutzung einer statischen Verbindung keinen zusätzlichen File Pointer, erzeugt aber ggf. I/O Last in Richtung Festplatte (selbst SSDs sind immer noch um Klassen langsamer als Arbeitsspeicher), einiges an Rechenlast (die Query muss geparsed und übersetzt werden), frisst ggf. Zeit (durch IPC-Operationen) und Arbeitsspeicher.
Worst Case: dynamische Connection, kein Query Cache und miese Tabellenstruktur (Full Table Scan bei jedem Lookup).
Ein Virenscan oder ein Spam-Filter sind dann so ziemlich die (einsame) Spitze der Ressourcenräuber. Im Worst Case (z. B. bei verschachtelten Archiven im Anhang der Mail) werden gleich dutzendweise File Pointer erzeugt, es entsteht massiv Disk I/O, ggf. werden gleich mehrfach DNS-Abfragen oder gar SMTP-Dialoge gestartet (SpamAssassin z. B. tut so etwas - je nach Konfiguration, versteht sich), und ein Bayes-Filter verbrät auch noch gewaltige Mengen an Arbeitsspeicher durch die lexikalische Analyse (für Suchbäume und so...). Und das alles natürlich immer schön über Prozessgrenzen hinweg, also mit hübsch vielen Context-Wechseln und ordentlich IPC.
Jetzt die Preisfrage: Wann ist eine Authentifizierung teuer (im Vergleich zu anderen Checks)?
Das hängt wesentlich von zwei Faktoren ab: Der Datenquelle, und der verwendeten
Key Derivation Function.
Zunächst zur Datenquelle: Eine statische Hash-Tabelle ist billig, da sie normalerweise nur einmal beim Start des MTAs eingelesen wird, also zur Laufzeit keinen File Pointer benötigt, keine IPC Timeouts auftreten und Signal-Laufzeiten keine Rolle spielen. Ein Datenbankserver als Quelle ist teuer, weil die Abfrage entweder beim RDBMS lokale Last verursacht, oder bei einem Remote System wieder die lange Dauer (durch Signallaufzeit und IPC Timeouts) zuschlägt. Ein LDAP-Server ist zwar durch seine Spezialisierung meist schneller als ein RDBMS, unterliegt aber gerade in Puncto IPC und Signallaufzeit denselben Restriktionen.
Jetzt zur KDF: Hier geht es um die Dauer der Berechnung. Schlechte KDFs lassen sich schnell berechnen, und skalieren mit der verfügbaren CPU-Leistung (z. B. einfache Hashes wie MD5, SHA1 .. SHA512 - mit und ohne Salz). Das macht sie billig in der Prüfung, aber auch billig beim Brechen - insbesondere MD5, SHA1, RipeMD160 und NTLM sind eine ziemlich blöde Idee[1][2][3]. Sicherer sind KDFs mit konstantem (oder zumindest vorhersagbarem) Laufzeitverhalten, wie etwa
PBKDF2,
bcrypt oder
scrypt (zur Not zählen auch noch SHA256-CRYPT und SHA512-CRYPT). Aber eben auch teurer, und zwar sowohl was Rechenleistung als auch Laufzeitverhalten anbelangt.
Eine "billige" Kombination wäre also eine statische Hash-Tabelle mit (gesalzenen) MD5 Passwort-Hashes. Eine solche Prüfung dürfte schneller sein als ein DNS Lookup und darf daher möglichst früh in der Verarbeitungskette stattfinden. Eine "teure" Kombination könnte etwa ein (remote) RDBMS mit einer guten KDF wie scrypt sein - diese Prüfung dauert mit an Sicherheit grenzender Wahrscheinlichkeit länger als jeder DNS Lookup, und wäre somit idealerweise erst möglichst spät in der Verarbeitungskette zu platzieren. Einen Virenscanner oder Spamfilter dürfte man aber auch damit nicht schlagen...
Wort zum Sonntag
Tatsächlich halte ich es für sehr sinnvoll, Prüfungen nach ihren Kosten anzuordnen. Bei Postfix ist das (leider) nicht ganz so sprechend wie bei Exim, wo für jedes Stadium der Mail-Verarbeitung eigene ACLs definiert werden können (connect, rcpt, data, etc.). Das bedeutet aber ggf. auch, Prüfungen an vorgelagerte Stufen abzugeben, die das ggf. billiger und schneller können. Ein schönes Beispiel sind statische (oder pseudo-statische) Blacklists, mit denen bestimmte Mailserver oder Subnetze gesperrt werden. Ja, natürlich kann man so etwas mit einer Datenbankabfrage nach jedem Connect im Mailserver realisieren. Oder aber man füttert (ggf. per Cronjob) einfach den Paketfilter mit dieser Blacklist und fängt eingehende Verbindungen schon ab, bevor der MTA überhaupt dafür bemüht wird, einen Prozess forked, etc...
[1]
http://blog.codinghorror.com/speed-hashing/
[2]
http://codahale.com/how-to-safely-store-a-password/
[3] [Link entfernt, da möglicherweise Verstoß gegen § 202c StGB]