Integrated SPF Best Guess. Fixes: bug #521
[exim.git] / doc / doc-txt / experimental-spec.txt
index 8ca491c1ab33e72a464e97fc88c4a748b5d72d4a..4175173c320d5cf1113133a8dd7117807a152e54 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/experimental-spec.txt,v 1.7 2007/07/27 13:56:24 magnus Exp $
+$Cambridge: exim/doc/doc-txt/experimental-spec.txt,v 1.11 2008/02/12 12:52:51 nm4 Exp $
 
 From time to time, experimental features may be added to Exim.
 While a feature  is experimental, there  will be a  build-time
@@ -8,6 +8,157 @@ about experimenatal  features, all  of which  are unstable and
 liable to incompatibile change.
 
 
+0. DKIM support
+--------------------------------------------------------------
+
+DKIM support is implemented via libdkim. A compatible version
+is available here:
+
+http://duncanthrax.net/exim-experimental/libdkim-1.0.15-tk.tar.gz
+
+Build the lib according to the instructions in the enclosed
+INSTALL file.
+
+To build Exim with DKIM support, specify this in Local/Makefile:
+
+EXPERIMENTAL_DKIM=yes
+CFLAGS  += -I/home/tom/libdkim/include
+LDFLAGS += -ldkim -lssl -lstdc++ -L/home/tom/libdkim/lib
+
+Remember to tweak  the CFLAGS and  LDFLAGS lines to  match the
+location of the libdomainkeys includes and lib on your system.
+
+The current experimental implementation supports two independent
+functions:
+
+o Validate incoming DKIM-signed email.
+o Sign outgoing email with DKIM.
+
+The former is implemented in the ACLs for SMTP, the latter  as
+an extension to the SMTP transport. That means both facilities
+are limited to SMTP I/O.
+
+
+1) Validate incoming email
+
+Incoming messages are fed to the DKIM validation process as they
+are received "on  the wire". This happens synchronously to Exim's
+buffering of the message in the spool.
+
+You must set "control = dkim_verify" in one of the ACLs preceding
+DATA (you will typically use acl_smtp_rcpt), at a point where
+non-local, non-relay, non-submission mail is processed. If that
+control flag is not set, the message will NOT be verified.
+
+Example:
+
+warn log_message = Feeding message to DKIM validator.
+     control = dk_verify
+
+You can then check for DKIM signatures in the ACL after data
+(acl_smtp_data), using the 'dkim' query-style lookup type. The
+query string should be a domain or DKIM identity:
+
+${lookup dkim{domain.example}}
+
+Such a lookup will yield one of the following strings:
+
+unverified: Exim did not (yet) verify the eventual DKIM
+            signatures in this message. This may happen
+            if a) You did not use control=dkim_verify
+            or b) You are using the lookup before
+            the DATA ACL.
+
+unsigned:   The message does not have a signature from
+            the specified domain.
+
+good:       The message has a signature from the specified
+            domain, and it verified successfully.
+
+bad:        The message has a signature from the specified
+            domain, but it did not verify.
+
+defer:      A temporary DNS problem was encountered while
+            trying to verify the signature.
+
+
+
+2) Sign outgoing email with DKIM
+
+Outgoing messages are  signed just before  Exim puts them  "on
+the wire".  The only  thing that happens after DKIM signing is
+eventual TLS encryption.
+
+Signing is implemented by setting private options on the  SMTP
+transport.  These   options  take   (expandable)  strings   as
+arguments.
+
+  dkim_domain = <expanded string> [MANDATORY]
+
+    The domain you want to sign with. Should optimally match
+    the domain in the "From:" header of the message, but
+    does not necessarily have to. The result of this expanded
+    option is put into the $dkim_domain expansion variable.
+
+  dkim_selector = <expanded string> [MANDATORY]
+
+    This  sets  the  key  selector  string.  You  can  use the
+    $dkim_domain  expansion  variable  to  look  up  a  matching
+    selector.  The result  is put  in the  expansion  variable
+    $dkim_selector which  should be  used in  the dkim_private_key
+    option along with $dkim_domain.
+
+  dkim_private_key = <expanded string> [MANDATORY]
+
+    This  sets the  private key to use. You can use the
+    $dkim_domain and  $dkim_selector expansion variables to
+    determine the private key to use. The result can either
+
+      o be a valid RSA private key in ASCII armor, including
+        line breaks.
+      o start with a slash, in which case it is treated as
+        a file that contains the private key.
+      o be "0", "false" or the empty string, in which case
+        the message will not be signed. This case will not
+        result in an error, even if dkim_strict is set.
+
+  dkim_canon = <expanded string> [OPTIONAL]
+
+    This option sets the canonicalization method used when
+    signing a message. The DKIM RFC currently supports two
+    methods: "simple" and "relaxed".  The option defaults to
+    "relaxed" when unset. Note: the current implementation
+    only support using the same canonicalization method for
+    both headers and body.
+
+  dkim_strict = <expanded string> [OPTIONAL]
+
+    This  option  defines  how  Exim  behaves  when  signing a
+    message that should be signed fails for some reason.  When
+    the expansion evaluates to either "1" or "true", Exim will
+    defer. Otherwise Exim will send the message unsigned.  You
+    can  use the $dkim_domain and $dkim_selector expansion
+    variables here.
+
+  dkim_sign_headers = <expanded string> [OPTIONAL]
+
+    When set, this option must expand to (or be specified as)
+    a colon-separated list of header names. These headers will
+    be included in the message signature. When unspecified,
+    the recommended headers will be used. Currently, these
+    are:
+
+    from:sender:reply-to:subject:date:
+    message-id:to:cc:mime-version:content-type:
+    content-transfer-encoding:content-id:
+    content-description:resent-date:resent-from:
+    resent-sender:resent-to:resent-cc:resent-message-id:
+    in-reply-to:references:
+    list-id:list-help:list-unsubscribe:
+    list-subscribe:list-post:list-owner:list-archive
+
+
+
 
 1. Yahoo DomainKeys support
 --------------------------------------------------------------
@@ -546,7 +697,7 @@ These four steps are explained in more details below.
 3. Sender Policy Framework (SPF) support
 --------------------------------------------------------------
 
-To learn  more  about  SPF, visit   http://spf.pobox.com. This
+To learn  more  about  SPF, visit   http://www.openspf.org. This
 document does   not explain  the SPF  fundamentals, you should
 read and understand the implications of deploying SPF on  your
 system before doing so.
@@ -610,11 +761,12 @@ the SPF check, the condition  succeeds. If none of the  listed
 strings matches the  outcome of the  SPF check, the  condition
 fails.
 
-Here is a simple example to fail forgery attempts from domains
-that publish SPF records:
+Here is an example to fail forgery attempts from domains that
+publish SPF records:
 
 /* -----------------
-deny message = $sender_host_address is not allowed to send mail from $sender_address_domain
+deny message = $sender_host_address is not allowed to send mail from ${if def:sender_address_domain {$sender_address_domain}{$sender_helo_name}}.  \
+              Please see http://www.openspf.org/Why?scope=${if def:sender_address_domain {mfrom}{helo}};identity=${if def:sender_address_domain {$sender_address}{$sender_helo_name}};ip=$sender_host_address
      spf = fail
 --------------------- */
 
@@ -647,6 +799,9 @@ variables.
   draft, this header must be added at the top of the header
   list. Please see section 10 on how you can do this.
 
+  Note: in case of "Best-guess" (see below), the convention is
+  to put this string in a header called X-SPF-Guess: instead.
+
   $spf_result
   This contains the outcome of the SPF check in string form,
   one of pass, fail, softfail, none, neutral, err_perm or
@@ -656,6 +811,37 @@ variables.
   This contains a string that can be used in a SMTP response
   to the calling party. Useful for "fail".
 
+In addition to SPF, you can also perform checks for so-called
+"Best-guess".  Strictly speaking, "Best-guess" is not standard
+SPF, but it is supported by the same framework that enables SPF
+capability.  Refer to http://www.openspf.org/FAQ/Best_guess_record
+for a description of what it means.
+
+To access this feature, simply use the spf_guess condition in place
+of the spf one.  For example:
+
+/* -----------------
+deny message = $sender_host_address doesn't look trustworthy to me
+     spf_guess = fail
+--------------------- */
+
+In case you decide to reject messages based on this check, you
+should note that although it uses the same framework, "Best-guess"
+is NOT SPF, and therefore you should not mention SPF at all in your
+reject message.
+
+When the spf_guess condition has run, it sets up the same expansion
+variables as when spf condition is run, described above.
+
+Additionally, since Best-guess is not standarized, you may redefine
+what "Best-guess" means to you by redefining spf_guess variable in
+global config.  For example, the following:
+
+/* -----------------
+spf_guess = v=spf1 a/16 mx/16 ptr ?all
+--------------------- */
+
+would relax host matching rules to a broader network range.
 
 
 4. SRS (Sender Rewriting Scheme) Support