--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/short.txt Mon Apr 20 23:07:59 2015 +0200
@@ -0,0 +1,1565 @@
+Kurzer Konfigurationsritt
+=========================
+:Author: Heiko Schlittermann
+:toc:
+:data-uri:
+:icons:
+:numbered:
+:ascii-ids:
+
+_italic_::
+ Namen von Dateien, Programmen, Hosts, Domains, Mail-Header, URLS: _example.com_, _From:_
+*bold*::
+ Namen von Exim-Routern, Transports, Authenticators: *dnslookup*-Router
++fixed+::
+ Kommandos, Code-Beispiele, Exim-Konfigurations-Optionen: +primary_hostname+
+
+*+fixed bold+*::
+ Hervorhebung von Kommandos, Nutzereingaben: *+exim -bV+*
+
+'+slanted+'::
+ Exim-Variablen im Text: '+$local_part+' oder '+$sender_address+'
+
+== Konfiguration
+
+=== File
+
+Das Konfigurationsfile wird in der Build-Konfiguration (_EDITME_) festgelegt.
+Es ist auch eine Liste von Konfigurationsfiles möglich, der erste Treffer gewinnt.
+Das verwendete File läßt sich ermitteln mit
+
+ exim -bP configure_file
+
+Das aktive Konfigurationsfile kann auch auf der Kommandozeile festgelegt
+werden. Für einige Operationen muss der Pfad ein absoluter sein. Auch
+_/dev/null_ ist eine gültige Konfiguration.
+
+ exim -C <Pfadname> …
+
+Die Konfiguration wird öfter gelesen als vielleicht erwartet:
+
+* Beim Start
+* Aber - wann wird gestartet?
+ ** Start des Daemon
+ ** Signal _HUP_
+ ** re-exec for verschiedene Zwecke
+
+CAUTION: Inhalt der Datei _exim.conf_ footnote:[Debian verwendet häufig exim4 an
+stelle von exim.]
+und eventuell über +.include+ eingelesener Files
+ist statisch. Dynamisch sind dann Expansionen, Lookups.
+
+=== Syntax
+
+Der Parser der Konfigurationsdatei ist ziemlich einfach.
+
+. Kommentarzeilen werden entfernt
+. Führende und anhängige Leerzeichen werden entfernt
+. Forsetzungszeilen („\“ am Zeilenende) werden zusammengefasst
+. einfache Syntax-Checks
+
+Die Konfiguration besteht aus mehreren Abschnitten. Nicht alle Abschnitte
+sind identisch aufgebaut.
+
+Globale Optionen::
+ Allgemeine Parameter wir Listendefinitionen, Optionen für den Mailempfang,
+ Datenbank-Verbindungsparameter
+Access Control Lists::
+ Kontrolle der Nachrichtenannahme
+Router::
+ Steuerung des Nachrichten-Routings (Ermittlung des Zielhosts und des
+ Transportmechanismus)
+Transports::
+ Konfiguration der Transportmechanismen
+Rewrite::
+ Umschreiben von Envelope und Kopfzeilen
+Authentifizierung::
+ Parameter für die SMTP-Authentifizierung (sowohl Client als auch Server)
+
+== Syntax der Konfiguration
+
+=== Kommentare
+Alle Zeilen, die mit einem „#“ beginnen (nach optionalem Whitespace), sind Kommentarzeilen.
+An anderen Stellen der Konfiguration hat das „#“-Zeichen keine besondere Bedeutung.
+
+=== Macros
+Macros sind für einen einfachen statischen Textersetzungsmechanismus und für das
+bedingte Parsen von Konfigurationsteilen. Macros können in der Konfiguration definiert werden, aber
+auch auf der Kommandozeile. (Auf der Kommandozeile gibt es jedoch wegen eventueller Sicherheitsimplikationen
+einige Besonderheiten zu beachten.) Macros werden generell groß geschrieben.
+
+ LDAP_BASE = ou=ousers,o=acme
+ LDAP = ldap:///LDAPBASE
+ …
+ data = ${lookup ldap{LDAP?mail?sub?uid=${quote_ldap:$local_part}}}
+ …
+ .ifdef TESTING
+ testrouter:
+ driver = dnslookup
+ …
+ .endif
+
+Und beim Aufruf:
+
+ exim -DTESTING …
+ exim -DFOO=bar …
+
+Macros können neu definiert werden („==“ statt „=“). Macros von der Kommandozeile haben Vorrang.
+
+=== Optionen
+Es gibt ca. 250 globale Optionen, hinzu kommen noch weitere Optionen für Router, Transports, …
+Optionen haben einen bestimmten <<types,Datentyp>>. Optionen werden generell klein geschrieben.
+
+ primary_hostname = foo.example.com
+
+=== Listen
+Listen bestehen aus der Angabe des Listentypes, eines Namens und dem Listeninhalt.
+Es gibt 4 verschiedenen Listentypen.
+
+Domains::
+ Liste von Domain-Namen. Es gibt einige spezielle Tokens, die in einer solchen
+ Liste auftauchen dürfen.
+
+ domainlist local_domains = @ : schlittermann.de : @mx_primary
+
+Hosts::
+ Hosts oder IP-Adressen, z.B. für vertrauenswürdige Absender-Netze
+
+ hostlist trusted_hosts = 192.168.0.0/24 : 127.0.0.1
+
+Mail-Adressen::
+ Mailadressen
+
+ addresslist blocked_senders = ad@bestholiday.de : *@mailgun.com
+
+Local Parts::
+ Local Parts von Mail-Adressen, z.B. von ACL-Checks ausgenommene lokale Empfänger
+
+ localpartlist rfc = postmaster : abuse
+
+Listen-Lookups werden nur gecacht, wenn die Liste keine Expansions-Items entält
+(also kein '\$'). Um ein Caching zu erwzingen, kann dem Listentyp ein +_cache+
+nachgesetzt werden:
+
+ domainlist_cache local_domain = ${lookup …}
+
+=== Instanzen von Routern, Transports, Authentificators
+
+Router, Transports und Authenificators werden in einzelnen „Funktionsblöcken“
+definiert. Diese Blöcke haben selbstgewählte Namen und eine Liste von
+Optionen, die das Verhalten des jeweiligen Routers, Transports oder
+Authenicators bestimmen.
+
+ begin transports
+ …
+ remote_smtp:
+ driver = smtp
+ command_timeout = 20s
+
+=== ACL und Rewrite-Regeln
+
+Diese beiden Teile der Konfiguration haben ihre eigene Syntax.
+
+[[types]]
+== Werte und ihre Typen
+
+ALle Optionen der Konfigurationsdatei haben einen spezifischen Werte-Typ.
+
+* _bool_, _integer_, _fixed-point_, _time_ und _string_
+* Listen sind immer String-Listen
+* Werte, die der Expansion unterliegen, sind immer vom Typ _string_
+
+
+=== Bool
+
+Werte vom Typ _bool_ sind einfache Schalter.
+
+.Format
+ <option> = true
+ <option> = false
+ <option>
+ no_<option>
+ not_<option>
+
+.Beispiel
+ split_spool_directory
+ not_split_spool_directory
+ split_spool_directory = true
+ split_spool_directory = no
+
+=== Integer
+
+Zahlen. Ganze Zahlen.
+
+.Format
+ … = <digits>[<suffix>]
+ = 0<oct digts>[<suffix>]
+ = 0x<hex digts>[<suffix>]
+
+Erlaubte Suffixe sind 'k' (2^10^) und 'm' (2^20^).
+
+.Beipiel
+ check_spool_space = 10M
+
+=== Fixed-Point
+
+Fixkomma-Zahlen, maximal 3 Nachkommastellen
+
+.Format
+ … = <digits>[.<max 3 digits>]
+
+Diese Werte erlauben *keine* Einheitensuffixe.
+
+.Beispiel
+ deliver_queue_load_max = 2.5
+
+=== Zeitintervalle
+
+Zeitintervalle sind Zeitintervalle.
+
+.Format:
+ … = <digits><suffix>[<digits><suffix>]…
+
+Erlaubte Suffixe sind 's', 'm', 'h', 'd', 'w', also für
+Intervalle, die sich zweifelsfrei in Sekunden umrechnen lassen.
+
+.Beispiel
+ auto_thaw = 3d12h
+
+CAUTION: Bei der Ausgabe von Intervall-Optionen werden die Zeiten normalisiert.
+
+=== Zeichenketten
+
+Zeichenketten gibt es in zwei Formen: Literale Zeichenketten und gequotet.
+Zeichenketten, die später noch expandiert werden, werden _immer_ als gequotete
+Zeichenketten behandelt.
+
+.Format
+ … = <string>
+ … = <"string">
+
+Die gequotete Form ist notwendig, wenn die Zeichenkette mit Leerzeichen enden
+oder beginnen soll, oder wenn eine der folgenden Sequenzen interpretiert
+werden soll: '\\', '\n', '\r', '\t', '\ddd' (oktaler Zeichenwert), '\xdd'
+(hexadezimaler Zeichenwert).
+
+.Beispiel
+ bounce_message_file = /etc/exim/bounce-message.txt
+ bounce_message_text = "Sorry.\nI'm really sorry.\n"
+ message = User $local_part does not exist.
+
+CAUTION: Bei der Ausgabe von String-Optionen werden eventuell vorhandene Steuerzeichen
+durch korrenspondierende Escape-Sequenzen ersetzt.
+
+=== Listen
+
+Listen sind immer Listen zuerst eine _einzige_ Zeichenkette, unterliegen also
+den Zeichenketten-Interpretationsregeln. Der Feldtrenner ist standardmäßig
+ein ':'. Wird der Feldtrenner als Teil eines Listenelements benötigt, muss er
+verdoppelt werden (oder es wird ein anderer Trenner gewält.)
+Umschließender Leerraum an den einzelnen Elementen wird ignoriert. Leere
+Elemente in der Liste und am _Ende_ der Liste werden ignoriert.
+
+.Format
+ … = <item> : <item> …
+ … = <item> : <i::tem> …
+ … = <<separator> <item> ; <item> …
+
+.Beispiel
+ local_interfaces = 127.0.0.1 : ::::1
+ local_interfaces = <; 127.0.0.1 ; ::1
+ domains = <\n ${lookup mysql{…}}
+ senders = <1>
+ senders = : <2>
+
+<1> leere Liste
+<2> Liste mit einem leeren Element
+
+.Debugging
+ exim -be '${map{:a:b:c,}{<$item>}}'
+ exim -be '${map{<,,a,b,c,}{<$item>}}'
+ exim -C <(echo domainlist local_domains = 'a:b::c:d') -be '${listnamed:local_domains}'
+
+=== Reguläre Ausdrücke
+
+Reguläre Ausdrücke werden durch 'libpcre' ausgewertet, sie sind also kompatibel
+mit den von Perl bekannten regulären Ausdrücken. Reguläre Ausdrücke werden immer
+zuerst als String evaluiert, eventuelle Backslash-Sequenzen müssen also ggf. geschützt
+werden.
+
+.Format
+ … = ^<regexp>
+
+.Beispiel
+ domains = example.com : ^\\d{3}
+ domains = example.com : \N^\d{3}\N
+
+Im Beispiel wird der Backslash verdoppelt, da die +domains+ Option zuerst
+expandiert wird.
+
+== Expansion von Zeichenketten
+
+Viele Stellen der Konfiguration verwenden String-Expansion (Typ 'string*' im
+_spec.txt_). String-Expansion wird von '\$' getriggert. Das Ergebnis ist dann
+ein neuer String oder 'forced failure'.
+Die Expansion der Strings erfolgt in der Regel erst im Bedarfsfall („late
+binding“).
+
+CAUTION: Es stehen aber nicht in jeder Phase alle Items zur Verfügung. (z.B.
+wird der Wert der globalen Option +message_size_limit+ expandiert, aber bereits
+während der Antwort auf das SMTP-HELO, in dieser Phase gibt es noch keinen
+'+$local_part+').
+
+.Debugging
+ exim -be [<string>]
+ exim -bem <message-file> [<string>]
+ exim -be -Mset <spool-id> [<string>]
+
+ eg: exim -be '$primary_hostname'
+ exim -be '$tod_full'
+ exim -bem <(echo 'Subject: Hi') '$h_subject:'
+
+=== Expansions-Items
+
+Aus Sicht des Expanders ist alles, was mit einem '\$' beginnt, ein
+Expansions-Item.
+
+Variablen::
+ Das sind operative Parameter, Information über die aktuelle Nachricht,
+ den aktuellen Systemzustand, Rückgabewerte.
+ http://www.exim.org/exim-html-current/doc/html/spec_html/ch-string_expansions.html#SECTexpvar[spec]
+
+ $local_part
+ ${local_part}
+
+Operatoren::
+ Einfache Funktionen wie die Transformation einer Zeichenkette von Klein- auf
+ Großbuchstaben.
+ http://www.exim.org/exim-html-current/doc/html/spec_html/ch-string_expansions.html#SECTexpop[spec]
+
+ ${hex2b64:<string>}
+
+Bedingungen::
+ Fluss-Steuerung
+ http://www.exim.org/exim-html-current/doc/html/spec_html/ch-string_expansions.html#SECTexpcond[spec]
+
+ ${if <condition>…}
+
+Funktionen::
+ Komplexere Umwandlungen mit mehreren Eingangsparametern
+ http://www.exim.org/exim-html-current/doc/html/spec_html/ch-string_expansions.html#SECTexpansionitems[spec]
+
+ ${readsocket{<socket>}}
+
+Lookups::
+ Informationsgewinnung aus externen Quellen (Files, Datenbanken)
+ http://www.exim.org/exim-html-current/doc/html/spec_html/ch-file_and_database_lookups.html[spec]
+
+ ${lookup{<item>}lsearch{<file>}}
+ lsearch;<file>
+
+== Lookups
+
+Mit Lookups werden Daten aus externen Quellen gewonnen. Lookups gibt es in zwei
+Syntaxvarianten und in zwei Stilen.
+
+* Syntax
+** implizit
+** explizit
+* Stil
+** Single-Key
+** Query-Style
+
+
+=== Syntax
+
+==== explizit
+
+Der Key oder die Frage wird ausdrücklich formuliert, es ist eine gewöhnliche
+String-Expansion. Als Resultat wird das Ergebnis des Lookups zurückgeliefert.
+
+.Format
+ … = ${lookup{<key>}<type>{<file>}}
+ … = ${lookup <type>{<query>}}
+
+.Beispiel
+ domainlist local_domains = ${lookup{$domain}dsearch{/etc/vmail/domains}}
+ local_parts = ${lookup ldap{ldap:///o=foo?uid?sub?uid=${quote_ldap:$local_part}}}
+
+Im Beispiel wird der Umstand genutzt, dass in vielen Fällen lediglich
+die aktuell behandelte Adresse in der Liste vorhanden sein muss.
+
+Die explizite Syntax kann natürlich auch eine komplette Liste zurückliefern,
+diese muss dann eventuell massiert werden, damit die Feldtrenner den Erwartungen
+von Exim entsprechen.
+
+==== implizit
+
+Der Key ergibt sich aus dem Kontext, das Lookup wird dennoch durch den
+String-Expander behandelt. Wenn das Lookup erfolgreich ist, wird als Resultat
+der Key zurückgeliefert, nicht ein eventuell vorhandener Wert!
+
+.Format
+ … = <type>;<file>
+ … = <type>;<query>
+
+.Beispiel
+ domains = lsearch;/etc/vmail/domainlist
+ domains = mysql;SELECT COUNT(*) FROM domains WHERE domain = ${quote_mysql:$domain}
+
+=== Style
+
+==== Single Key
+
+Single-Key Lookups beziehen sich auf einfach (und meist schnelle) Key/Value
+Daten. Das sind Dateien im Format der _/etc/aliases_, das sind Verzeichnisse und
+DBM-Files.
+http://www.exim.org/exim-html-current/doc/html/spec_html/ch-file_and_database_lookups.html#SECTsinglekeylookups[spec]
+
+.Wichtige Single Key Lookups
+_lsearch_::
+ Lineare Suche in einer Datei. Suche nach einem Default-Wert mit _lsearch*_,
+ Suche nach Teilzeichenketten (Domain) mit _partial-lsearch_.
+_dsearch_::
+ Verzeichnis-Lookup: Suche nach einem spezifischen Verzeichniseintrag
+_iplsearch::
+ Suche nach IP-Adressen oder Netzen unter Beachtung von Netzmasken
+_dbm_::
+ Suche in Berkeley-DBM Files
+
+.Beispiel
+ data = ${lookup{$local_part}lsearch*{/etc/aliases}}
+
+==== Query Style
+
+Komplexe Anfragen im Sinne einer „Query“.
+http://www.exim.org/exim-html-current/doc/html/spec_html/ch-file_and_database_lookups.html#SECTquerystylelookups[spec]
+
+.Wichtige Query-Style Lookups
+_mysql_::
+ Eben MySQL…
+
+ ${lookup mysql{SELECT … WHERE … like ${quote_mysql:$local_part}}
+
+_dnsdb_::
+ Pseudo-Queries
+
+ ${lookup dnsdb{a=$sender_host}}
+ dnsdb;mxh=example.com
+
+_ldap_::
+ Anfragen an LDAP. Erwartet wird ein Object (_ldap_) oder mehrere Objekte
+ (_ldap_)
+
+ ${lookup ldap{ldap:///ou=foo?mail?sub?uid=${quote_ldap:$local_part}}}
+
+
+=== Überblick
+
+Es gibt also vier Möglichkeiten, Daten aus externen Quellen zu gewinnen.
+
+[cols="h,m,m",options="header"]
+|=======================================================================
+| | single key | query style
+| explizit | ${lookup{<key>}<type>{<file>} | ${lookup <type> {<query>}}
+| implizit | <type>;<file> | <type>;<query>
+|=======================================================================
+
+== Acess Control Lists
+
+ACL wirken für alle Phasen der SMTP-Session. Im globalen Teil werden die
+Einstiegspunkte mit +acl_smtp_connect+ usw. definiert. Im ACL-Abschnitt der
+Konfiguration muss dann ein entsprechend genannter Block existieren.
+
+Die häufigsten Einstiegspunkte sind
+
++acl_smtp_rcpt+::
+ Überprüfung beim +RCPT TO+ Kommando.
+
++acl_smtp_data+::
+ Überprüfung am Ende der +DATA+ Phase, also Content-Scan.
+
+Eine ACL ist eine Folge von Bedingungsblöcken. Sind _alle_ Bedingungen eines
+Blocks erfüllt, gilt die für diesen Block festgelegte Aktion.
+Die Bedingungen werden in der Reihenfolge ihres Auftretens bearbeitet. Sobald
+eine nicht zutrifft, wird der nächste Block untersucht.
+
+.Beispiel
+ accept domains = +local_domains
+ local_parts = postmaster : abuse
+
+.Mögliche ACL-Aktionen
+_accept_::
+ Alles ist ok. Es geht zur nächsten Phase der Verbindung
+_deny_::
+ Fehler 5xx wird zurückgeliefert (nicht zwingend ein Ende der Verbindung!)
+_defer_::
+ Fehler 4xx wird zurückgeliefert
+_drop_::
+ Fehler 5xx wird generiert und Verbindung wird abgebrochen
+_warn_::
+ Keine finale Entscheidung, NOOP
+_require_::
+ Wenn eine der Bedingungen *nicht* erfüllt ist, Abbruch mit 5xx,
+ andernfalls weiter zum nächsten Block
+_discard_::
+ Wie _accept_, aber Empfänger, bzw. Nachricht wird verworfen!
+
+.Häufige ACL-Bedingungen
++hosts+::
+ Sender-Host-IP wird geprüft
+
+ hosts = +trusted_hosts
+
++domains+::
+ Empfänger-Domain wird geprüft
+
+ domains = +local_domains
+
++senders+::
+ Absender-Mailadresse wird geprüft
+
+ senders = postmaster@example.com : hans@foo.bar
+
++malware+::
+ Malware-Content-Scan liefert einen Treffer
+
+ malware = *
+
++spam+::
+ SPAM-Content-Scan (_SpamAssassin_)
+
+ spam = nobody/true
+
++verify+::
+ Empfänger- oder Absenderüberprüfung, eventuell auch mit _callout_.
+
+ verify = recipient/callout=use_sender,defer_ok
+
++ratelimit+::
+ Limitierungen aller Art (Menge, Größe, …)
+
+ ratelimit = 10/1h/$sender_address
+
++condition+::
+ Sonstige Bedingungen aller Art
+
+ condition = ${run{perl}{graylist}{$sender_address/$local_part@$domain}}
+
+.ACL-Modifier
++message+::
+ Der Nachrichtenpuffer wird mit einem Text gefüllt.
+
+ message = 550 Sorry
+
++log_message+::
+ Der Nachritenpuffer für das Protokoll wird mit einem Text gefüllt.
+ Sonst identisch zu +message+.
+
++logwrite+::
+ Sofort einen Log-Eintrag
+
++control+::
+ Steuert das weitere Verhalten
+
+ control = submission
+
++set+::
+ ACL-Variablen setzen
+
+ set acl_m_domain = $domain
+ set acl_c_host = $sender_host_address
+
++add_header+::
+ Header zum Hinzufügen vormerken
+
++remove_header+::
+ Header zum Entfernen vormerken
+
++delay+::
+ Fügt eine kurze Verarbeitungspause ein
+
+Ziel der ACL-Operations sollte es sein, möglichst viele Dinge zur SMTP-Zeit zu
+entscheiden und dann die SMTP-Verbindung mit 5xx zu beenden. Damit bleibt die
+Verantwortung für die Bounce beim Absender.
+
+== Router
+
+Im Router-Abschnitt wird durch einzelne Blöcke das Routing-Verhalten gesteuert.
+Die Reihenfolge der Blöcke ist wichtig. Das Verhalten eines jeden Blocks wird
+durch den Treiber bestimmt.
+
+.Routing als Pseudoprogramm
+
+ if (check preconditions == FAIL) goto NEXT ROUTER
+
+ switch route($address)
+ case ACCEPT: schedule $address for transport
+ case NEW ADDRESS: goto FIRST ROUTER
+ case PASS: goto NEXT ROUTER
+ case FAIL: generate bounce
+ case DEFER: back to queue
+ case DECLINE: if (more?) goto NEXT ROUTER
+ generate bounce
+
+.Beispiel
+ external:
+ driver = dnslookup
+ domains = !+local_domains
+ transport = remote_smtp
+ ignore_target_hosts = <; 127.0.0.1 : ::1
+
+Eine Liste der konfigurierten Router erhält man mit:
+
+ exim -bP router_list
+
+== Transports
+
+Die Transport-Blöcke werden von den Routern referenziert, ihre Reihenfolge ist
+egal. Auch hier wird das grundlegende Verhalten eins Blocks durch den Treiber
+bestimmt.
+
+.Beispiel
+ remote_smtp
+ driver = smtp
+ command_timeout = 10s
+
+Die Liste der konfigurierten Transports:
+
+ exim -bP transport_list
+
+== Filter
+
+Es gibt das _System_-Filter und _User_-Filter. Das System-Filter wird *vor* dem
+Routing der Nachricht aktiv. Das User-Filter dann, wenn ein Router für diesen
+Nutzer aktiv wird und das User-Filter auswertet.
+
+Wenn eine Nachricht nicht zugestellt werden kann, dann wird bei einem späteren
+Queue-Run der Filter-Prozess wiederholt! (Es gibt aber einen +first_delivery+
+Test, mit dem man das behandeln kann.)
+
+
+System-Filter verwenden immer
+http://www.exim.org/exim-html-current/doc/html/spec_html/filter_ch-exim_filter_files.html[Exim-Filter-Syntax].
+User-Filter können Exim-Filter-Syntax verwenden, oder eine Teilmenge der
+http://www.exim.org/exim-html-current/doc/html/spec_html/filter_ch-sieve_filter_files.html[Sieve-Filter-Syntax].
+
+Dem Filter steht die Nachricht schon zur Verfügung, es kann also auf Variablen
+aus den ACL und auf die Header der Nachricht zugreifen..
+
+=== Exim-Filter-Syntax
+
+* 1. Zeile
+
+ # Exim filter
+
+* Keyword/Value, separiert durch Whitespace oder an einigen Stellen durch
+ '('/')'
+* Zeilenumbrüche haben keine Sonderbedeutung
+* Kommentare von '<separator>#' bis zum Zeilenende
+* Data-Values
+** verbatim, wenn sie keine Separatoren enthalten
+** quoted mit '"'
+*** Leerzeichen und die Zeichen '\n', '\r', '\t',
+*** '\ddd' oder '\xdd'
+*** alle anderen Backspace-Squenzen werden daruch das
+ dem Backspace folgende Zeichen ersetzt
+** Strings-Expansion wie in der Exim-Konfiguration
+** max 1024 Zeichen *vor* der Expansion
+
+=== Filter-Kommandos
+
++add+::
+ Nutzer-Variable inkrementieren. Diese Variablen stehen dann später als
+ '+$sn1+' - '+$sn9+' in den Routern und Transports zur Verfügung
+
+ add 27 to to n3
+
++deliver+::
+ Mail weiterleiten, Vorsicht mit den Absendern (SPF). Signifikant.
+
+ deliver "Fred <fred@example.com>"
+
++fail+::
+ Mail abweisen
++finish+::
+ Keine weitere Bearbeitung
++freeze+::
+ Mail einfrieren
++headers+::
+ Header-Verarbeitung konfigurieren (Zeichensatz)
+
+ headers charset UTF-8
+
++if+::
+ Bedingte Verarbeitung mit +if+, +then+, +elif+, +else+, +endif+.
+ * String-Conditions sind +begins+, +contains+, +ends+, +matches+, bzw. +does not …+.
+ * Numerische Bedingungen sind +is above+, +is below+ bzw. +is not …+
+ * Andere Bedingunge: +is_delivered+, +error_message+, +personal+,
+ +first_delivery+
+ * Listen: +forany+
+
++logfile+::
+ Logfile definieren
++logwrite+::
+ Schreiben ins Logfile
++mail+::
+ Antwort-Nachricht erzeugen
+
+ mail text "Danke für Ihre Nachricht mit $h_subject:"
+
++pipe+::
+ Nachricht per Pipeline weiterverarbeiten. Signifikant.
+
+ pipe "/usr/bin/mailstat"
+
++save+::
+ Nachricht in File/Mailbox sichern, das Format der Sicherung hängt vom
+ +filter_file_transport+ in der Konfiguration ab. Signifikant.
+
+ save bcc
+
++testprint+::
+ Testausgabe im Filter-Test-Modus
++vacation+::
+ Urlaubsnachricht erzeugen. Sonderform von +mail+.
+
+
+== Operating
+
+Exim legt alle wichtigen Daten in Text-Dateien ab. Trotzdem sind einige Optionen
+und Tools hilfreich im Umgang mit den operativen Daten des Exim.
+
+=== Prozesse
+
+Mit
+
+ exiwhat
+
+erhält man eine gute Übersicht über die aktuellen Aktivitäten des Exim.
+
+=== Queue
+
+Alle operativen Daten liegen unter dem Spool-Directory:
+
+ exim -bP spool_directory
+
+'input'::
+ Message-Spool. Wichtig! Je Message 2 Dateien.
+'db'::
+ Hint-Files, nicht wichtig.
+'msglog'::
+ Nachrichten-Logs, solange die Nachricht noch nicht 'completed' ist.
+
+Mit dem klassischen 'mailq' lässt sich die aktuelle Queue anzeichen. Oder auch
+mit
+
+ exim -bp
+ exim -bpc
+
+Besser ist 'exipick', das verfügt über viele Möglichkeiten, Queue-Inhalte zu
+selektieren:
+
+ exipick
+ exipick -c
+ exipick -zi
+ exipick -f foo
+
+.Einzelne Nachrichten untersuchen
+ exim -Mvh <queue-id>
+ exim -Mvb <queue-id>
+ exim -Mvc <queue-id>
+
+.Löschen von Nachrichten
+ exim -Mrm <queue-id>
+
+
+=== Protokolle
+
+Protokolle liegen in
+
+ exim -bP log_file_path
+
+'mainlog'::
+ Logfile über alle Transaktionen, dokumentiertes und maschinenlesbares Format
+'rejectlog'::
+ Etwas mehr Details bei 5xx/4xx (Headerzeilen)
+'paniclog'::
+ ... wenn nichts mehr geht.
+
+Zum Suchen und Zusammenfassen dieser Informationen eignet sich 'exigrep' am besten.
+
+.Beispiel
+ exigrep 'hannes@example.com' /var/log/exim/mainlog
+ exigrep 'fred@foobar.de' $(ls -tr /var/log/exim/mainlog*)
+
+Solange die Nachricht noch in der Queue ist:
+
+ exim -Mvl <spool-id>
+
+=== Hint-Data
+
+Die Hint-Data-Files sind Berkeley-DB-Files. Die dafür vorhandenen Werkzeuge sind
+eher spartanisch. Im Zweifelsfall können diese Files auch gelöscht werden.
+
+'exim_dumpdb'::
+ Textdump der jeweiligen Datenbank, Ausgabeformat ist je nach DB-Format
+ leicht unterschiedlich
+
+.Beispiel
+ exim_dumpdb /var/spool/exim retry
+
+'exim_fixdb'::
+ Mit diesem Werkzeug können gezielt einzelne Datensätze einer Hint-DB
+ gelöscht werden
+
+.Beispiel
+ # exim_fixdb /var/spool/exim4 retry
+ Modifying Exim hints database /var/spool/exim4/db/retry
+ > T:mx1.bmw.c3s2.iphmx.com:2620:101:200a:d100::e
+ 13-Apr-2015 08:16:36
+ 0 error number: 101 Network is unreachable
+ 1 extra data: 77
+ 2 first failed: 12-Apr-2015 18:09:35
+ 3 last try: 13-Apr-2015 08:16:36
+ 4 next try: 13-Apr-2015 10:16:36
+ 5 expired: no
+ > d
+ deleted
+
+'exim_tidydb'::
+ Wird regelmäßig über Cron aufgerufen um die Inhalte der Datenbankfiles
+ aufzuräumen. Die Files werden dabei nicht zwangsläufig kleiner!
+
+
+== Debugging
+
+=== Konfiguration
+
+Die syntaktische Korrektheit der Konfiguration wird mit
+
+ exim -bV
+
+geprüft.
+In Routern und Transports kann die +debug_print+ Option verwendet werden, um
+während der Test-Sessions noch angepasste Ausgaben zu erhalten.
+
+CAUTION: Viele Fehler treten erst später bei der Expansion auf!
+
+Teile der Konfiguration können mit:
+
+ exim -bP <option>
+ exim -bP
+ exim -bP transports
+ exim -bP routers
+
+ausgelesen werden.
+
+=== Routing im Trockentest
+
+Das nützlichste Werkzeug ist sicher der Routing-Trockentest.
+Mit
+
+ exim -bt <address>
+
+wird ein Address-Test gemacht. Das entspricht dem Routing-Vorgang. Im
+Unterschied zum echten Routing-Vorgang stehen diesem Test aber keine
+Header-Daten zur Verfügung. Die Absender-Adresse kann mit _-f <sender>_
+eingesetzt werden:
+
+ exim -f <sender> -bt <address>
+
+Mit
+
+ exim -bv <address>
+
+findet eine Adress-Verification statt. Das ist normalerweise identisch zum
+Adresstest. Aber Router können so konfiguriert sein, dass sie nur zum
+Adress-Test oder nur zur Verification verwendet werden. Adress-Verification
+findet u.a. über das ACL-Statement +verify = recipient+ statt.
+
+.Beispiel
+ exim -bt postmaster@schlittermann.de <1>
+ exim -bts postmaster@schlittermann.de <2>
+
+<1> Recipient-Test
+<2> Sender-Test
+
+=== Fake-Delivery für Filter/Router/Rewriting
+
+Bei Fake-Deliveries werden alle Schritte vom Routing über Filter und Rewriting
+ausgeführt, aber es findet keine Delivery statt.
+
+.Beispiel
+ exim -N 1Yk9s3-00048G-4a
+ exim -N <message.eml
+
+=== Fake-SMTP-Session zum ACL-Test
+
+Exim kann SMTP-Sessions zum Test über STDIN/STDOUT abwickeln.
+
+ exim -bh <sender-ip>
+ exim -bhc <sender-ip> <1>
+
+<1> Callouts werden durchgeführt
+
+Dabei schaltet er automatisch in den Debug-Modus für ACL.
+
+.Beispiel
+ swaks -f hs@schlittermann.de -t fred@example.com \
+ --pipe 'exim -bh 1.2.3.4'
+
+=== Filter-Tests
+
+Mit +exim -bf+ bzw. +exim -bF+ lassen sich die Filter-Scripte debuggen.
+
+.Beispiel
+
+ exim -f sender@example.com .de -bf ./filter <message
+ exim -bfd <domain> -bfl <local_part> … -bf
+
+=== Rewrite-Tests
+
+Wenn Rewrite-Regeln verwendet werden, dann können diese mit
+
+ exim -brw <address>
+
+getestet werden.
+
+=== String-Expansion
+
+Der String-Expander steht auf der Kommandozeile zur Verfügung:
+
+ exim -be <string>
+
+.Beispiel
+ exim -be '${lookup{root}lsearch{/etc/aliases}}'
+
+////
+
+ implizit "deny" am Ende jeder ACL!
+
+
+## Test
+
+ > exim -bh <ip> # ohne callouts
+ > exim -bhc <ip> # mit callouts
+ > swaks --pipe 'exim -bh <ip> -C <config>' -f <sender> -t <rcpt>
+
+ exim -N hilft nicht, ist nicht für die SMTP acl
+ relevant!
+
+## Format
+
+ <aclverb> [<condition>]
+ …
+ [<modifier]
+
+ Bedingungen müssen erfüllt sein, Order matters, Abbruch
+ bei nicht erfüllter Bedingung! Modifier sind immer "true"
+
+### Verb
+
+ accept, defer, deny, discard, drop, require, warn
+
+### Modifier
+
+ message = [code] text
+ log_message = text
+
+ Immediate:
+ logwrite = …
+ control = …
+ set = …
+ add_header = …
+ remove_header = …
+ delay = …
+
+### Conditions
+
+ <condition> = <value>
+
+ eg: deny hosts = !192.168.3.8 # neg. Liste
+ deny !hosts = 192.168.3.8 # neg. Resultat
+
+ vs: deny !verify = recipient # works
+ deny verify = !recipient # FALSCH
+
+
+ Wert der Condition und von Modifiern wird expandiert.
+ Force Failure bedeutet: Condition war nicht anwesend!
+
+ Reihenfolge ist wichtig! Short Circuit.
+ Position der Modifier ist wichtig!
+
+
+
+# DNS Lookups
+
+## DNSSEC
+ dns_dnssec_ok = 1
+
+ dnslookup.dnssec_require_domains = # leider noch falsche Syntax
+ smtp.dnssec_require_domains = # leider noch falsche Syntax
+ dnslookup.dnssec_request_domains = # leider noch falsche Syntax
+ smtp.dnssec_request_domains = # leider noch falsche Syntax
+
+# Anhang
+
+## Misc
+
+ Spec.txt durchsuchen (less):
+ - Option /^.<option> eg: |exim_user|
+ - Variable /^\$<variable eg: $localhost_number
+ - Operators: /^\$\{<operator>: eg: ${hash:<string>} …
+ - Condition: /^<condition> \{ eg: eq {<string1>}{<string2>} …
+ - Functions: /^\$\{<function\{ eg: ${map{<string1>}{<string2>}} …
+ - ACL conditions /^<condition> = eg: malware = …
+
+// Die folgenden Listen sind durch einfaches Greppen im Spec-File bzw.
+// im spec.xfpt enstanden, also weder vollständig noch zwingend korrekt!
+
+## Liste globaler Optionen {{{
+
+ accept_8bitmime
+ acl_not_smtp
+ acl_not_smtp_mime
+ acl_not_smtp_start
+ acl_smtp_auth
+ acl_smtp_connect
+ acl_smtp_data
+ acl_smtp_data_prdr
+ acl_smtp_etrn
+ acl_smtp_expn
+ acl_smtp_helo
+ acl_smtp_mail
+ acl_smtp_mailauth
+ acl_smtp_mime
+ acl_smtp_predata
+ acl_smtp_quit
+ acl_smtp_rcpt
+ acl_smtp_starttls
+ acl_smtp_vrfy
+ admin_groups
+ allow_domain_literals
+ allow_mx_to_ip
+ allow_utf8_domains
+ auth_advertise_hosts
+ auto_thaw
+ av_scanner
+ bi_command
+ bounce_message_file
+ bounce_message_text
+ bounce_return_body
+ bounce_return_message
+ bounce_return_size_limit
+ bounce_sender_authentication
+ callout_domain_negative_expire
+ callout_domain_positive_expire
+ callout_negative_expire
+ callout_positive_expire
+ callout_random_local_part
+ check_log_inodes
+ check_log_space
+ check_rfc2047_length
+ check_spool_inodes
+ check_spool_space
+ daemon_smtp_ports
+ daemon_startup_retries
+ daemon_startup_sleep
+ delay_warning
+ delay_warning_condition
+ deliver_drop_privilege
+ deliver_queue_load_max
+ delivery_date_remove
+ disable_fsync
+ disable_ipv6
+ dns_again_means_nonexist
+ dns_check_names_pattern
+ dns_csa_search_limit
+ dns_csa_use_reverse
+ dns_dnssec_ok
+ dns_ipv4_lookup
+ dns_retrans
+ dns_retry
+ dns_use_edns0
+ drop_cr
+ dsn_from
+ envelope_to_remove
+ errors_copy
+ errors_reply_to
+ exim_group
+ exim_path
+ exim_user
+ extra_local_interfaces
+ finduser_retries
+ freeze_tell
+ gecos_name
+ gecos_pattern
+ gnutls_compat_mode
+ header_line_maxsize
+ header_maxsize
+ headers_charset
+ helo_accept_junk_hosts
+ helo_allow_chars
+ helo_lookup_domains
+ helo_try_verify_hosts
+ helo_verify_hosts
+ hold_domains
+ host_lookup
+ host_lookup_order
+ host_reject_connection
+ hosts_connection_nolog
+ hosts_treat_as_local
+ ibase_servers
+ ignore_bounce_errors_after
+ ignore_fromline_hosts
+ ignore_fromline_local
+ keep_malformed
+ ldap_ca_cert_dir
+ ldap_ca_cert_file
+ ldap_cert_file
+ ldap_cert_key
+ ldap_cipher_suite
+ ldap_default_servers
+ ldap_require_cert
+ ldap_start_tls
+ ldap_version
+ local_from_check
+ local_from_prefix
+ local_from_suffix
+ local_interfaces
+ local_scan_timeout
+ local_sender_retain
+ localhost_number
+ log_file_path
+ log_selector
+ log_timezone
+ lookup_open_max
+ max_username_length
+ message_body_newlines
+ message_body_visible
+ message_id_header_domain
+ message_id_header_text
+ message_logs
+ message_size_limit
+ move_frozen_messages
+ mua_wrapper
+ mysql_servers
+ never_users
+ openssl_options
+ oracle_servers
+ percent_hack_domains
+ perl_at_start
+ perl_startup
+ pgsql_servers
+ pid_file_path
+ pipelining_advertise_hosts
+ prdr_enable
+ preserve_message_logs
+ primary_hostname
+ print_topbitchars
+ process_log_path
+ prod_requires_admin
+ qualify_domain
+ qualify_recipient
+ queue_domains
+ queue_list_requires_admin
+ queue_only
+ queue_only_file
+ queue_only_load
+ queue_only_load_latch
+ queue_only_override
+ queue_run_in_order
+ queue_run_max
+ queue_smtp_domains
+ receive_timeout
+ received_header_text
+ received_headers_max
+ recipient_unqualified_hosts
+ recipients_max
+ recipients_max_reject
+ remote_max_parallel
+ remote_sort_domains
+ retry_data_expire
+ retry_interval_max
+ return_path_remove
+ return_size_limit
+ rfc1413_hosts
+ rfc1413_query_timeout
+ sender_unqualified_hosts
+ smtp_accept_keepalive
+ smtp_accept_max
+ smtp_accept_max_nonmail
+ smtp_accept_max_nonmail_hosts
+ smtp_accept_max_per_connection
+ smtp_accept_max_per_host
+ smtp_accept_queue
+ smtp_accept_queue_per_connection
+ smtp_accept_reserve
+ smtp_active_hostname
+ smtp_banner
+ smtp_check_spool_space
+ smtp_connect_backlog
+ smtp_enforce_sync
+ smtp_etrn_command
+ smtp_etrn_serialize
+ smtp_load_reserve
+ smtp_max_synprot_errors
+ smtp_max_unknown_commands
+ smtp_ratelimit_hosts
+ smtp_ratelimit_mail
+ smtp_ratelimit_rcpt
+ smtp_receive_timeout
+ smtp_reserve_hosts
+ smtp_return_error_details
+ spamd_address
+ split_spool_directory
+ spool_directory
+ sqlite_lock_timeout
+ strict_acl_vars
+ strip_excess_angle_brackets
+ strip_trailing_dot
+ syslog_duplication
+ syslog_facility
+ syslog_processname
+ syslog_timestamp
+ system_filter
+ system_filter_directory_transport
+ system_filter_file_transport
+ system_filter_group
+ system_filter_pipe_transport
+ system_filter_reply_transport
+ system_filter_user
+ tcp_nodelay
+ timeout_frozen_after
+ timezone
+ tls_advertise_hosts
+ tls_certificate
+ tls_crl
+ tls_dh_max_bits
+ tls_dhparam
+ tls_ocsp_file
+ tls_on_connect_ports
+ tls_privatekey
+ tls_remember_esmtp
+ tls_require_ciphers
+ tls_try_verify_hosts
+ tls_verify_certificates
+ tls_verify_hosts
+ trusted_groups
+ trusted_users
+ unknown_login
+ unknown_username
+ untrusted_set_sender
+ uucp_from_pattern
+ uucp_from_sender
+ warn_message_file
+ write_rejectlog
+
+
+ }}}
+
+## Liste von Expansionsvariablen {{{
+
+ $acl_narg
+ $acl_verify_message
+ $address_data
+ $address_file
+ $address_pipe
+ $authenticated_fail_id
+ $authenticated_id
+ $authenticated_sender
+ $authentication_failed
+ $av_failed
+ $body_linecount
+ $body_zerocount
+ $bounce_recipient
+ $bounce_return_size_limit
+ $caller_gid
+ $caller_uid
+ $compile_date
+ $compile_number
+ $demime_errorlevel
+ $demime_errorlevel
+ $demime_reason
+ $demime_reason
+ $dnslist_domain
+ $domain
+ $domain_data
+ $exim_gid
+ $exim_path
+ $exim_uid
+ $found_extension
+ $found_extension
+ $header_
+ $headers_added
+ $home
+ $host
+ $host_address
+ $host_data
+ $host_lookup_deferred
+ $host_lookup_failed
+ $host_port
+ $inode
+ $interface_address
+ $interface_port
+ $item
+ $ldap_dn
+ $load_average
+ $local_part
+ $local_part_data
+ $local_part_prefix
+ $local_part_suffix
+ $local_scan_data
+ $local_user_gid
+ $local_user_uid
+ $localhost_number
+ $log_inodes
+ $log_space
+ $lookup_dnssec_authenticated
+ $mailstore_basename
+ $malware_name
+ $max_received_linelength
+ $message_age
+ $message_body
+ $message_body_end
+ $message_body_size
+ $message_exim_id
+ $message_headers
+ $message_headers_raw
+ $message_id
+ $message_linecount
+ $message_size
+ $mime_
+ $mime_boundary
+ $mime_charset
+ $mime_content_description
+ $mime_content_disposition
+ $mime_content_id
+ $mime_content_size
+ $mime_content_transfer_encoding
+ $mime_content_type
+ $mime_decoded_filename
+ $mime_filename
+ $mime_is_coverletter
+ $mime_is_multipart
+ $mime_is_rfc822
+ $mime_part_count
+ $original_domain
+ $original_local_part
+ $originator_gid
+ $originator_uid
+ $parent_domain
+ $parent_local_part
+ $pid
+ $pipe_addresses
+ $primary_hostname
+ $prvscheck_address
+ $prvscheck_keynum
+ $prvscheck_result
+ $qualify_domain
+ $qualify_recipient
+ $rcpt_count
+ $rcpt_defer_count
+ $rcpt_fail_count
+ $received_count
+ $received_for
+ $received_ip_address
+ $received_port
+ $received_protocol
+ $received_time
+ $recipient_data
+ $recipient_verify_failure
+ $recipients
+ $recipients_count
+ $regex_match_string
+ $reply_address
+ $return_path
+ $return_size_limit
+ $router_name
+ $runrc
+ $self_hostname
+ $sender_address
+ $sender_address_data
+ $sender_address_domain
+ $sender_address_local_part
+ $sender_data
+ $sender_fullhost
+ $sender_helo_name
+ $sender_host_address
+ $sender_host_authenticated
+ $sender_host_dnssec
+ $sender_host_name
+ $sender_host_port
+ $sender_ident
+ $sender_rate_
+ $sender_rcvhost
+ $sender_verify_failure
+ $sending_ip_address
+ $sending_port
+ $smtp_active_hostname
+ $smtp_command
+ $smtp_command_argument
+ $smtp_count_at_connection_start
+ $spam_
+ $spam_bar
+ $spam_report
+ $spam_score
+ $spam_score_int
+ $spool_directory
+ $spool_inodes
+ $spool_space
+ $thisaddress
+ $tls_in_bits
+ $tls_in_certificate_verified
+ $tls_in_cipher
+ $tls_in_ocsp
+ $tls_in_ourcert
+ $tls_in_peercert
+ $tls_in_peerdn
+ $tls_in_sni
+ $tls_out_bits
+ $tls_out_certificate_verified
+ $tls_out_cipher
+ $tls_out_ocsp
+ $tls_out_ourcert
+ $tls_out_peercert
+ $tls_out_peerdn
+ $tls_out_sni
+ $tod_bsdinbox
+ $tod_epoch
+ $tod_epoch_l
+ $tod_full
+ $tod_log
+ $tod_logfile
+ $tod_zone
+ $tod_zulu
+ $transport_name
+ $value
+ $verify_mode
+ $version_number
+ $warn_message_delay
+ $warn_message_recipients
+
+ }}}
+
+## Liste von Operatoren {{{
+
+ ${address:
+ ${addresses:
+ ${base62:
+ ${base62d:
+ ${domain:
+ ${escape:
+ ${eval:
+ ${expand:
+ ${from_utf8:
+ ${hex2b64:
+ ${hexquote:
+ ${lc:
+ ${listcount:
+ ${listnamed:
+ ${local_part:
+ ${mask:
+ ${md5:
+ ${quote:
+ ${quote_local_part:
+ ${randint:
+ ${reverse_ip:
+ ${rfc2047:
+ ${rfc2047d:
+ ${rxquote:
+ ${sha1:
+ ${sha256:
+ ${stat:
+ ${str2b64:
+ ${strlen:
+ ${time_eval:
+ ${time_interval:
+ ${uc:
+ ${utf8clean:
+
+ }}}
+
+## List of Conditions {{{
+
+ acl
+ and
+ bool
+ bool_lax
+ crypteq
+ eq
+ exists
+ ge
+ gt
+ inlist
+ isip
+ ldapauth
+ le
+ lt
+ match
+ match_address
+ match_domain
+ match_ip
+ match_local_part
+ or
+ pam
+ pwcheck
+ radius
+
+ }}}
+
+## List of Functions {{{
+
+ ${acl
+ ${certextract
+ ${dlfunc
+ ${extract
+ ${extract
+ ${filter
+ ${hash
+ ${hmac
+ ${length
+ ${listextract
+ ${lookup
+ ${map
+ ${nhash
+ ${perl
+ ${prvs
+ ${prvscheck
+ ${readfile
+ ${readsocket
+ ${reduce
+ ${run
+ ${sg
+ ${sort
+ ${substr
+ ${tr
+
+ }}}
+
+## Routing Pre-Conditions {{{
+
+ address_test
+ check_local_user
+ condition
+ domains
+ expn
+ local_part_prefix
+ local_part_suffix
+ local_parts
+ require_files
+ senders
+ verify
+ verify_only
+ verify_recipient
+ verify_sender
+
+ }}}
+
+
+Cheat sheet: http://www.datadisk.co.uk/html_docs/exim/exim_cs.htm
+
+# vim:tw=80:et:ts=4:sw=4:et:fdm=marker:ft=asciidoc:
+////