diff -r 310001890766 -r 3d9bb718ac1c mk2014.tex --- a/mk2014.tex Thu May 08 15:44:04 2014 +0200 +++ b/mk2014.tex Fri May 09 10:38:05 2014 +0200 @@ -12,6 +12,12 @@ \author[H. Schlittermann]{Heiko Schlittermann} \institute{schlittermann - internet \& unix support, Dresden} +\newcommand{\B}{$\hookleftarrow$} +\newcommand{\ttinput}[1]{% + \begin{alltt}% + \input{#1}% + \end{alltt}} + \begin{document} @@ -23,376 +29,14 @@ \tableofcontents \end{frame} -\section{Positionierung} - -\begin{frame}[<+->][fragile]{Exim}{Entwicklung} -\begin{itemize} - \item \textbf{Ex}perimental \textbf{I}nternet \textbf{M}ailer - \item seit 1995 Phil Hazel, seit ca. 2007 ca. 5…8 Aktive Entwickler - \item Klassisch Unix: Traditionelle Konfiguration und traditionelles Prozess-Management - \item mehr als 90\% der Nachrichten werden sofort weitergeleitet bzw. ausgeliefert -\begin{verbatim} -Time spent on the queue: messages with at least one remote delivery -------------------------------------------------------------------- -Under 1m 15052 99.2% 99.2% - 5m 20 0.1% 99.3% - 15m 2 0.0% 99.3% - 30m 91 0.6% 99.9% - 1h 9 0.1% 100.0% - 6h 2 0.0% 100.0% -Over 1d 1 0.0% 100.0% -\end{verbatim} -\end{itemize} -\end{frame} - -\begin{frame}[<+->][fragile]{Exim}{Position} -Ja, das ist Religionskrieg :-) -\pause -\begin{itemize} - \item Lego vs. Playmobil (P. Heinlein) - \item Anpassbarkeit - \begin{itemize} - \item keine Klassifizierung von Adressen - \item keine \verb=mydestinations= - \item Router sind Funktionsblöcke - \item Intensiver Gebrauch von Expansionsmechanismen zur Laufzeit - \end{itemize} - \item Stabilität - \item Sicherheit - \item Definierte Dokumentation (Referenz-Handbuch mit Beispielen) - \item Hervorragendes Debugging -\end{itemize} -\pause -Nachteile? Klar - das Abarbeiten der Queue ist nicht sonderlich -effizient gelöst. -\end{frame} - -\section{Anatomie} - -\begin{frame}[<+->]{Arbeitsweise und Anatomie}{Überblick} -\begin{itemize} -\item Binary ist ein ca 1\,MB großer Universalklumpen -\item Einfache Struktur der operativen Daten - Verzeichnis, 2 Files je -Message, Spool/Message-Log in 16 Verzeichnissen -\item Dokument -\item Keine aufwändigen IPC - nichts, außer fork(2) oder exec(3) -\item Wenig gemeinsam genutzte Daten - nur „Hint“-Files (z.B. retry info) -\item Ohoh - setuid 0! -\end{itemize} -\end{frame} - -\begin{frame}{Arbeitsweise und Anatomie}{Prozesse} -\includegraphics[width=0.8\textwidth,angle=270]{procs} -\end{frame} - -\begin{frame}[<+->]{Arbeitsweise und Anatomie}{IN, OUT, Retry} -Es gibt im wesentlichen 3 Phasen der Verarbeitung. -\pause -\begin{enumerate} - \item Empfang - \begin{itemize} - \item ACL mit Ratelimit, Blacklists, Routing-Test, Content-Scan - \item Ablage im Spool-Verzeichnis - \end{itemize} - \item Start des Sendeprozesses - \begin{itemize} - \item Spoolfile-Lock - \item Routing - \item Transport oder ggf. Abbruch - \end{itemize} - \item Queuerunner startet ggf. weitere Versuche -\end{enumerate} -\end{frame} - -\section{Konfiguration} - -\subsection{File} - -\begin{frame}[<+->][fragile]{Konfiguration}{File} -\begin{itemize} - \item Debian geht einen sonder(baren) Weg - \item \verb=/dev/null= ist eine gültige Konfiguration - \item \verb=exim -bV= listet die verwendete Konfigurationsdatei und - einkompilierte Features - \item Beispiel-Konfig \verb=example.conf.gz= als Ausgangspunkt -\end{itemize} -\end{frame} - -\subsection{Struktur} - -\begin{frame}[<+->][fragile]{Konfiguration}{Struktur} -Strukturiertes Konfigurationsfile mit mehreren Abschnitten, teilweise -miteinander verlinkt (Router referenziert Tranports, globaler Teil -referenziert ACL) -\pause -\begin{description} - \item[global] Etwa 240 allgemeine Direktiven - \item[acl] Access Control Lists für SMTP - \item[routers] Routing-Regeln (genutzt auch von ACL) - \item[transports] Wie wird SMTP gemacht, oder das Anhängen an Mailboxen - \item[retry] Unter welchen Bedingungen wird wann und wie oft und wie - lange wiederholt - \item[rewrite] Umschreiben von Headern und Envelope - \item[authenticators] SMTP-Authentifizierung -\end{description} -\end{frame} - -\subsection{Syntax} - -\begin{frame}[fragile]{Konfiguration}{Syntax} -\begin{exampleblock}{Macros} -\begin{verbatim} - CF = /etc/exim4/ - USER_BASE = ou=users,BASE - BASE = dc=example,dc=com -\end{verbatim} -\end{exampleblock} -\pause - -\begin{exampleblock}{Bedingte Konfiguration} -\begin{verbatim} - .ifdef SMALL_MEM - message_size_limit = 50M - .else - message_size_limit = 500M - .endif -\end{verbatim} -\end{exampleblock} -\pause - -\begin{exampleblock}{Versteckte Optionen} -Wegen \verb=exim -bP …=: -\begin{verbatim} - hide mysql_servers = localhost/mail/exim/secret -\end{verbatim} -\end{exampleblock} -\end{frame} - -\begin{frame}[fragile]{Konfiguration}{Options-Typen} -Es existieren ca. 580 Direktiven (Optionen). Exim kennt mehrere Datentypen. -\begin{exampleblock}{Bool} -\begin{verbatim} - more = yes - more = no - more - no_more -\end{verbatim} -\end{exampleblock} - -\begin{exampleblock}{Numerisch: Integer, Fixed-Point, Zeitintervalle} -\begin{verbatim} - message_size_limit = 100k - queue_only_load = 1.5 - retry_data_expire = 4d2h -\end{verbatim} -\end{exampleblock} -\begin{exampleblock}{Zeichenketten} -\begin{verbatim} - primary_hostname = mail.example.com -\end{verbatim} -\end{exampleblock} -\end{frame} - -\begin{frame}[fragile]{Konfiguration}{Options-Typen 2} -\begin{exampleblock}{Listen} -\begin{verbatim} - local_parts = hans : fred : detlef - interfaces = <; 192.168.123.123 ; 2001:db8::42 -\end{verbatim} -\end{exampleblock} - -\begin{exampleblock}{Frei definierte Listen} -\begin{verbatim} - domainlist local_domains = example.com : example.org - hostlist relay_from_hosts = 127.0.0.1 : fred.example.com -\end{verbatim} -\end{exampleblock} +\section{Exim - Entwicklung und Positionierung} +\input{frames/exim.tex} -\end{frame} - -\subsection{Variablen-Expansion} - -\begin{frame}[fragile]{Konfiguration}{Expansion} - Etwa die Hälfte der Konfigurationsdirektiven erlaubt - Variablensubstitution (Expansion) zur Laufzeit. - Testen kann man diese sehr einfach: -\begin{alltt} - $ exim -be '$primary\_hostname' - jumper.schlittermann.de - \pause - $ exim -be -oMi 1.1.1.1 -oMa 2.2.2.2 '$sender\_host\_address $received\_ip\_address' - 2.2.2.2 1.1.1.1 - \pause - $ exim -be '$\{lookup passwd\{nobody\}\{$\{extract\{5\}\{:\}\{$value\}\}\}\}' - /nonexistent - \pause - $ exim -be '$\{lookup\{root\}lsearch\{/etc/aliases\}\}' - heiko - \pause - $ exim -be '$\{lookup dnsdb\{mx=heise.de\}\}' - 10 relay.heise.de -\end{alltt} -\end{frame} - -\begin{frame}[fragile]{Expansion}{Übersicht} -Expansion als „working horse“ der Flexibilität -\begin{description} -\item[Variablen] \verb=$local_part=, \verb=${local_part}= -\item[Operatoren] \verb=${sha1:$local_part}=, \verb=${uc:$domain}= -\item[Manipulation] \verb=${sg{$local_part}{.laus}{XXX}}= -\item[Bedingungen] \verb=${if eq{$local_part}{x}{~x/.mbox}{/var/mail/$local_part}}= -\item[Lookup/Key] \verb=${lookup{$local_part}lsearch{/etc/aliases}}= -\item[Lookup/Query] \verb+${lookup dnsdb{mx=heise.de}}+ -\end{description} -\end{frame} - -\begin{frame}[fragile]{Expansion}{Variablen} -Es gibt knapp 200 Variablen, die Information über Zustände, Limits, … -enthalten: -\begin{verbatim} - … = $ - … = ${} -\end{verbatim} -\begin{description} -\item[Envelope] \verb=$local_part=, \verb=$domain=, \verb=$local_part_prefix=, - \verb=$sender_local_part=, \verb=$recipients= -\item[Message] \verb=$message_line_count=, \verb=$message_size=, - \verb=$message_headers=, \verb=$h_subject:= -\item[Content] \verb=$spam_score_int=, \verb=$malware_name= -\item[Routing] \verb=$original_domain= -\item[Delivery] \verb=$host_address=, \verb=$home=, - \verb=$qualify_recipient= -\item[Operation] \verb=$load_average=, \verb=$log_space=, \verb=$pid= - \verb=$received_interface_address=, \verb=$tls_out_peerdn=, - \verb=$message_age= -\end{description} -\end{frame} - -\begin{frame}[fragile]{Expansion}{String-Operationen} -Einfache Operationen auf Zeichenketten sind möglich: -\begin{verbatim} - … = ${:} -\end{verbatim} -\begin{description} -\item[Konvertierung] \verb=${uc:$local_part}=, \verb=${sha1:$domain}=, \verb=${time_eval:2d4h}= -\item[Extraktion] \verb=${length_3:$domain}=, \verb=${substr_1_3:$domain}=, \verb=${addresses:$h_from}= -\item[Arithmetik] \verb=${eval:40 + 2}=, \verb=${eval:40 + 2k}=, \verb=${eval:8 << 2}= -\item[Filesystem] \verb=${stat:/etc/hosts}= -\end{description} -\end{frame} - -\begin{frame}[fragile]{Expansion}{Bedingte Expansion} -Expansion kann von Bedingungen abhängig gemacht werden. -\begin{verbatim} - ${if :} - ${if [{arg}…] {}[{}]} - ${if [{arg}…] {}fail} -\end{verbatim} -\begin{description} -\item[Negation] \verb=! = -\item[Verknüpfungen] \verb=and{{…}{…}{…}}= -\item[Definiert] \verb=def:tls_cipher= -\item[Vergleiche] \verb=eq{foo}{bar}=, \verb+=={1}{2}+ -\item[Matching] \verb=match{$local_part}{^h\d+}= -\item[Authentication] \verb=pam{$user:$pass}= -\item[Status] \verb=first_delivery= -\end{description} -\end{frame} +\section{Arbeitsweise und Anatomie} +\input{frames/anatomie.tex} -\begin{frame}[fragile]{String-Expansion}{Listen} -An vielen Stellen werden Listen verwendet, Trenner in literalen -Listen ist „:“, es können aber auch Listen aus Textfiles, DBM-Files und -Directories erstellt werden: -\begin{description} -\item[Literale] \verb=example.com : foo.bar : example.org=, - \verb=<; 2001:db8::10 ; 2001:db8::12= -\item[Datei] \verb=lsearch;/etc/mailnames=, - \verb=dbm;/etc/mailnames= -\item[Verzeichnis] \verb=dsearch;/etc/vmail/domains= -\end{description} -\end{frame} - -\begin{frame}[fragile]{String-Expansion}{Single-Key Lookups} -Suche nach einem einzelnen Key, implizit oder explizit -\begin{verbatim} - = ; - ${lookup{}{}[{}[{}{}{}fail} -\end{verbatim} -\begin{description} -\item[implizit] \verb+domains = lsearch;/etc/mail/domains+ -\item[Lookup] \verb|${lookup{$local_part}lsearch{/etc/aliases}}| -\item[Lookup] \begin{verbatim} - ${lookup{$local_part}lsearch{/etc/aliases}\ - {$value}\ - {${lookup{…}}}} -\end{verbatim} -\end{description} -\begin{exampleblock}{Lookup-Typen} -lsearch, dsearch, dbm, cdbm, iplsearch, net-iplsearch, wildlsearch, … -\end{exampleblock} -\end{frame} - -\begin{frame}[fragile]{String-Expansion}{Query-Style Lookups} -Generische Suche in (SQL)-Datenbank, LDAP, DNS, NIS -\begin{verbatim} - ${lookup {}[{}[{}]]} -\end{verbatim} -\begin{description} -\item[DNS] \verb+${lookup dnsdb{a=foobar.de}}+ -\item[LDAP] \begin{verbatim}${lookup ldap{ldap:///o=bar?mailbox - ?sub?uid=${quote_ldap:$local_part}}} -\end{verbatim} -\item[PSQL] \verb=${lookup pgsql{SELECT mailbox FROM …}}= -\end{description} -\begin{exampleblock}{Lookup-Typen} - dnsdb, ibase, ldap, mysql, nisplus, oracle, passwd, pgsql, sqlite -\end{exampleblock} -\end{frame} - -\begin{frame}[fragile]{String-Expansion}{Wenn nichts mehr geht} -Als letzter Hilfe gibt es die Möglichkeit, Sockets auszulesen, externe -Kommandos aufzurufen oder Perl-Funktionen zu nutzen. -\begin{exampleblock}{Sockets} -\begin{verbatim} - condition = ${readsocket{}{}} -\end{verbatim} -\end{exampleblock} -\begin{exampleblock}{Kommandos} -\begin{verbatim} - domains = ${run{[]…}} -\end{verbatim} -\end{exampleblock} -\begin{exampleblock}{Perl} -\begin{verbatim} - perl_startup = do '/etc/exim/foo.pl' - … - domains = ${perl{}[{}…]} -\end{verbatim} -\end{exampleblock} -\end{frame} - - -%\begin{frame}{ACL (SMTP-Phasen, Address-Überprüfung, Rate-Limiting, Content-Scan)} -%\begin{itemize} -%\item Eingehende SMTP-Verbindungen (und in Grenzen auch -% nicht-SMTP)-Verbindungen müssen ACL überwinden. -%\item Für jede Phase der SMTP-Kommunikation gibt es einen -%ACL-Einstiegspunkt, z.B.:\begin{verbatim} -% acl_smtp_connect = -% acl_smtp_rcpt = -% acl_smtp_data = -%\end{verbatim} -%\item ACL entscheidet: accept, reject, defer, warn (noop) -%\item ACL Bedingungen: domains, DNS-BL, Verify (Sender/Empfänger), …, -% condition -%\item ACL können die interne Behandlung der Nachricht beeinflussen -% (queue\_only, submission, …) -%\item ACL können Variablen setzen, die später (Router, Transports) -% verwendet werden -%\end{itemize} -%\end{frame} -% +% -- +\input{frames/konfiguration.tex} \section{Routing} \subsection{Ablauf}