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