Document DCC in experimental-spec.txt
[exim.git] / doc / doc-txt / experimental-spec.txt
1 From time to time, experimental features may be added to Exim.
2 While a feature  is experimental, there  will be a  build-time
3 option whose name starts  "EXPERIMENTAL_" that must be  set in
4 order to include the  feature. This file contains  information
5 about experimenatal  features, all  of which  are unstable and
6 liable to incompatibile change.
7
8
9 OCSP Stapling support
10 --------------------------------------------------------------
11
12 X509 PKI certificates expire and can be revoked; to handle this, the
13 clients need some way to determine if a particular certificate, from a
14 particular Certificate Authority (CA), is still valid.  There are three
15 main ways to do so.
16
17 The simplest way is to serve up a Certificate Revocation List (CRL) with
18 an ordinary web-server, regenerating the CRL before it expires.  The
19 downside is that clients have to periodically re-download a potentially
20 huge file from every certificate authority it knows of.
21
22 The way with most moving parts at query time is Online Certificate
23 Status Protocol (OCSP), where the client verifies the certificate
24 against an OCSP server run by the CA.  This lets the CA track all
25 usage of the certs.  This requires running software with access to the
26 private key of the CA, to sign the responses to the OCSP queries.  OCSP
27 is based on HTTP and can be proxied accordingly.
28
29 The only widespread OCSP server implementation (known to this writer)
30 comes as part of OpenSSL and aborts on an invalid request, such as
31 connecting to the port and then disconnecting.  This requires
32 re-entering the passphrase each time some random client does this.
33
34 The third way is OCSP Stapling; in this, the server using a certificate
35 issued by the CA periodically requests an OCSP proof of validity from
36 the OCSP server, then serves it up inline as part of the TLS
37 negotiation.   This approach adds no extra round trips, does not let the
38 CA track users, scales well with number of certs issued by the CA and is
39 resilient to temporary OCSP server failures, as long as the server
40 starts retrying to fetch an OCSP proof some time before its current
41 proof expires.  The downside is that it requires server support.
42
43 If Exim is built with EXPERIMENTAL_OCSP and it was built with OpenSSL,
44 then it gains one new option: "tls_ocsp_file".
45
46 The file specified therein is expected to be in DER format, and contain
47 an OCSP proof.  Exim will serve it as part of the TLS handshake.  This
48 option will be re-expanded for SNI, if the tls_certificate option
49 contains $tls_sni, as per other TLS options.
50
51 Exim does not at this time implement any support for fetching a new OCSP
52 proof.  The burden is on the administrator to handle this, outside of
53 Exim.  The file specified should be replaced atomically, so that the
54 contents are always valid.  Exim will expand the "tls_ocsp_file" option
55 on each connection, so a new file will be handled transparently on the
56 next connection.
57
58 Exim will check for a validity next update timestamp in the OCSP proof;
59 if not present, or if the proof has expired, it will be ignored.
60
61 At this point in time, we're gathering feedback on use, to determine if
62 it's worth adding complexity to the Exim daemon to periodically re-fetch
63 OCSP files and somehow handling multiple files.
64
65
66
67
68 Brightmail AntiSpam (BMI) suppport
69 --------------------------------------------------------------
70
71 Brightmail  AntiSpam  is  a  commercial  package.  Please  see
72 http://www.brightmail.com    for    more    information     on
73 the product. For  the sake of  clarity, we'll refer  to it  as
74 "BMI" from now on.
75
76
77 0) BMI concept and implementation overview
78
79 In  contrast  to   how  spam-scanning  with   SpamAssassin  is
80 implemented  in  exiscan-acl,  BMI  is  more  suited  for  per
81 -recipient  scanning of  messages. However,  each messages  is
82 scanned  only  once,  but  multiple  "verdicts"  for  multiple
83 recipients can be  returned from the  BMI server. The  exiscan
84 implementation  passes  the  message to  the  BMI  server just
85 before accepting it.  It then adds  the retrieved verdicts  to
86 the messages header file in the spool. These verdicts can then
87 be  queried  in  routers,  where  operation  is  per-recipient
88 instead  of per-message.  To use  BMI, you  need to  take the
89 following steps:
90
91   1) Compile Exim with BMI support
92   2) Set up main BMI options (top section of Exim config file)
93   3) Set up ACL control statement (ACL section of the config
94      file)
95   4) Set up your routers to use BMI verdicts (routers section
96      of the config file).
97   5) (Optional) Set up per-recipient opt-in information.
98
99 These four steps are explained in more details below.
100
101 1) Adding support for BMI at compile time
102
103   To compile with BMI support,  you need to link Exim  against
104   the   Brighmail  client   SDK,  consisting   of  a   library
105   (libbmiclient_single.so)  and  a  header  file  (bmi_api.h).
106   You'll also need to explicitly set a flag in the Makefile to
107   include BMI support in the Exim binary. Both can be achieved
108   with  these lines in Local/Makefile:
109
110   EXPERIMENTAL_BRIGHTMAIL=yes
111   CFLAGS=-I/path/to/the/dir/with/the/includefile
112   EXTRALIBS_EXIM=-L/path/to/the/dir/with/the/library -lbmiclient_single
113
114   If  you use  other CFLAGS  or EXTRALIBS_EXIM  settings then
115   merge the content of these lines with them.
116
117   Note for BMI6.x users: You'll also have to add -lxml2_single
118   to the EXTRALIBS_EXIM line. Users of 5.5x do not need to  do
119   this.
120
121   You    should     also    include     the    location     of
122   libbmiclient_single.so in your dynamic linker  configuration
123   file   (usually   /etc/ld.so.conf)   and   run    "ldconfig"
124   afterwards, or  else the  produced Exim  binary will  not be
125   able to find the library file.
126
127
128 2) Setting up BMI support in the Exim main configuration
129
130   To enable BMI  support in the  main Exim configuration,  you
131   should set the path to the main BMI configuration file  with
132   the "bmi_config_file" option, like this:
133
134   bmi_config_file = /opt/brightmail/etc/brightmail.cfg
135
136   This must go into section 1 of Exim's configuration file (You
137   can  put it  right on  top). If  you omit  this option,  it
138   defaults to /opt/brightmail/etc/brightmail.cfg.
139
140   Note for BMI6.x users: This  file is in XML format  in V6.xx
141   and its  name is  /opt/brightmail/etc/bmiconfig.xml. So  BMI
142   6.x users MUST set the bmi_config_file option.
143
144
145 3) Set up ACL control statement
146
147   To  optimize performance,  it makes  sense only  to process
148   messages coming from remote, untrusted sources with the  BMI
149   server.  To set  up a  messages for  processing by  the BMI
150   server, you MUST set the "bmi_run" control statement in  any
151   ACL for an incoming message.  You will typically do this  in
152   an "accept"  block in  the "acl_check_rcpt"  ACL. You should
153   use the "accept" block(s)  that accept messages from  remote
154   servers for your own domain(s). Here is an example that uses
155   the "accept" blocks from Exim's default configuration file:
156
157
158   accept  domains       = +local_domains
159           endpass
160           verify        = recipient
161           control       = bmi_run
162
163   accept  domains       = +relay_to_domains
164           endpass
165           verify        = recipient
166           control       = bmi_run
167
168   If bmi_run  is not  set in  any ACL  during reception of the
169   message, it will NOT be passed to the BMI server.
170
171
172 4) Setting up routers to use BMI verdicts
173
174   When a message has been  run through the BMI server,  one or
175   more "verdicts" are  present. Different recipients  can have
176   different verdicts. Each  recipient is treated  individually
177   during routing, so you  can query the verdicts  by recipient
178   at  that stage.  From Exim's  view, a  verdict can  have the
179   following outcomes:
180
181   o deliver the message normally
182   o deliver the message to an alternate location
183   o do not deliver the message
184
185   To query  the verdict  for a  recipient, the  implementation
186   offers the following tools:
187
188
189   - Boolean router  preconditions. These  can be  used in  any
190     router. For a simple  implementation of BMI, these  may be
191     all  that  you  need.  The  following  preconditions   are
192     available:
193
194     o bmi_deliver_default
195
196       This  precondition  is  TRUE  if  the  verdict  for  the
197       recipient is  to deliver  the message  normally. If  the
198       message has not been  processed by the BMI  server, this
199       variable defaults to TRUE.
200
201     o bmi_deliver_alternate
202
203       This  precondition  is  TRUE  if  the  verdict  for  the
204       recipient  is to  deliver the  message to  an alternate
205       location.  You  can  get the  location  string  from the
206       $bmi_alt_location expansion variable if you need it. See
207       further below. If the message has not been processed  by
208       the BMI server, this variable defaults to FALSE.
209
210     o bmi_dont_deliver
211
212       This  precondition  is  TRUE  if  the  verdict  for  the
213       recipient  is  NOT  to   deliver  the  message  to   the
214       recipient. You will typically use this precondition in a
215       top-level blackhole router, like this:
216
217         # don't deliver messages handled by the BMI server
218         bmi_blackhole:
219           driver = redirect
220           bmi_dont_deliver
221           data = :blackhole:
222
223       This router should be on top of all others, so  messages
224       that should not be delivered do not reach other  routers
225       at all. If   the  message  has  not  been  processed  by
226       the  BMI server, this variable defaults to FALSE.
227
228
229   - A list router  precondition to query  if rules "fired"  on
230     the message for the recipient. Its name is "bmi_rule". You
231     use  it  by  passing it  a  colon-separated  list of  rule
232     numbers. You can use this condition to route messages that
233     matched specific rules. Here is an example:
234
235       # special router for BMI rule #5, #8 and #11
236       bmi_rule_redirect:
237         driver = redirect
238         bmi_rule = 5:8:11
239         data = postmaster@mydomain.com
240
241
242   - Expansion variables. Several  expansion variables are  set
243     during  routing.  You  can  use  them  in  custom   router
244     conditions,  for  example.  The  following  variables  are
245     available:
246
247     o $bmi_base64_verdict
248
249       This variable  will contain  the BASE64  encoded verdict
250       for the recipient being routed. You can use it to add  a
251       header to messages for tracking purposes, for example:
252
253       localuser:
254         driver = accept
255         check_local_user
256         headers_add = X-Brightmail-Verdict: $bmi_base64_verdict
257         transport = local_delivery
258
259       If there is no verdict available for the recipient being
260       routed, this variable contains the empty string.
261
262     o $bmi_base64_tracker_verdict
263
264       This variable  will contain  a BASE64  encoded subset of
265       the  verdict  information  concerning  the  "rules" that
266       fired  on the  message. You  can add  this string  to a
267       header, commonly named "X-Brightmail-Tracker". Example:
268
269       localuser:
270         driver = accept
271         check_local_user
272         headers_add = X-Brightmail-Tracker: $bmi_base64_tracker_verdict
273         transport = local_delivery
274
275       If there is no verdict available for the recipient being
276       routed, this variable contains the empty string.
277
278     o $bmi_alt_location
279
280       If  the  verdict  is  to  redirect  the  message  to  an
281       alternate  location,  this  variable  will  contain  the
282       alternate location string returned by the BMI server. In
283       its default configuration, this is a header-like  string
284       that can be added to the message with "headers_add".  If
285       there is  no verdict  available for  the recipient being
286       routed, or if the  message is to be  delivered normally,
287       this variable contains the empty string.
288
289     o $bmi_deliver
290
291       This is an additional integer variable that can be  used
292       to query if the message should be delivered at all.  You
293       should use router preconditions instead if possible.
294
295       $bmi_deliver is '0': the message should NOT be delivered.
296       $bmi_deliver is '1': the message should be delivered.
297
298
299   IMPORTANT NOTE: Verdict inheritance.
300   The  message  is passed  to  the BMI  server  during message
301   reception,  using the  target addresses  from the  RCPT TO:
302   commands in the SMTP transaction. If recipients get expanded
303   or re-written (for example by aliasing), the new address(es)
304   inherit the  verdict from  the original  address. This means
305   that verdicts also apply to all "child" addresses  generated
306   from top-level addresses that were sent to the BMI server.
307
308
309 5) Using per-recipient opt-in information (Optional)
310
311   The  BMI server  features multiple  scanning "profiles"  for
312   individual recipients.  These are  usually stored  in a LDAP
313   server and are  queried by the  BMI server itself.  However,
314   you can also  pass opt-in data  for each recipient  from the
315   MTA to the  BMI server. This  is particularly useful  if you
316   already look  up recipient  data in  Exim anyway  (which can
317   also be  stored in  a SQL  database or  other source).  This
318   implementation enables you  to pass opt-in  data to the  BMI
319   server  in  the  RCPT   ACL.  This  works  by   setting  the
320   'bmi_optin' modifier in  a block of  that ACL. If  should be
321   set to a list  of comma-separated strings that  identify the
322   features which the BMI server should use for that particular
323   recipient. Ideally, you  would use the  'bmi_optin' modifier
324   in the same  ACL block where  you set the  'bmi_run' control
325   flag. Here is an example that will pull opt-in data for each
326   recipient      from       a      flat       file      called
327   '/etc/exim/bmi_optin_data'.
328
329   The file format:
330
331     user1@mydomain.com: <OPTIN STRING1>:<OPTIN STRING2>
332     user2@thatdomain.com: <OPTIN STRING3>
333
334
335   The example:
336
337     accept  domains       = +relay_to_domains
338             endpass
339             verify        = recipient
340             bmi_optin     = ${lookup{$local_part@$domain}lsearch{/etc/exim/bmi_optin_data}}
341             control       = bmi_run
342
343   Of course,  you can  also use  any other  lookup method that
344   Exim supports, including LDAP, Postgres, MySQL, Oracle etc.,
345   as long as  the result is  a list of  colon-separated opt-in
346   strings.
347
348   For a list of available opt-in strings, please contact  your
349   Brightmail representative.
350
351
352
353
354 Sender Policy Framework (SPF) support
355 --------------------------------------------------------------
356
357 To learn  more  about  SPF, visit   http://www.openspf.org. This
358 document does   not explain  the SPF  fundamentals, you should
359 read and understand the implications of deploying SPF on  your
360 system before doing so.
361
362 SPF support is added via the libspf2 library. Visit
363
364   http://www.libspf2.org/
365
366 to obtain  a copy,  then compile  and install  it. By default,
367 this will  put headers  in /usr/local/include  and the  static
368 library in /usr/local/lib.
369
370 To compile Exim with SPF support, set these additional flags in
371 Local/Makefile:
372
373 EXPERIMENTAL_SPF=yes
374 CFLAGS=-DSPF -I/usr/local/include
375 EXTRALIBS_EXIM=-L/usr/local/lib -lspf2
376
377 This assumes   that the   libspf2 files   are installed  in
378 their default locations.
379
380 You can now run SPF checks in incoming SMTP by using the "spf"
381 ACL condition  in either  the MAIL,  RCPT or  DATA ACLs.  When
382 using it in the RCPT ACL, you can make the checks dependend on
383 the RCPT  address (or  domain), so  you can  check SPF records
384 only  for   certain  target   domains.  This   gives  you  the
385 possibility  to opt-out  certain customers  that do  not want
386 their mail to be subject to SPF checking.
387
388 The spf condition  takes a list  of strings on  its right-hand
389 side. These strings describe the outcome of the SPF check  for
390 which the spf condition should succeed. Valid strings are:
391
392   o pass      The SPF check passed, the sending host
393               is positively verified by SPF.
394   o fail      The SPF check failed, the sending host
395               is NOT allowed to send mail for the domain
396               in the envelope-from address.
397   o softfail  The SPF check failed, but the queried
398               domain can't absolutely confirm that this
399               is a forgery.
400   o none      The queried domain does not publish SPF
401               records.
402   o neutral   The SPF check returned a "neutral" state.
403               This means the queried domain has published
404               a SPF record, but wants to allow outside
405               servers to send mail under its domain as well.
406   o err_perm  This indicates a syntax error in the SPF
407               record of the queried domain. This should be
408               treated like "none".
409   o err_temp  This indicates a temporary error during all
410               processing, including Exim's SPF processing.
411               You may defer messages when this occurs.
412
413 You can prefix each string with an exclamation mark to  invert
414 is meaning,  for example  "!fail" will  match all  results but
415 "fail".  The  string  list is  evaluated  left-to-right,  in a
416 short-circuit fashion.  When a  string matches  the outcome of
417 the SPF check, the condition  succeeds. If none of the  listed
418 strings matches the  outcome of the  SPF check, the  condition
419 fails.
420
421 Here is an example to fail forgery attempts from domains that
422 publish SPF records:
423
424 /* -----------------
425 deny message = $sender_host_address is not allowed to send mail from ${if def:sender_address_domain {$sender_address_domain}{$sender_helo_name}}.  \
426               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
427      spf = fail
428 --------------------- */
429
430 You can also give special treatment to specific domains:
431
432 /* -----------------
433 deny message = AOL sender, but not from AOL-approved relay.
434      sender_domains = aol.com
435      spf = fail:neutral
436 --------------------- */
437
438 Explanation: AOL  publishes SPF  records, but  is liberal  and
439 still allows  non-approved relays  to send  mail from aol.com.
440 This will result in a "neutral" state, while mail from genuine
441 AOL servers  will result  in "pass".  The example  above takes
442 this into account and  treats "neutral" like "fail",  but only
443 for aol.com. Please note that this violates the SPF draft.
444
445 When the spf condition has run, it sets up several expansion
446 variables.
447
448   $spf_header_comment
449   This contains a human-readable string describing the outcome
450   of the SPF check. You can add it to a custom header or use
451   it for logging purposes.
452
453   $spf_received
454   This contains a complete Received-SPF: header that can be
455   added to the message. Please note that according to the SPF
456   draft, this header must be added at the top of the header
457   list. Please see section 10 on how you can do this.
458
459   Note: in case of "Best-guess" (see below), the convention is
460   to put this string in a header called X-SPF-Guess: instead.
461
462   $spf_result
463   This contains the outcome of the SPF check in string form,
464   one of pass, fail, softfail, none, neutral, err_perm or
465   err_temp.
466
467   $spf_smtp_comment
468   This contains a string that can be used in a SMTP response
469   to the calling party. Useful for "fail".
470
471 In addition to SPF, you can also perform checks for so-called
472 "Best-guess".  Strictly speaking, "Best-guess" is not standard
473 SPF, but it is supported by the same framework that enables SPF
474 capability.  Refer to http://www.openspf.org/FAQ/Best_guess_record
475 for a description of what it means.
476
477 To access this feature, simply use the spf_guess condition in place
478 of the spf one.  For example:
479
480 /* -----------------
481 deny message = $sender_host_address doesn't look trustworthy to me
482      spf_guess = fail
483 --------------------- */
484
485 In case you decide to reject messages based on this check, you
486 should note that although it uses the same framework, "Best-guess"
487 is NOT SPF, and therefore you should not mention SPF at all in your
488 reject message.
489
490 When the spf_guess condition has run, it sets up the same expansion
491 variables as when spf condition is run, described above.
492
493 Additionally, since Best-guess is not standarized, you may redefine
494 what "Best-guess" means to you by redefining spf_guess variable in
495 global config.  For example, the following:
496
497 /* -----------------
498 spf_guess = v=spf1 a/16 mx/16 ptr ?all
499 --------------------- */
500
501 would relax host matching rules to a broader network range.
502
503
504 SRS (Sender Rewriting Scheme) Support
505 --------------------------------------------------------------
506
507 Exiscan  currently  includes SRS  support  via Miles  Wilton's
508 libsrs_alt library. The current version of the supported
509 library is 0.5.
510
511 In order to  use SRS, you  must get a  copy of libsrs_alt from
512
513 http://srs.mirtol.com/
514
515 Unpack the tarball, then refer to MTAs/README.EXIM
516 to proceed. You need to set
517
518 EXPERIMENTAL_SRS=yes
519
520 in your Local/Makefile.
521
522
523 DCC Support
524 --------------------------------------------------------------
525
526 *) Building exim
527
528 In order to build exim with DCC support add
529
530 EXPERIMENTAL_DCC=yes
531
532 to your Makefile. (Re-)build/install exim. exim -d should show
533 EXPERIMENTAL_DCC under "Support for".
534
535
536 *) Configuration
537
538 In the main section of exim.cf add at least
539   dccifd_address = /usr/local/dcc/var/dccifd
540 or
541   dccifd_address = <ip> <port>
542
543 In the DATA ACL you can use the new condition
544         dcc = *
545
546 After that "$dcc_header" contains the X-DCC-Header.
547
548 Returnvalues are:
549   fail    for overall "R", "G" from dccifd
550   defer   for overall "T" from dccifd
551   accept  for overall "A", "S" from dccifd
552
553 dcc = */defer_ok works as for spamd.
554
555 The "$dcc_result" variable contains the overall result from DCC
556 answer.  There will an X-DCC: header added to the mail.
557
558 Usually you'll use
559   defer   !dcc = *
560 to greylist with DCC.
561
562 If you set, in the main section,
563   dcc_direct_add_header = true
564 then the dcc header will be added "in deep" and if the spool
565 file was already written it gets removed. This forces Exim to
566 write it again if needed.  This helps to get the DCC Header
567 through to eg. SpamAssassin.
568
569 If you want to pass even more headers in the middle of the
570 DATA stage you can set
571   $acl_m_dcc_add_header
572 to tell the DCC routines add more information; eg, you might set
573 this to some results from ClamAV.  Be careful.  Header syntax is
574 not checked and is added "as is".
575
576
577 --------------------------------------------------------------
578 End of file
579 --------------------------------------------------------------