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