Commit | Line | Data |
---|---|---|
65a7d8c3 | 1 | $Cambridge: exim/doc/doc-txt/experimental-spec.txt,v 1.11 2008/02/12 12:52:51 nm4 Exp $ |
ee161e8f | 2 | |
7bafa7d9 TK |
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 | |
ee161e8f PH |
8 | liable to incompatibile change. |
9 | ||
10 | ||
b80649a9 TK |
11 | 0. DKIM support |
12 | -------------------------------------------------------------- | |
13 | ||
14 | DKIM support is implemented via libdkim. A compatible version | |
15 | is available here: | |
16 | ||
17 | http://duncanthrax.net/exim-experimental/libdkim-1.0.15-tk.tar.gz | |
18 | ||
19 | Build the lib according to the instructions in the enclosed | |
20 | INSTALL file. | |
21 | ||
22 | To build Exim with DKIM support, specify this in Local/Makefile: | |
23 | ||
24 | EXPERIMENTAL_DKIM=yes | |
25 | CFLAGS += -I/home/tom/libdkim/include | |
26 | LDFLAGS += -ldkim -lssl -lstdc++ -L/home/tom/libdkim/lib | |
27 | ||
28 | Remember to tweak the CFLAGS and LDFLAGS lines to match the | |
29 | location of the libdomainkeys includes and lib on your system. | |
30 | ||
31 | The current experimental implementation supports two independent | |
32 | functions: | |
33 | ||
34 | o Validate incoming DKIM-signed email. | |
35 | o Sign outgoing email with DKIM. | |
36 | ||
37 | The former is implemented in the ACLs for SMTP, the latter as | |
38 | an extension to the SMTP transport. That means both facilities | |
39 | are limited to SMTP I/O. | |
40 | ||
41 | ||
42 | 1) Validate incoming email | |
43 | ||
44 | Incoming messages are fed to the DKIM validation process as they | |
45 | are received "on the wire". This happens synchronously to Exim's | |
46 | buffering of the message in the spool. | |
47 | ||
48 | You must set "control = dkim_verify" in one of the ACLs preceding | |
49 | DATA (you will typically use acl_smtp_rcpt), at a point where | |
50 | non-local, non-relay, non-submission mail is processed. If that | |
51 | control flag is not set, the message will NOT be verified. | |
52 | ||
53 | Example: | |
54 | ||
55 | warn log_message = Feeding message to DKIM validator. | |
56 | control = dk_verify | |
57 | ||
58 | You can then check for DKIM signatures in the ACL after data | |
59 | (acl_smtp_data), using the 'dkim' query-style lookup type. The | |
60 | query string should be a domain or DKIM identity: | |
61 | ||
62 | ${lookup dkim{domain.example}} | |
63 | ||
64 | Such a lookup will yield one of the following strings: | |
65 | ||
66 | unverified: Exim did not (yet) verify the eventual DKIM | |
67 | signatures in this message. This may happen | |
68 | if a) You did not use control=dkim_verify | |
69 | or b) You are using the lookup before | |
70 | the DATA ACL. | |
71 | ||
72 | unsigned: The message does not have a signature from | |
73 | the specified domain. | |
74 | ||
75 | good: The message has a signature from the specified | |
76 | domain, and it verified successfully. | |
77 | ||
78 | bad: The message has a signature from the specified | |
79 | domain, but it did not verify. | |
80 | ||
81 | defer: A temporary DNS problem was encountered while | |
82 | trying to verify the signature. | |
83 | ||
84 | ||
85 | ||
86 | 2) Sign outgoing email with DKIM | |
87 | ||
88 | Outgoing messages are signed just before Exim puts them "on | |
89 | the wire". The only thing that happens after DKIM signing is | |
90 | eventual TLS encryption. | |
91 | ||
92 | Signing is implemented by setting private options on the SMTP | |
93 | transport. These options take (expandable) strings as | |
94 | arguments. | |
95 | ||
96 | dkim_domain = <expanded string> [MANDATORY] | |
97 | ||
98 | The domain you want to sign with. Should optimally match | |
99 | the domain in the "From:" header of the message, but | |
100 | does not necessarily have to. The result of this expanded | |
101 | option is put into the $dkim_domain expansion variable. | |
102 | ||
103 | dkim_selector = <expanded string> [MANDATORY] | |
104 | ||
105 | This sets the key selector string. You can use the | |
106 | $dkim_domain expansion variable to look up a matching | |
107 | selector. The result is put in the expansion variable | |
108 | $dkim_selector which should be used in the dkim_private_key | |
109 | option along with $dkim_domain. | |
110 | ||
111 | dkim_private_key = <expanded string> [MANDATORY] | |
112 | ||
113 | This sets the private key to use. You can use the | |
114 | $dkim_domain and $dkim_selector expansion variables to | |
115 | determine the private key to use. The result can either | |
116 | ||
117 | o be a valid RSA private key in ASCII armor, including | |
118 | line breaks. | |
119 | o start with a slash, in which case it is treated as | |
120 | a file that contains the private key. | |
121 | o be "0", "false" or the empty string, in which case | |
122 | the message will not be signed. This case will not | |
123 | result in an error, even if dkim_strict is set. | |
124 | ||
125 | dkim_canon = <expanded string> [OPTIONAL] | |
126 | ||
127 | This option sets the canonicalization method used when | |
128 | signing a message. The DKIM RFC currently supports two | |
129 | methods: "simple" and "relaxed". The option defaults to | |
130 | "relaxed" when unset. Note: the current implementation | |
131 | only support using the same canonicalization method for | |
132 | both headers and body. | |
133 | ||
134 | dkim_strict = <expanded string> [OPTIONAL] | |
135 | ||
136 | This option defines how Exim behaves when signing a | |
137 | message that should be signed fails for some reason. When | |
138 | the expansion evaluates to either "1" or "true", Exim will | |
139 | defer. Otherwise Exim will send the message unsigned. You | |
140 | can use the $dkim_domain and $dkim_selector expansion | |
141 | variables here. | |
142 | ||
e7f87740 TK |
143 | dkim_sign_headers = <expanded string> [OPTIONAL] |
144 | ||
145 | When set, this option must expand to (or be specified as) | |
146 | a colon-separated list of header names. These headers will | |
147 | be included in the message signature. When unspecified, | |
148 | the recommended headers will be used. Currently, these | |
149 | are: | |
150 | ||
151 | from:sender:reply-to:subject:date: | |
152 | message-id:to:cc:mime-version:content-type: | |
153 | content-transfer-encoding:content-id: | |
154 | content-description:resent-date:resent-from: | |
155 | resent-sender:resent-to:resent-cc:resent-message-id: | |
156 | in-reply-to:references: | |
157 | list-id:list-help:list-unsubscribe: | |
158 | list-subscribe:list-post:list-owner:list-archive | |
b80649a9 TK |
159 | |
160 | ||
161 | ||
7bafa7d9 TK |
162 | |
163 | 1. Yahoo DomainKeys support | |
164 | -------------------------------------------------------------- | |
165 | ||
166 | DomainKeys (DK) support is built into Exim using the | |
167 | "libdomainkeys" reference library implementation. It is | |
168 | available at | |
169 | ||
170 | http://domainkeys.sf.net | |
171 | ||
172 | You must build this library on your system and compile Exim | |
173 | against it. To build Exim with DK support, add these lines to | |
174 | your Local/Makefile: | |
175 | ||
176 | EXPERIMENTAL_DOMAINKEYS=yes | |
177 | CFLAGS += -I/home/tom/exim-cvs/extra/libdomainkeys | |
178 | LDFLAGS += -ldomainkeys -L/home/tom/exim-cvs/extra/libdomainkeys | |
179 | ||
180 | Remember to tweak the CFLAGS and LDFLAGS lines to match the | |
181 | location of the libdomainkeys includes and lib on your system. | |
182 | ||
183 | The current experimental implementation supports two | |
184 | independent functions: | |
185 | ||
186 | o Validate incoming DK-signed email. | |
187 | o Sign outgoing email with DK. | |
188 | ||
189 | The former is implemented in the ACLs for SMTP, the latter as | |
190 | an extension to the SMTP transport. That means both facilities | |
191 | are limited to SMTP I/O. | |
192 | ||
193 | ||
194 | ||
195 | 1) Validate incoming email | |
196 | ||
197 | Incoming messages are fed to the DK validation process as they | |
198 | are received "on the wire". This happens synchronously to | |
8ff3788c | 199 | Exim's buffering of the message in the spool. |
7bafa7d9 TK |
200 | |
201 | You must set "control = dk_verify" in one of the ACLs | |
202 | preceding DATA (you will typically use acl_smtp_rcpt), at a | |
203 | point where non-local, non-relay, non-submission mail is | |
204 | processed. If that control flag is not set, the message will | |
205 | NOT be verified. | |
206 | ||
207 | Example: | |
208 | ||
209 | warn log_message = Feeding message to DK validator. | |
210 | control = dk_verify | |
211 | ||
212 | You can check for the outcome of the DK check in the ACL after | |
213 | data (acl_smtp_data), using a number of ACL conditions and/or | |
214 | expansion variables. | |
215 | ||
216 | ||
217 | ||
218 | 1.1.) DK ACL conditions | |
219 | ||
220 | dk_sender_domains = <domain list> | |
8ff3788c | 221 | |
7bafa7d9 TK |
222 | This condition takes a domainlist as argument and |
223 | succeeds if the domain that DK has been verifying for is | |
224 | found in the list. | |
225 | ||
226 | ||
227 | dk_senders = <address list> | |
8ff3788c | 228 | |
7bafa7d9 TK |
229 | This condition takes an addresslist as argument and |
230 | succeeds if the address that DK has been verifying for | |
231 | is found in the list. | |
232 | ||
233 | ||
234 | dk_sender_local_parts = <local part list> | |
8ff3788c | 235 | |
7bafa7d9 TK |
236 | This condition takes a local_part list as argument |
237 | and succeeds if the domain that DK has been | |
238 | verifying for is found in the list. | |
239 | ||
240 | ||
241 | dk_status = <colon separated list of keywords> | |
8ff3788c | 242 | |
7bafa7d9 TK |
243 | This condition takes a list of keywords as argument, and |
244 | succeeds if one of the listed keywords matches the outcome | |
245 | of the DK check. The available keywords are: | |
8ff3788c | 246 | |
7bafa7d9 TK |
247 | good DK check succeeded, mail is verified. |
248 | bad DK check failed. | |
249 | no signature Mail is not signed with DK. | |
250 | no key Public key missing in target domain DNS. | |
251 | bad format Public key available, but unuseable. | |
252 | non-participant Target domain states not to participate in DK. | |
253 | revoked The signing key has been revoked by the domain. | |
254 | ||
255 | ||
256 | dk_policy = <colon separated list of keywords> | |
8ff3788c | 257 | |
7bafa7d9 TK |
258 | This condition takes a list of keywords as argument, and |
259 | succeeds if one of the listed keywords matches the policy | |
260 | announced by the target domain. The available keywords | |
261 | are: | |
8ff3788c | 262 | |
7bafa7d9 TK |
263 | signsall The target domain signs all outgoing email. |
264 | testing The target domain is currently testing DK. | |
265 | ||
266 | ||
267 | dk_domain_source = <colon separated list of keywords> | |
8ff3788c | 268 | |
7bafa7d9 TK |
269 | This condition takes a list of keywords as argument, and |
270 | succeeds if one of the listed keywords matches the | |
271 | location where DK found the sender domain it verified for. | |
272 | The available keywords are: | |
8ff3788c | 273 | |
7bafa7d9 TK |
274 | from The domain came from the "From:" header. |
275 | sender The domain came from the "Sender:" header. | |
276 | none DK was unable to find the responsible domain. | |
277 | ||
278 | ||
279 | ||
280 | 1.2.) DK verification expansion variables | |
281 | ||
282 | $dk_sender_domain | |
8ff3788c | 283 | |
7bafa7d9 | 284 | Contains the domain that DK has verified for. |
8ff3788c TK |
285 | |
286 | ||
7bafa7d9 | 287 | $dk_sender |
8ff3788c | 288 | |
7bafa7d9 | 289 | Contains the address that DK has verified for. |
8ff3788c TK |
290 | |
291 | ||
7bafa7d9 | 292 | $dk_sender_local_part |
8ff3788c | 293 | |
7bafa7d9 | 294 | Contains the local part that DK has verified for. |
8ff3788c TK |
295 | |
296 | ||
7bafa7d9 | 297 | $dk_sender_source |
8ff3788c | 298 | |
7bafa7d9 | 299 | Contains the "source" of the above three variables, one of |
8ff3788c | 300 | |
7bafa7d9 TK |
301 | "from" The address came from the "From:" header. |
302 | "sender" The address came from the "Sender:" header. | |
8ff3788c | 303 | |
7bafa7d9 | 304 | When DK was unable to find a valid address, this variable |
8ff3788c | 305 | is "0". |
7bafa7d9 TK |
306 | |
307 | ||
308 | $dk_signsall | |
8ff3788c | 309 | |
7bafa7d9 TK |
310 | Is "1" if the target domain signs all outgoing email, |
311 | "0" otherwise. | |
8ff3788c TK |
312 | |
313 | ||
7bafa7d9 | 314 | $dk_testing |
8ff3788c | 315 | |
7bafa7d9 | 316 | Is "1" if the target domain is testing DK, "0" otherwise. |
8ff3788c TK |
317 | |
318 | ||
7bafa7d9 | 319 | $dk_is_signed |
8ff3788c | 320 | |
7bafa7d9 | 321 | Is "1" if the message is signed, "0" otherwise. |
8ff3788c TK |
322 | |
323 | ||
7bafa7d9 | 324 | $dk_status |
8ff3788c | 325 | |
7bafa7d9 TK |
326 | Contains the outcome of the DK check as a string, commonly |
327 | used to add a "DomainKey-Status:" header to messages. Will | |
328 | contain one of: | |
8ff3788c | 329 | |
7bafa7d9 TK |
330 | good DK check succeeded, mail is verified. |
331 | bad DK check failed. | |
332 | no signature Mail is not signed with DK. | |
333 | no key Public key missing in target domain DNS. | |
334 | bad format Public key available, but unuseable. | |
335 | non-participant Target domain states not to participate in DK. | |
336 | revoked The signing key has been revoked by the domain. | |
337 | ||
338 | ||
339 | $dk_result | |
8ff3788c | 340 | |
7bafa7d9 TK |
341 | Contains a human-readable result of the DK check, more |
342 | verbose than $dk_status. Useful for logging purposes. | |
8ff3788c | 343 | |
7bafa7d9 TK |
344 | |
345 | ||
346 | 2) Sign outgoing email with DK | |
347 | ||
3ec3e3bb | 348 | Outgoing messages are signed just before Exim puts them "on |
7bafa7d9 TK |
349 | the wire". The only thing that happens after DK signing is |
350 | eventual TLS encryption. | |
351 | ||
352 | Signing is implemented by setting private options on the SMTP | |
353 | transport. These options take (expandable) strings as | |
354 | arguments. The most important variable to use in these | |
355 | expansions is $dk_domain. It contains the domain that DK wants | |
356 | to sign for. | |
357 | ||
358 | ||
359 | dk_selector = <expanded string> [MANDATORY] | |
8ff3788c | 360 | |
7bafa7d9 TK |
361 | This sets the key selector string. You can use the |
362 | $dk_domain expansion variable to look up a matching | |
363 | selector. The result is put in the expansion variable | |
364 | $dk_selector which should be used in the dk_private_key | |
365 | option along with $dk_domain. | |
366 | ||
367 | ||
368 | dk_private_key = <expanded string> [MANDATORY] | |
8ff3788c | 369 | |
7bafa7d9 TK |
370 | This sets the private key to use. You SHOULD use the |
371 | $dk_domain and $dk_selector expansion variables to | |
372 | determine the private key to use. The result can either | |
8ff3788c | 373 | |
7bafa7d9 TK |
374 | o be a valid RSA private key in ASCII armor, including |
375 | line breaks. | |
376 | o start with a slash, in which case it is treated as | |
377 | a file that contains the private key. | |
378 | o be "0", "false" or the empty string, in which case | |
379 | the message will not be signed. This case will not | |
380 | result in an error, even if dk_strict is set. | |
8ff3788c | 381 | |
7bafa7d9 TK |
382 | |
383 | dk_canon = <expanded string> [OPTIONAL] | |
8ff3788c | 384 | |
7bafa7d9 TK |
385 | This option sets the canonicalization method used when |
386 | signing a message. The DK draft currently supports two | |
387 | methods: "simple" and "nofws". The option defaults to | |
388 | "simple" when unset. | |
389 | ||
390 | ||
391 | dk_strict = <expanded string> [OPTIONAL] | |
8ff3788c | 392 | |
7bafa7d9 TK |
393 | This option defines how Exim behaves when signing a |
394 | message that should be signed fails for some reason. When | |
395 | the expansion evaluates to either "1" or "true", Exim will | |
396 | defer. Otherwise Exim will send the message unsigned. You | |
397 | can and should use the $dk_domain and $dk_selector | |
398 | expansion variables here. | |
399 | ||
400 | ||
401 | dk_domain = <expanded string> [NOT RECOMMENDED] | |
8ff3788c | 402 | |
7bafa7d9 TK |
403 | This option overrides DKs autodetection of the signing |
404 | domain. You should only use this option if you know what | |
405 | you are doing. The result of the string expansion is also | |
406 | put in $dk_domain. | |
8ff3788c TK |
407 | |
408 | ||
7bafa7d9 TK |
409 | |
410 | ||
3ec3e3bb | 411 | 2. Brightmail AntiSpam (BMI) suppport |
ee161e8f PH |
412 | -------------------------------------------------------------- |
413 | ||
414 | Brightmail AntiSpam is a commercial package. Please see | |
415 | http://www.brightmail.com for more information on | |
416 | the product. For the sake of clarity, we'll refer to it as | |
417 | "BMI" from now on. | |
418 | ||
419 | ||
420 | 0) BMI concept and implementation overview | |
421 | ||
422 | In contrast to how spam-scanning with SpamAssassin is | |
423 | implemented in exiscan-acl, BMI is more suited for per | |
424 | -recipient scanning of messages. However, each messages is | |
425 | scanned only once, but multiple "verdicts" for multiple | |
426 | recipients can be returned from the BMI server. The exiscan | |
427 | implementation passes the message to the BMI server just | |
428 | before accepting it. It then adds the retrieved verdicts to | |
429 | the messages header file in the spool. These verdicts can then | |
430 | be queried in routers, where operation is per-recipient | |
431 | instead of per-message. To use BMI, you need to take the | |
432 | following steps: | |
433 | ||
434 | 1) Compile Exim with BMI support | |
3ec3e3bb | 435 | 2) Set up main BMI options (top section of Exim config file) |
ee161e8f PH |
436 | 3) Set up ACL control statement (ACL section of the config |
437 | file) | |
438 | 4) Set up your routers to use BMI verdicts (routers section | |
439 | of the config file). | |
440 | 5) (Optional) Set up per-recipient opt-in information. | |
441 | ||
8ff3788c | 442 | These four steps are explained in more details below. |
ee161e8f PH |
443 | |
444 | 1) Adding support for BMI at compile time | |
445 | ||
446 | To compile with BMI support, you need to link Exim against | |
447 | the Brighmail client SDK, consisting of a library | |
448 | (libbmiclient_single.so) and a header file (bmi_api.h). | |
449 | You'll also need to explicitly set a flag in the Makefile to | |
450 | include BMI support in the Exim binary. Both can be achieved | |
451 | with these lines in Local/Makefile: | |
452 | ||
453 | EXPERIMENTAL_BRIGHTMAIL=yes | |
47bbda99 | 454 | CFLAGS=-I/path/to/the/dir/with/the/includefile |
ee161e8f | 455 | EXTRALIBS_EXIM=-L/path/to/the/dir/with/the/library -lbmiclient_single |
8ff3788c | 456 | |
ee161e8f PH |
457 | If you use other CFLAGS or EXTRALIBS_EXIM settings then |
458 | merge the content of these lines with them. | |
459 | ||
7c0c8547 | 460 | Note for BMI6.x users: You'll also have to add -lxml2_single |
ee161e8f PH |
461 | to the EXTRALIBS_EXIM line. Users of 5.5x do not need to do |
462 | this. | |
8ff3788c | 463 | |
ee161e8f PH |
464 | You should also include the location of |
465 | libbmiclient_single.so in your dynamic linker configuration | |
466 | file (usually /etc/ld.so.conf) and run "ldconfig" | |
467 | afterwards, or else the produced Exim binary will not be | |
468 | able to find the library file. | |
469 | ||
470 | ||
3ec3e3bb | 471 | 2) Setting up BMI support in the Exim main configuration |
ee161e8f | 472 | |
3ec3e3bb | 473 | To enable BMI support in the main Exim configuration, you |
ee161e8f PH |
474 | should set the path to the main BMI configuration file with |
475 | the "bmi_config_file" option, like this: | |
8ff3788c | 476 | |
ee161e8f | 477 | bmi_config_file = /opt/brightmail/etc/brightmail.cfg |
8ff3788c | 478 | |
3ec3e3bb | 479 | This must go into section 1 of Exim's configuration file (You |
ee161e8f PH |
480 | can put it right on top). If you omit this option, it |
481 | defaults to /opt/brightmail/etc/brightmail.cfg. | |
482 | ||
483 | Note for BMI6.x users: This file is in XML format in V6.xx | |
484 | and its name is /opt/brightmail/etc/bmiconfig.xml. So BMI | |
485 | 6.x users MUST set the bmi_config_file option. | |
8ff3788c | 486 | |
ee161e8f PH |
487 | |
488 | 3) Set up ACL control statement | |
489 | ||
490 | To optimize performance, it makes sense only to process | |
491 | messages coming from remote, untrusted sources with the BMI | |
492 | server. To set up a messages for processing by the BMI | |
493 | server, you MUST set the "bmi_run" control statement in any | |
494 | ACL for an incoming message. You will typically do this in | |
495 | an "accept" block in the "acl_check_rcpt" ACL. You should | |
496 | use the "accept" block(s) that accept messages from remote | |
497 | servers for your own domain(s). Here is an example that uses | |
3ec3e3bb | 498 | the "accept" blocks from Exim's default configuration file: |
8ff3788c | 499 | |
ee161e8f PH |
500 | |
501 | accept domains = +local_domains | |
502 | endpass | |
503 | verify = recipient | |
504 | control = bmi_run | |
505 | ||
506 | accept domains = +relay_to_domains | |
507 | endpass | |
508 | verify = recipient | |
509 | control = bmi_run | |
8ff3788c | 510 | |
ee161e8f PH |
511 | If bmi_run is not set in any ACL during reception of the |
512 | message, it will NOT be passed to the BMI server. | |
513 | ||
514 | ||
515 | 4) Setting up routers to use BMI verdicts | |
516 | ||
517 | When a message has been run through the BMI server, one or | |
518 | more "verdicts" are present. Different recipients can have | |
519 | different verdicts. Each recipient is treated individually | |
520 | during routing, so you can query the verdicts by recipient | |
3ec3e3bb | 521 | at that stage. From Exim's view, a verdict can have the |
ee161e8f | 522 | following outcomes: |
8ff3788c | 523 | |
ee161e8f PH |
524 | o deliver the message normally |
525 | o deliver the message to an alternate location | |
526 | o do not deliver the message | |
8ff3788c | 527 | |
ee161e8f PH |
528 | To query the verdict for a recipient, the implementation |
529 | offers the following tools: | |
8ff3788c TK |
530 | |
531 | ||
ee161e8f PH |
532 | - Boolean router preconditions. These can be used in any |
533 | router. For a simple implementation of BMI, these may be | |
534 | all that you need. The following preconditions are | |
535 | available: | |
8ff3788c | 536 | |
ee161e8f | 537 | o bmi_deliver_default |
8ff3788c | 538 | |
ee161e8f PH |
539 | This precondition is TRUE if the verdict for the |
540 | recipient is to deliver the message normally. If the | |
541 | message has not been processed by the BMI server, this | |
542 | variable defaults to TRUE. | |
8ff3788c | 543 | |
ee161e8f | 544 | o bmi_deliver_alternate |
8ff3788c | 545 | |
ee161e8f PH |
546 | This precondition is TRUE if the verdict for the |
547 | recipient is to deliver the message to an alternate | |
548 | location. You can get the location string from the | |
549 | $bmi_alt_location expansion variable if you need it. See | |
550 | further below. If the message has not been processed by | |
551 | the BMI server, this variable defaults to FALSE. | |
8ff3788c | 552 | |
ee161e8f | 553 | o bmi_dont_deliver |
8ff3788c | 554 | |
ee161e8f PH |
555 | This precondition is TRUE if the verdict for the |
556 | recipient is NOT to deliver the message to the | |
557 | recipient. You will typically use this precondition in a | |
558 | top-level blackhole router, like this: | |
8ff3788c | 559 | |
ee161e8f PH |
560 | # don't deliver messages handled by the BMI server |
561 | bmi_blackhole: | |
562 | driver = redirect | |
563 | bmi_dont_deliver | |
564 | data = :blackhole: | |
8ff3788c | 565 | |
ee161e8f PH |
566 | This router should be on top of all others, so messages |
567 | that should not be delivered do not reach other routers | |
568 | at all. If the message has not been processed by | |
569 | the BMI server, this variable defaults to FALSE. | |
8ff3788c TK |
570 | |
571 | ||
ee161e8f PH |
572 | - A list router precondition to query if rules "fired" on |
573 | the message for the recipient. Its name is "bmi_rule". You | |
574 | use it by passing it a colon-separated list of rule | |
575 | numbers. You can use this condition to route messages that | |
576 | matched specific rules. Here is an example: | |
8ff3788c | 577 | |
ee161e8f PH |
578 | # special router for BMI rule #5, #8 and #11 |
579 | bmi_rule_redirect: | |
580 | driver = redirect | |
581 | bmi_rule = 5:8:11 | |
582 | data = postmaster@mydomain.com | |
8ff3788c TK |
583 | |
584 | ||
ee161e8f PH |
585 | - Expansion variables. Several expansion variables are set |
586 | during routing. You can use them in custom router | |
587 | conditions, for example. The following variables are | |
588 | available: | |
8ff3788c | 589 | |
ee161e8f | 590 | o $bmi_base64_verdict |
8ff3788c | 591 | |
ee161e8f PH |
592 | This variable will contain the BASE64 encoded verdict |
593 | for the recipient being routed. You can use it to add a | |
594 | header to messages for tracking purposes, for example: | |
8ff3788c | 595 | |
ee161e8f PH |
596 | localuser: |
597 | driver = accept | |
598 | check_local_user | |
599 | headers_add = X-Brightmail-Verdict: $bmi_base64_verdict | |
600 | transport = local_delivery | |
8ff3788c | 601 | |
ee161e8f PH |
602 | If there is no verdict available for the recipient being |
603 | routed, this variable contains the empty string. | |
8ff3788c | 604 | |
ee161e8f | 605 | o $bmi_base64_tracker_verdict |
8ff3788c | 606 | |
ee161e8f PH |
607 | This variable will contain a BASE64 encoded subset of |
608 | the verdict information concerning the "rules" that | |
609 | fired on the message. You can add this string to a | |
610 | header, commonly named "X-Brightmail-Tracker". Example: | |
8ff3788c | 611 | |
ee161e8f PH |
612 | localuser: |
613 | driver = accept | |
614 | check_local_user | |
615 | headers_add = X-Brightmail-Tracker: $bmi_base64_tracker_verdict | |
616 | transport = local_delivery | |
8ff3788c | 617 | |
ee161e8f PH |
618 | If there is no verdict available for the recipient being |
619 | routed, this variable contains the empty string. | |
8ff3788c | 620 | |
ee161e8f | 621 | o $bmi_alt_location |
8ff3788c | 622 | |
ee161e8f PH |
623 | If the verdict is to redirect the message to an |
624 | alternate location, this variable will contain the | |
625 | alternate location string returned by the BMI server. In | |
626 | its default configuration, this is a header-like string | |
627 | that can be added to the message with "headers_add". If | |
628 | there is no verdict available for the recipient being | |
629 | routed, or if the message is to be delivered normally, | |
630 | this variable contains the empty string. | |
8ff3788c | 631 | |
ee161e8f | 632 | o $bmi_deliver |
8ff3788c | 633 | |
ee161e8f PH |
634 | This is an additional integer variable that can be used |
635 | to query if the message should be delivered at all. You | |
636 | should use router preconditions instead if possible. | |
8ff3788c | 637 | |
ee161e8f PH |
638 | $bmi_deliver is '0': the message should NOT be delivered. |
639 | $bmi_deliver is '1': the message should be delivered. | |
8ff3788c TK |
640 | |
641 | ||
ee161e8f PH |
642 | IMPORTANT NOTE: Verdict inheritance. |
643 | The message is passed to the BMI server during message | |
644 | reception, using the target addresses from the RCPT TO: | |
645 | commands in the SMTP transaction. If recipients get expanded | |
646 | or re-written (for example by aliasing), the new address(es) | |
647 | inherit the verdict from the original address. This means | |
648 | that verdicts also apply to all "child" addresses generated | |
649 | from top-level addresses that were sent to the BMI server. | |
8ff3788c TK |
650 | |
651 | ||
ee161e8f PH |
652 | 5) Using per-recipient opt-in information (Optional) |
653 | ||
654 | The BMI server features multiple scanning "profiles" for | |
655 | individual recipients. These are usually stored in a LDAP | |
656 | server and are queried by the BMI server itself. However, | |
657 | you can also pass opt-in data for each recipient from the | |
658 | MTA to the BMI server. This is particularly useful if you | |
3ec3e3bb | 659 | already look up recipient data in Exim anyway (which can |
ee161e8f PH |
660 | also be stored in a SQL database or other source). This |
661 | implementation enables you to pass opt-in data to the BMI | |
662 | server in the RCPT ACL. This works by setting the | |
663 | 'bmi_optin' modifier in a block of that ACL. If should be | |
664 | set to a list of comma-separated strings that identify the | |
665 | features which the BMI server should use for that particular | |
666 | recipient. Ideally, you would use the 'bmi_optin' modifier | |
667 | in the same ACL block where you set the 'bmi_run' control | |
668 | flag. Here is an example that will pull opt-in data for each | |
669 | recipient from a flat file called | |
670 | '/etc/exim/bmi_optin_data'. | |
8ff3788c | 671 | |
ee161e8f | 672 | The file format: |
8ff3788c | 673 | |
ee161e8f PH |
674 | user1@mydomain.com: <OPTIN STRING1>:<OPTIN STRING2> |
675 | user2@thatdomain.com: <OPTIN STRING3> | |
8ff3788c TK |
676 | |
677 | ||
ee161e8f | 678 | The example: |
8ff3788c | 679 | |
ee161e8f PH |
680 | accept domains = +relay_to_domains |
681 | endpass | |
682 | verify = recipient | |
683 | bmi_optin = ${lookup{$local_part@$domain}lsearch{/etc/exim/bmi_optin_data}} | |
8ff3788c TK |
684 | control = bmi_run |
685 | ||
ee161e8f | 686 | Of course, you can also use any other lookup method that |
3ec3e3bb | 687 | Exim supports, including LDAP, Postgres, MySQL, Oracle etc., |
ee161e8f PH |
688 | as long as the result is a list of colon-separated opt-in |
689 | strings. | |
8ff3788c | 690 | |
ee161e8f PH |
691 | For a list of available opt-in strings, please contact your |
692 | Brightmail representative. | |
ee161e8f | 693 | |
8ff3788c TK |
694 | |
695 | ||
696 | ||
7bafa7d9 | 697 | 3. Sender Policy Framework (SPF) support |
ee161e8f PH |
698 | -------------------------------------------------------------- |
699 | ||
f413481d | 700 | To learn more about SPF, visit http://www.openspf.org. This |
ee161e8f PH |
701 | document does not explain the SPF fundamentals, you should |
702 | read and understand the implications of deploying SPF on your | |
703 | system before doing so. | |
704 | ||
8ff3788c | 705 | SPF support is added via the libspf2 library. Visit |
ee161e8f PH |
706 | |
707 | http://www.libspf2.org/ | |
8ff3788c | 708 | |
ee161e8f PH |
709 | to obtain a copy, then compile and install it. By default, |
710 | this will put headers in /usr/local/include and the static | |
711 | library in /usr/local/lib. | |
712 | ||
3ec3e3bb | 713 | To compile Exim with SPF support, set these additional flags in |
ee161e8f PH |
714 | Local/Makefile: |
715 | ||
716 | EXPERIMENTAL_SPF=yes | |
717 | CFLAGS=-DSPF -I/usr/local/include | |
718 | EXTRALIBS_EXIM=-L/usr/local/lib -lspf2 | |
719 | ||
720 | This assumes that the libspf2 files are installed in | |
721 | their default locations. | |
722 | ||
723 | You can now run SPF checks in incoming SMTP by using the "spf" | |
724 | ACL condition in either the MAIL, RCPT or DATA ACLs. When | |
725 | using it in the RCPT ACL, you can make the checks dependend on | |
726 | the RCPT address (or domain), so you can check SPF records | |
727 | only for certain target domains. This gives you the | |
728 | possibility to opt-out certain customers that do not want | |
729 | their mail to be subject to SPF checking. | |
730 | ||
731 | The spf condition takes a list of strings on its right-hand | |
732 | side. These strings describe the outcome of the SPF check for | |
733 | which the spf condition should succeed. Valid strings are: | |
734 | ||
735 | o pass The SPF check passed, the sending host | |
736 | is positively verified by SPF. | |
737 | o fail The SPF check failed, the sending host | |
738 | is NOT allowed to send mail for the domain | |
739 | in the envelope-from address. | |
740 | o softfail The SPF check failed, but the queried | |
741 | domain can't absolutely confirm that this | |
742 | is a forgery. | |
743 | o none The queried domain does not publish SPF | |
744 | records. | |
745 | o neutral The SPF check returned a "neutral" state. | |
746 | This means the queried domain has published | |
747 | a SPF record, but wants to allow outside | |
748 | servers to send mail under its domain as well. | |
749 | o err_perm This indicates a syntax error in the SPF | |
750 | record of the queried domain. This should be | |
751 | treated like "none". | |
752 | o err_temp This indicates a temporary error during all | |
3ec3e3bb | 753 | processing, including Exim's SPF processing. |
ee161e8f | 754 | You may defer messages when this occurs. |
8ff3788c | 755 | |
ee161e8f PH |
756 | You can prefix each string with an exclamation mark to invert |
757 | is meaning, for example "!fail" will match all results but | |
758 | "fail". The string list is evaluated left-to-right, in a | |
759 | short-circuit fashion. When a string matches the outcome of | |
760 | the SPF check, the condition succeeds. If none of the listed | |
761 | strings matches the outcome of the SPF check, the condition | |
762 | fails. | |
763 | ||
f413481d TK |
764 | Here is an example to fail forgery attempts from domains that |
765 | publish SPF records: | |
ee161e8f PH |
766 | |
767 | /* ----------------- | |
f413481d TK |
768 | deny message = $sender_host_address is not allowed to send mail from ${if def:sender_address_domain {$sender_address_domain}{$sender_helo_name}}. \ |
769 | 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 | |
ee161e8f PH |
770 | spf = fail |
771 | --------------------- */ | |
772 | ||
773 | You can also give special treatment to specific domains: | |
774 | ||
775 | /* ----------------- | |
776 | deny message = AOL sender, but not from AOL-approved relay. | |
777 | sender_domains = aol.com | |
778 | spf = fail:neutral | |
779 | --------------------- */ | |
780 | ||
781 | Explanation: AOL publishes SPF records, but is liberal and | |
782 | still allows non-approved relays to send mail from aol.com. | |
783 | This will result in a "neutral" state, while mail from genuine | |
784 | AOL servers will result in "pass". The example above takes | |
785 | this into account and treats "neutral" like "fail", but only | |
786 | for aol.com. Please note that this violates the SPF draft. | |
787 | ||
788 | When the spf condition has run, it sets up several expansion | |
789 | variables. | |
790 | ||
791 | $spf_header_comment | |
792 | This contains a human-readable string describing the outcome | |
793 | of the SPF check. You can add it to a custom header or use | |
794 | it for logging purposes. | |
8ff3788c | 795 | |
ee161e8f | 796 | $spf_received |
8fe685ad | 797 | This contains a complete Received-SPF: header that can be |
ee161e8f PH |
798 | added to the message. Please note that according to the SPF |
799 | draft, this header must be added at the top of the header | |
800 | list. Please see section 10 on how you can do this. | |
8ff3788c | 801 | |
65a7d8c3 NM |
802 | Note: in case of "Best-guess" (see below), the convention is |
803 | to put this string in a header called X-SPF-Guess: instead. | |
804 | ||
ee161e8f PH |
805 | $spf_result |
806 | This contains the outcome of the SPF check in string form, | |
807 | one of pass, fail, softfail, none, neutral, err_perm or | |
808 | err_temp. | |
8ff3788c | 809 | |
ee161e8f PH |
810 | $spf_smtp_comment |
811 | This contains a string that can be used in a SMTP response | |
812 | to the calling party. Useful for "fail". | |
8ff3788c | 813 | |
65a7d8c3 NM |
814 | In addition to SPF, you can also perform checks for so-called |
815 | "Best-guess". Strictly speaking, "Best-guess" is not standard | |
816 | SPF, but it is supported by the same framework that enables SPF | |
817 | capability. Refer to http://www.openspf.org/FAQ/Best_guess_record | |
818 | for a description of what it means. | |
819 | ||
820 | To access this feature, simply use the spf_guess condition in place | |
821 | of the spf one. For example: | |
822 | ||
823 | /* ----------------- | |
824 | deny message = $sender_host_address doesn't look trustworthy to me | |
825 | spf_guess = fail | |
826 | --------------------- */ | |
827 | ||
828 | In case you decide to reject messages based on this check, you | |
829 | should note that although it uses the same framework, "Best-guess" | |
830 | is NOT SPF, and therefore you should not mention SPF at all in your | |
831 | reject message. | |
832 | ||
833 | When the spf_guess condition has run, it sets up the same expansion | |
834 | variables as when spf condition is run, described above. | |
835 | ||
836 | Additionally, since Best-guess is not standarized, you may redefine | |
837 | what "Best-guess" means to you by redefining spf_guess variable in | |
838 | global config. For example, the following: | |
839 | ||
840 | /* ----------------- | |
841 | spf_guess = v=spf1 a/16 mx/16 ptr ?all | |
842 | --------------------- */ | |
843 | ||
844 | would relax host matching rules to a broader network range. | |
8ff3788c | 845 | |
ee161e8f | 846 | |
7bafa7d9 | 847 | 4. SRS (Sender Rewriting Scheme) Support |
ee161e8f PH |
848 | -------------------------------------------------------------- |
849 | ||
850 | Exiscan currently includes SRS support via Miles Wilton's | |
8ff3788c | 851 | libsrs_alt library. The current version of the supported |
ee161e8f PH |
852 | library is 0.5. |
853 | ||
854 | In order to use SRS, you must get a copy of libsrs_alt from | |
855 | ||
856 | http://srs.mirtol.com/ | |
857 | ||
858 | Unpack the tarball, then refer to MTAs/README.EXIM | |
859 | to proceed. You need to set | |
860 | ||
861 | EXPERIMENTAL_SRS=yes | |
862 | ||
863 | in your Local/Makefile. | |
864 | ||
865 | ||
866 | -------------------------------------------------------------- | |
867 | End of file | |
868 | -------------------------------------------------------------- |