renamed abstract -> short v1.1
authorHeiko Schlittermann (JUMPER) <hs@schlittermann.de>
Mon, 20 Apr 2015 23:07:59 +0200
changeset 13 95ecb62b93e6
parent 12 86e315be5b57
child 14 3b662aa211f7
renamed abstract -> short
Makefile
abstract.conf
abstract.txt
short.conf
short.txt
--- a/Makefile	Mon Apr 20 23:07:09 2015 +0200
+++ b/Makefile	Mon Apr 20 23:07:59 2015 +0200
@@ -1,6 +1,6 @@
-TXT = abstract.txt
-HTML = out/abstract.html
-PDF = out/abstract.pdf
+TXT = short.txt
+HTML = out/short.html
+PDF = out/short.pdf
 
 #REVISION = ${shell hg id -tibB}
 REVISION = ${shell hg log -r . --template '{latesttag}-{latesttagdistance}-{node|short}'}
--- a/abstract.conf	Mon Apr 20 23:07:09 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-[blockdef-listing]
-#subs=verbatim,quotes
-
-
-[quotes]
-#$|=vars
-
-[tags]
-#vars=<code><em>$|</em></code>
--- a/abstract.txt	Mon Apr 20 23:07:09 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1565 +0,0 @@
-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:
-////
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/short.conf	Mon Apr 20 23:07:59 2015 +0200
@@ -0,0 +1,9 @@
+[blockdef-listing]
+#subs=verbatim,quotes
+
+
+[quotes]
+#$|=vars
+
+[tags]
+#vars=<code><em>$|</em></code>
--- /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:
+////