Merge branch 'master' of ssh://git.exim.org/home/git/exim
[exim.git] / doc / doc-txt / experimental-spec.txt
1 $Cambridge: exim/doc/doc-txt/experimental-spec.txt,v 1.12 2009/06/11 14:07:57 tom Exp $
2
3 From time to time, experimental features may be added to Exim.
4 While a feature  is experimental, there  will be a  build-time
5 option whose name starts  "EXPERIMENTAL_" that must be  set in
6 order to include the  feature. This file contains  information
7 about experimenatal  features, all  of which  are unstable and
8 liable to incompatibile change.
9
10
11 Brightmail AntiSpam (BMI) suppport
12 --------------------------------------------------------------
13
14 Brightmail  AntiSpam  is  a  commercial  package.  Please  see
15 http://www.brightmail.com    for    more    information     on
16 the product. For  the sake of  clarity, we'll refer  to it  as
17 "BMI" from now on.
18
19
20 0) BMI concept and implementation overview
21
22 In  contrast  to   how  spam-scanning  with   SpamAssassin  is
23 implemented  in  exiscan-acl,  BMI  is  more  suited  for  per
24 -recipient  scanning of  messages. However,  each messages  is
25 scanned  only  once,  but  multiple  "verdicts"  for  multiple
26 recipients can be  returned from the  BMI server. The  exiscan
27 implementation  passes  the  message to  the  BMI  server just
28 before accepting it.  It then adds  the retrieved verdicts  to
29 the messages header file in the spool. These verdicts can then
30 be  queried  in  routers,  where  operation  is  per-recipient
31 instead  of per-message.  To use  BMI, you  need to  take the
32 following steps:
33
34   1) Compile Exim with BMI support
35   2) Set up main BMI options (top section of Exim config file)
36   3) Set up ACL control statement (ACL section of the config
37      file)
38   4) Set up your routers to use BMI verdicts (routers section
39      of the config file).
40   5) (Optional) Set up per-recipient opt-in information.
41
42 These four steps are explained in more details below.
43
44 1) Adding support for BMI at compile time
45
46   To compile with BMI support,  you need to link Exim  against
47   the   Brighmail  client   SDK,  consisting   of  a   library
48   (libbmiclient_single.so)  and  a  header  file  (bmi_api.h).
49   You'll also need to explicitly set a flag in the Makefile to
50   include BMI support in the Exim binary. Both can be achieved
51   with  these lines in Local/Makefile:
52
53   EXPERIMENTAL_BRIGHTMAIL=yes
54   CFLAGS=-I/path/to/the/dir/with/the/includefile
55   EXTRALIBS_EXIM=-L/path/to/the/dir/with/the/library -lbmiclient_single
56
57   If  you use  other CFLAGS  or EXTRALIBS_EXIM  settings then
58   merge the content of these lines with them.
59
60   Note for BMI6.x users: You'll also have to add -lxml2_single
61   to the EXTRALIBS_EXIM line. Users of 5.5x do not need to  do
62   this.
63
64   You    should     also    include     the    location     of
65   libbmiclient_single.so in your dynamic linker  configuration
66   file   (usually   /etc/ld.so.conf)   and   run    "ldconfig"
67   afterwards, or  else the  produced Exim  binary will  not be
68   able to find the library file.
69
70
71 2) Setting up BMI support in the Exim main configuration
72
73   To enable BMI  support in the  main Exim configuration,  you
74   should set the path to the main BMI configuration file  with
75   the "bmi_config_file" option, like this:
76
77   bmi_config_file = /opt/brightmail/etc/brightmail.cfg
78
79   This must go into section 1 of Exim's configuration file (You
80   can  put it  right on  top). If  you omit  this option,  it
81   defaults to /opt/brightmail/etc/brightmail.cfg.
82
83   Note for BMI6.x users: This  file is in XML format  in V6.xx
84   and its  name is  /opt/brightmail/etc/bmiconfig.xml. So  BMI
85   6.x users MUST set the bmi_config_file option.
86
87
88 3) Set up ACL control statement
89
90   To  optimize performance,  it makes  sense only  to process
91   messages coming from remote, untrusted sources with the  BMI
92   server.  To set  up a  messages for  processing by  the BMI
93   server, you MUST set the "bmi_run" control statement in  any
94   ACL for an incoming message.  You will typically do this  in
95   an "accept"  block in  the "acl_check_rcpt"  ACL. You should
96   use the "accept" block(s)  that accept messages from  remote
97   servers for your own domain(s). Here is an example that uses
98   the "accept" blocks from Exim's default configuration file:
99
100
101   accept  domains       = +local_domains
102           endpass
103           verify        = recipient
104           control       = bmi_run
105
106   accept  domains       = +relay_to_domains
107           endpass
108           verify        = recipient
109           control       = bmi_run
110
111   If bmi_run  is not  set in  any ACL  during reception of the
112   message, it will NOT be passed to the BMI server.
113
114
115 4) Setting up routers to use BMI verdicts
116
117   When a message has been  run through the BMI server,  one or
118   more "verdicts" are  present. Different recipients  can have
119   different verdicts. Each  recipient is treated  individually
120   during routing, so you  can query the verdicts  by recipient
121   at  that stage.  From Exim's  view, a  verdict can  have the
122   following outcomes:
123
124   o deliver the message normally
125   o deliver the message to an alternate location
126   o do not deliver the message
127
128   To query  the verdict  for a  recipient, the  implementation
129   offers the following tools:
130
131
132   - Boolean router  preconditions. These  can be  used in  any
133     router. For a simple  implementation of BMI, these  may be
134     all  that  you  need.  The  following  preconditions   are
135     available:
136
137     o bmi_deliver_default
138
139       This  precondition  is  TRUE  if  the  verdict  for  the
140       recipient is  to deliver  the message  normally. If  the
141       message has not been  processed by the BMI  server, this
142       variable defaults to TRUE.
143
144     o bmi_deliver_alternate
145
146       This  precondition  is  TRUE  if  the  verdict  for  the
147       recipient  is to  deliver the  message to  an alternate
148       location.  You  can  get the  location  string  from the
149       $bmi_alt_location expansion variable if you need it. See
150       further below. If the message has not been processed  by
151       the BMI server, this variable defaults to FALSE.
152
153     o bmi_dont_deliver
154
155       This  precondition  is  TRUE  if  the  verdict  for  the
156       recipient  is  NOT  to   deliver  the  message  to   the
157       recipient. You will typically use this precondition in a
158       top-level blackhole router, like this:
159
160         # don't deliver messages handled by the BMI server
161         bmi_blackhole:
162           driver = redirect
163           bmi_dont_deliver
164           data = :blackhole:
165
166       This router should be on top of all others, so  messages
167       that should not be delivered do not reach other  routers
168       at all. If   the  message  has  not  been  processed  by
169       the  BMI server, this variable defaults to FALSE.
170
171
172   - A list router  precondition to query  if rules "fired"  on
173     the message for the recipient. Its name is "bmi_rule". You
174     use  it  by  passing it  a  colon-separated  list of  rule
175     numbers. You can use this condition to route messages that
176     matched specific rules. Here is an example:
177
178       # special router for BMI rule #5, #8 and #11
179       bmi_rule_redirect:
180         driver = redirect
181         bmi_rule = 5:8:11
182         data = postmaster@mydomain.com
183
184
185   - Expansion variables. Several  expansion variables are  set
186     during  routing.  You  can  use  them  in  custom   router
187     conditions,  for  example.  The  following  variables  are
188     available:
189
190     o $bmi_base64_verdict
191
192       This variable  will contain  the BASE64  encoded verdict
193       for the recipient being routed. You can use it to add  a
194       header to messages for tracking purposes, for example:
195
196       localuser:
197         driver = accept
198         check_local_user
199         headers_add = X-Brightmail-Verdict: $bmi_base64_verdict
200         transport = local_delivery
201
202       If there is no verdict available for the recipient being
203       routed, this variable contains the empty string.
204
205     o $bmi_base64_tracker_verdict
206
207       This variable  will contain  a BASE64  encoded subset of
208       the  verdict  information  concerning  the  "rules" that
209       fired  on the  message. You  can add  this string  to a
210       header, commonly named "X-Brightmail-Tracker". Example:
211
212       localuser:
213         driver = accept
214         check_local_user
215         headers_add = X-Brightmail-Tracker: $bmi_base64_tracker_verdict
216         transport = local_delivery
217
218       If there is no verdict available for the recipient being
219       routed, this variable contains the empty string.
220
221     o $bmi_alt_location
222
223       If  the  verdict  is  to  redirect  the  message  to  an
224       alternate  location,  this  variable  will  contain  the
225       alternate location string returned by the BMI server. In
226       its default configuration, this is a header-like  string
227       that can be added to the message with "headers_add".  If
228       there is  no verdict  available for  the recipient being
229       routed, or if the  message is to be  delivered normally,
230       this variable contains the empty string.
231
232     o $bmi_deliver
233
234       This is an additional integer variable that can be  used
235       to query if the message should be delivered at all.  You
236       should use router preconditions instead if possible.
237
238       $bmi_deliver is '0': the message should NOT be delivered.
239       $bmi_deliver is '1': the message should be delivered.
240
241
242   IMPORTANT NOTE: Verdict inheritance.
243   The  message  is passed  to  the BMI  server  during message
244   reception,  using the  target addresses  from the  RCPT TO:
245   commands in the SMTP transaction. If recipients get expanded
246   or re-written (for example by aliasing), the new address(es)
247   inherit the  verdict from  the original  address. This means
248   that verdicts also apply to all "child" addresses  generated
249   from top-level addresses that were sent to the BMI server.
250
251
252 5) Using per-recipient opt-in information (Optional)
253
254   The  BMI server  features multiple  scanning "profiles"  for
255   individual recipients.  These are  usually stored  in a LDAP
256   server and are  queried by the  BMI server itself.  However,
257   you can also  pass opt-in data  for each recipient  from the
258   MTA to the  BMI server. This  is particularly useful  if you
259   already look  up recipient  data in  Exim anyway  (which can
260   also be  stored in  a SQL  database or  other source).  This
261   implementation enables you  to pass opt-in  data to the  BMI
262   server  in  the  RCPT   ACL.  This  works  by   setting  the
263   'bmi_optin' modifier in  a block of  that ACL. If  should be
264   set to a list  of comma-separated strings that  identify the
265   features which the BMI server should use for that particular
266   recipient. Ideally, you  would use the  'bmi_optin' modifier
267   in the same  ACL block where  you set the  'bmi_run' control
268   flag. Here is an example that will pull opt-in data for each
269   recipient      from       a      flat       file      called
270   '/etc/exim/bmi_optin_data'.
271
272   The file format:
273
274     user1@mydomain.com: <OPTIN STRING1>:<OPTIN STRING2>
275     user2@thatdomain.com: <OPTIN STRING3>
276
277
278   The example:
279
280     accept  domains       = +relay_to_domains
281             endpass
282             verify        = recipient
283             bmi_optin     = ${lookup{$local_part@$domain}lsearch{/etc/exim/bmi_optin_data}}
284             control       = bmi_run
285
286   Of course,  you can  also use  any other  lookup method that
287   Exim supports, including LDAP, Postgres, MySQL, Oracle etc.,
288   as long as  the result is  a list of  colon-separated opt-in
289   strings.
290
291   For a list of available opt-in strings, please contact  your
292   Brightmail representative.
293
294
295
296
297 Sender Policy Framework (SPF) support
298 --------------------------------------------------------------
299
300 To learn  more  about  SPF, visit   http://www.openspf.org. This
301 document does   not explain  the SPF  fundamentals, you should
302 read and understand the implications of deploying SPF on  your
303 system before doing so.
304
305 SPF support is added via the libspf2 library. Visit
306
307   http://www.libspf2.org/
308
309 to obtain  a copy,  then compile  and install  it. By default,
310 this will  put headers  in /usr/local/include  and the  static
311 library in /usr/local/lib.
312
313 To compile Exim with SPF support, set these additional flags in
314 Local/Makefile:
315
316 EXPERIMENTAL_SPF=yes
317 CFLAGS=-DSPF -I/usr/local/include
318 EXTRALIBS_EXIM=-L/usr/local/lib -lspf2
319
320 This assumes   that the   libspf2 files   are installed  in
321 their default locations.
322
323 You can now run SPF checks in incoming SMTP by using the "spf"
324 ACL condition  in either  the MAIL,  RCPT or  DATA ACLs.  When
325 using it in the RCPT ACL, you can make the checks dependend on
326 the RCPT  address (or  domain), so  you can  check SPF records
327 only  for   certain  target   domains.  This   gives  you  the
328 possibility  to opt-out  certain customers  that do  not want
329 their mail to be subject to SPF checking.
330
331 The spf condition  takes a list  of strings on  its right-hand
332 side. These strings describe the outcome of the SPF check  for
333 which the spf condition should succeed. Valid strings are:
334
335   o pass      The SPF check passed, the sending host
336               is positively verified by SPF.
337   o fail      The SPF check failed, the sending host
338               is NOT allowed to send mail for the domain
339               in the envelope-from address.
340   o softfail  The SPF check failed, but the queried
341               domain can't absolutely confirm that this
342               is a forgery.
343   o none      The queried domain does not publish SPF
344               records.
345   o neutral   The SPF check returned a "neutral" state.
346               This means the queried domain has published
347               a SPF record, but wants to allow outside
348               servers to send mail under its domain as well.
349   o err_perm  This indicates a syntax error in the SPF
350               record of the queried domain. This should be
351               treated like "none".
352   o err_temp  This indicates a temporary error during all
353               processing, including Exim's SPF processing.
354               You may defer messages when this occurs.
355
356 You can prefix each string with an exclamation mark to  invert
357 is meaning,  for example  "!fail" will  match all  results but
358 "fail".  The  string  list is  evaluated  left-to-right,  in a
359 short-circuit fashion.  When a  string matches  the outcome of
360 the SPF check, the condition  succeeds. If none of the  listed
361 strings matches the  outcome of the  SPF check, the  condition
362 fails.
363
364 Here is an example to fail forgery attempts from domains that
365 publish SPF records:
366
367 /* -----------------
368 deny message = $sender_host_address is not allowed to send mail from ${if def:sender_address_domain {$sender_address_domain}{$sender_helo_name}}.  \
369               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
370      spf = fail
371 --------------------- */
372
373 You can also give special treatment to specific domains:
374
375 /* -----------------
376 deny message = AOL sender, but not from AOL-approved relay.
377      sender_domains = aol.com
378      spf = fail:neutral
379 --------------------- */
380
381 Explanation: AOL  publishes SPF  records, but  is liberal  and
382 still allows  non-approved relays  to send  mail from aol.com.
383 This will result in a "neutral" state, while mail from genuine
384 AOL servers  will result  in "pass".  The example  above takes
385 this into account and  treats "neutral" like "fail",  but only
386 for aol.com. Please note that this violates the SPF draft.
387
388 When the spf condition has run, it sets up several expansion
389 variables.
390
391   $spf_header_comment
392   This contains a human-readable string describing the outcome
393   of the SPF check. You can add it to a custom header or use
394   it for logging purposes.
395
396   $spf_received
397   This contains a complete Received-SPF: header that can be
398   added to the message. Please note that according to the SPF
399   draft, this header must be added at the top of the header
400   list. Please see section 10 on how you can do this.
401
402   Note: in case of "Best-guess" (see below), the convention is
403   to put this string in a header called X-SPF-Guess: instead.
404
405   $spf_result
406   This contains the outcome of the SPF check in string form,
407   one of pass, fail, softfail, none, neutral, err_perm or
408   err_temp.
409
410   $spf_smtp_comment
411   This contains a string that can be used in a SMTP response
412   to the calling party. Useful for "fail".
413
414 In addition to SPF, you can also perform checks for so-called
415 "Best-guess".  Strictly speaking, "Best-guess" is not standard
416 SPF, but it is supported by the same framework that enables SPF
417 capability.  Refer to http://www.openspf.org/FAQ/Best_guess_record
418 for a description of what it means.
419
420 To access this feature, simply use the spf_guess condition in place
421 of the spf one.  For example:
422
423 /* -----------------
424 deny message = $sender_host_address doesn't look trustworthy to me
425      spf_guess = fail
426 --------------------- */
427
428 In case you decide to reject messages based on this check, you
429 should note that although it uses the same framework, "Best-guess"
430 is NOT SPF, and therefore you should not mention SPF at all in your
431 reject message.
432
433 When the spf_guess condition has run, it sets up the same expansion
434 variables as when spf condition is run, described above.
435
436 Additionally, since Best-guess is not standarized, you may redefine
437 what "Best-guess" means to you by redefining spf_guess variable in
438 global config.  For example, the following:
439
440 /* -----------------
441 spf_guess = v=spf1 a/16 mx/16 ptr ?all
442 --------------------- */
443
444 would relax host matching rules to a broader network range.
445
446
447 SRS (Sender Rewriting Scheme) Support
448 --------------------------------------------------------------
449
450 Exiscan  currently  includes SRS  support  via Miles  Wilton's
451 libsrs_alt library. The current version of the supported
452 library is 0.5.
453
454 In order to  use SRS, you  must get a  copy of libsrs_alt from
455
456 http://srs.mirtol.com/
457
458 Unpack the tarball, then refer to MTAs/README.EXIM
459 to proceed. You need to set
460
461 EXPERIMENTAL_SRS=yes
462
463 in your Local/Makefile.
464
465
466 --------------------------------------------------------------
467 End of file
468 --------------------------------------------------------------