Die Schnittstelle Implementation Fragen und Diskussion Postfix Policy Daemons im Eigenbau. Sinn und Implementation. David Schweikert ISG.EE - ETH Zürich 2. Mailserver-Konferenz Magdeburg, 20. Mai 2005 David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Über die ISG.EE IT Support Gruppe an der ETH Zürich 15 Mitarbeiter Alle unsere Tools sind GPL http://isg.ee.ethz.ch David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Über mich Arbeite seit 5 Jahren bei der ISG.EE Administration von Mail-Servers (unter anderem) Open-Source Projekte: Mailgraph, Postgrey, Gedafe, ISGTC, Perl-Module http://people.ee.ethz.ch/dws David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Postfix Policy Daemons im Eigenbau 1 Die Schnittstelle Was ist eine SMTP-Policy? Beispiel SMTP-Policies Motivation für ein externer Prozess Das Protokoll Konfiguration in Postfix 2 Implementation Implementation mit spawn Implementation als einzelne Prozess Datenbanken Testen Typische Fallen 3 Fragen und Diskussion David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Was ist eine SMTP-Policy? Was ist eine SMTP-Policy? Entscheiden beim Mail-Verkehrseingang (SMTP-Protokoll), was mit einer E-Mail gemacht werden soll: Zurückweisen mit einem definitiven Fehler Zurückweisen mit einem temporären Fehler Mail akzeptieren (kann später noch “bouncen”) Kein Entscheid: weitere Policy-Regeln überprüfen Postfix: smtpd_xxx_restrictions David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Was ist eine SMTP-Policy? Beispiel SMTP-Session 220 example.com ESMTP Postfix HELO ee.ethz.ch 250 example.com MAIL FROM: <[email protected]> 250 Ok RCPT TO: <[email protected]> 451 Greylisted for 300 seconds QUIT David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Beispiel SMTP-Policies Policy-Beispiel: Relaying nur für lokale Clients Nur lokale Clients dürfen Mails schicken, die an Dritte weitergeleitet werden sollen. Input aus dem Mail-System: IP-Adresse der Mail-Client Policy: Bekannte Adresse? → ACCEPT David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Beispiel SMTP-Policies smtpd_recipient_restrictions In Postfix sind Policies mit smtpd_xxx_restrictions konfiguriert: smtpd_recipient_restrictions = reject_non_fqdn_recipient reject_unlisted_recipient permit_mynetworks permit_sasl_authenticated check_client_access hash:/etc/postfix/client_access reject_unauth_destination David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Beispiel SMTP-Policies Policy-Beispiel: SPF Bekämpfung von Fälschungen der Absender-Adresse: “Darf dieser Mail-Client, Mails mit dieser Absender-Mail-Domain zu verschicken?” Input aus dem Mail-System: Mail-Domain der Absender (“Envelope Sender”) IP-Adresse der Mail-Client Policy: Aus der DNS (SPF TXT-Einträge): erlaubte Mail-Clients für diese Mail-Domain Mail-Client nicht in der Liste? → REJECT Ist mit den eingebauten Restrictions von Postfix nicht möglich. David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Beispiel SMTP-Policies Policy-Beispiel: Greylisting “Echte” Mail-Servers reagieren auf temporäre Fehler indem sie später erneut Versuch die Mail zu versenden. Idee: einen temporären Fehler beim ersten Versuch erzeugen. Spammers haben keine echten Mailserver und kommen daher nicht wieder. Input aus dem Mail-System: IP-Adresse der Mail-Client Absender Adresse Empfänger Adresse Policy: “Triplet” neu? → DEFER Nicht möglich mit den eingebauten Restrictions von Postfix. David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Beispiel SMTP-Policies David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Motivation für ein externer Prozess Geschichte Juni 2003: Greylisting-Paper von Evan Harris Juli 2003: SPF-Talk von Meng Weng Wong Juli 2003: Ankündigung von Wietse Venema: “SMTPD Policy Delegation” David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Motivation für ein externer Prozess Warum ein externer Prozess? Hohe Komplexität (Implementation und Konfiguration) (Mail::SPF::Query ist 64KB Perl-Code) Sicherheit: Keine Abhängigkeit zu externen Libraries Hohe Flexibilität verlangt Policy-Entscheide können an einen anderen Server delegiert werden Performance kann trotzdem gut sein David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Motivation für ein externer Prozess Anwendungsbeispiele für Policy-Daemons Authentisierung Authentisierung der eigenen Clients SPF Anti-SPAM Greylisting Spam-Trap Blacklisting Nicht geeignet Caller-ID / Sender-ID Content-Filter Outbound-Policy (z.B. SPF/SRS) David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Das Protokoll Das Protokoll: Postfix → Daemon request=smtpd_access_policy protocol_state=RCPT protocol_name=SMTP helo_name=some.domain.tld queue_id=8045F2AB23 [email protected] [email protected] client_address=1.2.3.4 client_name=another.domain.tld instance=123.456.7 sasl_method=plain sasl_username=you sasl_sender= size=12345 [leere Zeile] David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Das Protokoll Das Protokoll: Daemon → Postfix action=defer_if_permit Greylisted [leere Zeile] David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Das Protokoll Mögliche Antworten (aus accept(5)): OK all-numerical (wie OK) 4NN text (temporäre Fehler) 5NN text (definitive Fehler) REJECT optional text DEFER_IF_REJECT optional text DEFER_IF_PERMIT optional text David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Das Protokoll Mögliche Antworten (aus accept(5)): restriction (entsprechende restriction applizieren) DISCARD optional text DUNNO FILTER transport:destination HOLD optional text PREPEND headername: headervalue REDIRECT user@domain WARN optional text David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Konfiguration in Postfix Konfiguration in Postfix smtpd_recipient_restrictions = reject_non_fqdn_recipient reject_unlisted_recipient permit_mynetworks permit_sasl_authenticated check_client_access hash:/etc/postfix/client_access reject_unauth_destination check_policy_service inet:127.0.0.1:10023 David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Implementation mit spawn Implementation mit spawn Postfix-Äquivalent zu inetd Wrapper für Programmen, die mit stdin/stdout arbeiten Prozesse werden nach Bedarf gestartet (parallel) Prozesse nach maximal 100 (max_use) Anfragen terminiert David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Implementation mit spawn Implementation mit spawn: master.cf # service type priv unpri chroot wakeup maxproc command 127.0.0.1:10023 inet n n spawn user=nobody argv=/some/where/policy-server David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Implementation mit spawn Implementation mit spawn: Hauptschleife while (<STDIN>) { if (/(.*?)=(.*)\n/) { $attr{$1} = $2; } elsif ($_ eq "\n") { fatal_exit "unrecognized request type" unless $attr{request} eq "smtpd_access_policy"; $action = smtpd_access_policy(\%attr); print STDOUT "action=$action\n\n"; %attr = (); } } (aus Postfix’s greylist.pl, vereinfacht) David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Implementation mit spawn Implementation mit spawn: Vor-/Nachteile Vorteile: Sehr einfache Implementation Ideale Integration in Postfix Überwachung durch Postfix Nachteile: Muss schnell starten Viele unabhängige Prozesse → Schwierigkeit bei gemeinsame Daten → (greylist.pl ist nicht zuverlässig) David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Implementation als einzelne Prozess Implementation als einzelne Prozess Wie kann man das Locking Problem lösen? Nur ein Prozess Mehrere Clients Select-loop Schwierigkeit: nur Ausschnitte vom gesamten Verkehr → Man muss zuerst den vollständigen Request zusammenbauen David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Implementation als einzelne Prozess Implementation als einzelne Prozess: Vor-/Nachteile Vorteile: Schnell unabhängig der Startup-Zeit Kein Locking Nachteile: Skaliert nicht auf mehrere CPU Programmierung nicht ganz trivial David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Implementation als einzelne Prozess Implementation als einzelne Prozess Die Implementation mit select ist komplex Abhilfe schafft Net::Server David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Implementation als einzelne Prozess Implementation mit Net::Server Prozess-Modell ist wählbar und austauschbar: Inetd/spawn Single Multiplexing (einzelne Prozess mit select) Forking, Pre-Forking Optionen Logging Daemonifizierung Zugriffskontrolle (allow/deny) Signal-Handlung (inklusive HUP) David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Implementation als einzelne Prozess Implementation mit Net::Server Prozess-Modell wählen Applikation als Subklasse schreiben $self->process_request und andere benötigte Prozeduren nach Bedarf überschreiben David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Implementation als einzelne Prozess Implementation mit Net::Server::Multiplex $self->mux_input statt process_request Input konsumieren Wenn Input reicht, Request behandeln sub mux_input() { my ($self, $mux, $fh, $in_ref) = @_; while ($$in_ref =~ s/^([^\r\n]*)\r?\n//) { next unless defined $1; my $in = $1; # etwas mit $in tun } } David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Datenbanken Datenbanken-Wahl Welche Datenbank ist am besten geeignet? Welche Vor- und Nachteile? David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Datenbanken Datenbanken: Text-Dateien Vorteile: Einfach zu debuggen / auswerten Nachteile: Performance Random access (read/write) schwierig Locking muss selber gemacht werden David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Datenbanken Datenbanken: Persistente Objekte Zum Beispiel mit Perl’s Storable... Vorteile: Einfache Programmierung Nachteile: Alles im Memory! Nur ein globales Lock Keine Transactions / Recovery Prozedur David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Datenbanken Datenbanken: Berkeley-DB Vorteile: Performance Angenehm für Key/Value (tie im Perl) Transactions und Recovery Locking Nachteile: Locking ist etwas komplex (Deadlock detection) Nur Key/Value-Modell Postgrey: Die CPU ist mit 40’000 eingehende Mails pro Tag 0.2% ausgelastet (1.2 Ghz UltraSparc IIIi) David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Datenbanken Datenbanken: SQLite Vorteile: Performance Public Domain! Flexibilität und Features von SQL Locking Nachteile: DBD ist schwieriger als tie Globales Lock (mit nicht zu häufige COMMITs aber trotzdem sehr schnell) Meine Empfehlung ausser es gibt spezielle Bedürfnisse David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Datenbanken Datenbanken: MySQL / PostgreSQL Vorteile: Performance Flexibilität und Features von SQL Locking Client-Server Nachteile: Installation Komplexität des gesamten Systems David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Testen Testen Von Hand telnet localhost 10023 Copy/Paste einer Policy-Request Mit XCLIENT Fälschung von Eckdaten einer SMTP-Session Client muss freigeschaltet werten: smtpd_authorized_xclient_hosts = localhost David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Testen Testen dws@tardis:~$ telnet localhost 25 Trying 127.0.0.1... Connected to localhost. Escape character is ’^]’. 220 smtp.ee.ethz.ch ESMTP Postfix XCLIENT NAME=test.example.com ADDR=192.168.1.1 250 Ok MAIL FROM:<[email protected]> 250 Ok RCPT TO:<[email protected]> 450 <[email protected]>: Recipient address rejected: Greylisted David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Typische Fallen Falle: Mails mit mehrere Empfänger Postgrey fügt einen Header ein, falls es ein Delay verursacht hat Mehrere Empfänger → mehrere Header Lösung: Mit instance die Requests korrelieren und nur einmal den Header einfügen David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Typische Fallen Falle: Crash des Daemon Postgrey: Crash wenn %n in der Absender-Adresse vorkommt Ursache: indirekt syslog (wie printf) wie ein puts gebraucht Konsequenz: 450 Server configuration problem Denial-of-Service! David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Zusammenfassung Zusammenfassung Sehr mächtig für spezielle Anwendungen. Kein Content-Filter! Aufpassen, wie es in Postfix konfiguriert wird Implementation muss robust sein: das ganze Mail-System hängt davon ab Net::Server und SQLite sind nützlich bei der Programmierung David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich Die Schnittstelle Implementation Fragen und Diskussion Fragen? David Schweikert Postfix Policy Daemons ISG.EE - ETH Zürich