Postfix Policy Daemons im Eigenbau. Sinn und

Werbung
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
Herunterladen