| 1 | |
| 2 | ### acl/30_exim4-config_check_rcpt |
| 3 | ################################# |
| 4 | |
| 5 | # This access control list is used for every RCPT command in an incoming |
| 6 | # SMTP message. The tests are run in order until the address is either |
| 7 | # accepted or denied. |
| 8 | # |
| 9 | acl_check_rcpt: |
| 10 | |
| 11 | # Accept if the source is local SMTP (i.e. not over TCP/IP). We do this by |
| 12 | # testing for an empty sending host field. |
| 13 | accept |
| 14 | hosts = : |
| 15 | |
| 16 | |
| 17 | # The following section of the ACL is concerned with local parts that contain |
| 18 | # certain non-alphanumeric characters. Dots in unusual places are |
| 19 | # handled by this ACL as well. |
| 20 | # |
| 21 | # Non-alphanumeric characters other than dots are rarely found in genuine |
| 22 | # local parts, but are often tried by people looking to circumvent |
| 23 | # relaying restrictions. Therefore, although they are valid in local |
| 24 | # parts, these rules disallow certain non-alphanumeric characters, as |
| 25 | # a precaution. |
| 26 | # |
| 27 | # Empty components (two dots in a row) are not valid in RFC 2822, but Exim |
| 28 | # allows them because they have been encountered. (Consider local parts |
| 29 | # constructed as "firstinitial.secondinitial.familyname" when applied to |
| 30 | # a name without a second initial.) However, a local part starting |
| 31 | # with a dot or containing /../ can cause trouble if it is used as part of a |
| 32 | # file name (e.g. for a mailing list). This is also true for local parts that |
| 33 | # contain slashes. A pipe symbol can also be troublesome if the local part is |
| 34 | # incorporated unthinkingly into a shell command line. |
| 35 | # |
| 36 | # These ACL components will block recipient addresses that are valid |
| 37 | # from an RFC2822 point of view. We chose to have them blocked by |
| 38 | # default for security reasons. |
| 39 | # |
| 40 | # If you feel that your site should have less strict recipient |
| 41 | # checking, please feel free to change the default values of the macros |
| 42 | # defined in main/01_exim4-config_listmacrosdefs or override them from a |
| 43 | # local configuration file. |
| 44 | # |
| 45 | # Two different rules are used. The first one has a quite strict |
| 46 | # default, and is applied to messages that are addressed to one of the |
| 47 | # local domains handled by this host. |
| 48 | |
| 49 | # The default value of CHECK_RCPT_LOCAL_LOCALPARTS is defined in |
| 50 | # main/01_exim4-config_listmacrosdefs: |
| 51 | # CHECK_RCPT_LOCAL_LOCALPARTS = ^[.] : ^.*[@%!/|`#&?] |
| 52 | # This blocks local parts that begin with a dot or contain a quite |
| 53 | # broad range of non-alphanumeric characters. |
| 54 | .ifdef CHECK_RCPT_LOCAL_LOCALPARTS |
| 55 | deny |
| 56 | domains = +local_domains : +unix_domains |
| 57 | local_parts = CHECK_RCPT_LOCAL_LOCALPARTS |
| 58 | message = restricted characters in address |
| 59 | .endif |
| 60 | |
| 61 | |
| 62 | # The second rule applies to all other domains, and its default is |
| 63 | # considerably less strict. |
| 64 | |
| 65 | # The default value of CHECK_RCPT_REMOTE_LOCALPARTS is defined in |
| 66 | # main/01_exim4-config_listmacrosdefs: |
| 67 | # CHECK_RCPT_REMOTE_LOCALPARTS = ^[./|] : ^.*[@%!`#&?] : ^.*/\\.\\./ |
| 68 | |
| 69 | # It allows local users to send outgoing messages to sites |
| 70 | # that use slashes and vertical bars in their local parts. It blocks |
| 71 | # local parts that begin with a dot, slash, or vertical bar, but allows |
| 72 | # these characters within the local part. However, the sequence /../ is |
| 73 | # barred. The use of some other non-alphanumeric characters is blocked. |
| 74 | # Single quotes might probably be dangerous as well, but they're |
| 75 | # allowed by the default regexps to avoid rejecting mails to Ireland. |
| 76 | # The motivation here is to prevent local users (or local users' malware) |
| 77 | # from mounting certain kinds of attack on remote sites. |
| 78 | .ifdef CHECK_RCPT_REMOTE_LOCALPARTS |
| 79 | deny |
| 80 | domains = !+local_domains : !+unix_domains |
| 81 | local_parts = CHECK_RCPT_REMOTE_LOCALPARTS |
| 82 | message = restricted characters in address |
| 83 | .endif |
| 84 | |
| 85 | |
| 86 | # Accept mail to postmaster in any local domain, regardless of the source, |
| 87 | # and without verifying the sender. |
| 88 | # |
| 89 | accept |
| 90 | .ifndef CHECK_RCPT_POSTMASTER |
| 91 | local_parts = postmaster |
| 92 | .else |
| 93 | local_parts = CHECK_RCPT_POSTMASTER |
| 94 | .endif |
| 95 | domains = +local_domains : +unix_domains : +relay_to_domains |
| 96 | |
| 97 | |
| 98 | # Deny unless the sender address can be verified. |
| 99 | # |
| 100 | # This is disabled by default so that DNSless systems don't break. If |
| 101 | # your system can do DNS lookups without delay or cost, you might want |
| 102 | # to enable this feature. |
| 103 | # |
| 104 | # This feature does not work in smarthost and satellite setups as |
| 105 | # with these setups all domains pass verification. See spec.txt chapter |
| 106 | # 39.31 with the added information that a smarthost/satellite setup |
| 107 | # routes all non-local e-mail to the smarthost. |
| 108 | .ifdef CHECK_RCPT_VERIFY_SENDER |
| 109 | deny |
| 110 | message = Sender verification failed |
| 111 | !acl = acl_local_deny_exceptions |
| 112 | !verify = sender |
| 113 | .endif |
| 114 | |
| 115 | # hcoop-change: Add recommended lines from |
| 116 | # /usr/share/doc/mailman/README.EXIM.gz so that bounce messages |
| 117 | # get through, even if they are from a malformed address |
| 118 | |
| 119 | # Accept bounces to lists even if callbacks or other checks would fail |
| 120 | warn |
| 121 | message = X-WhitelistedRCPT-nohdrfromcallback: Yes |
| 122 | condition = ${if and {{match{$local_part}{(.*)-bounces\+.*}} \ |
| 123 | {def:domain} \ |
| 124 | {eq {${lookup{$local_part@$domain}lsearch{MAILMAN_DB}}} \ |
| 125 | {true}}} \ |
| 126 | {yes}{no}} |
| 127 | |
| 128 | accept |
| 129 | condition = ${if and {{match{$local_part}{(.*)-bounces\+.*}} \ |
| 130 | {def:domain} \ |
| 131 | {eq {${lookup{$local_part@$domain}lsearch{MAILMAN_DB}}} \ |
| 132 | {true}}} \ |
| 133 | {yes}{no}} |
| 134 | |
| 135 | # Verify senders listed in local_sender_callout with a callout. |
| 136 | # |
| 137 | # In smarthost and satellite setups, this causes the callout to be |
| 138 | # done to the smarthost. Verification will thus only be reliable if the |
| 139 | # smarthost does reject illegal addresses in the SMTP dialog. |
| 140 | deny |
| 141 | !acl = acl_local_deny_exceptions |
| 142 | senders = ${if exists{CONFDIR/local_sender_callout}\ |
| 143 | {CONFDIR/local_sender_callout}\ |
| 144 | {}} |
| 145 | !verify = sender/callout |
| 146 | |
| 147 | |
| 148 | # Accept if the message comes from one of the hosts for which we are an |
| 149 | # outgoing relay. It is assumed that such hosts are most likely to be MUAs, |
| 150 | # so we set control=submission to make Exim treat the message as a |
| 151 | # submission. It will fix up various errors in the message, for example, the |
| 152 | # lack of a Date: header line. If you are actually relaying out out from |
| 153 | # MTAs, you may want to disable this. If you are handling both relaying from |
| 154 | # MTAs and submissions from MUAs you should probably split them into two |
| 155 | # lists, and handle them differently. |
| 156 | |
| 157 | # Recipient verification is omitted here, because in many cases the clients |
| 158 | # are dumb MUAs that don't cope well with SMTP error responses. If you are |
| 159 | # actually relaying out from MTAs, you should probably add recipient |
| 160 | # verification here. |
| 161 | |
| 162 | # Note that, by putting this test before any DNS black list checks, you will |
| 163 | # always accept from these hosts, even if they end up on a black list. The |
| 164 | # assumption is that they are your friends, and if they get onto black |
| 165 | # list, it is a mistake. |
| 166 | accept |
| 167 | hosts = +relay_from_hosts |
| 168 | control = submission/sender_retain |
| 169 | |
| 170 | |
| 171 | # Accept if the message arrived over an authenticated connection, from |
| 172 | # any host. Again, these messages are usually from MUAs, so recipient |
| 173 | # verification is omitted, and submission mode is set. And again, we do this |
| 174 | # check before any black list tests. |
| 175 | accept |
| 176 | authenticated = * |
| 177 | control = submission/sender_retain |
| 178 | |
| 179 | |
| 180 | # Insist that any other recipient address that we accept is either in one of |
| 181 | # our local domains, or is in a domain for which we explicitly allow |
| 182 | # relaying. Any other domain is rejected as being unacceptable for relaying. |
| 183 | require |
| 184 | message = relay not permitted |
| 185 | domains = +local_domains : +unix_domains : +relay_to_domains |
| 186 | |
| 187 | |
| 188 | # We also require all accepted addresses to be verifiable. This check will |
| 189 | # do local part verification for local domains, but only check the domain |
| 190 | # for remote domains. |
| 191 | require |
| 192 | verify = recipient |
| 193 | |
| 194 | |
| 195 | # Verify recipients listed in local_rcpt_callout with a callout. |
| 196 | # This is especially handy for forwarding MX hosts (secondary MX or |
| 197 | # mail hubs) of domains that receive a lot of spam to non-existent |
| 198 | # addresses. The only way to check local parts for remote relay |
| 199 | # domains is to use a callout (add /callout), but please read the |
| 200 | # documentation about callouts before doing this. |
| 201 | deny |
| 202 | !acl = acl_local_deny_exceptions |
| 203 | recipients = ${if exists{CONFDIR/local_rcpt_callout}\ |
| 204 | {CONFDIR/local_rcpt_callout}\ |
| 205 | {}} |
| 206 | !verify = recipient/callout |
| 207 | |
| 208 | |
| 209 | # CONFDIR/local_sender_blacklist holds a list of envelope senders that |
| 210 | # should have their access denied to the local host. Incoming messages |
| 211 | # with one of these senders are rejected at RCPT time. |
| 212 | # |
| 213 | # The explicit white lists are honored as well as negative items in |
| 214 | # the black list. See exim4-config_files(5) for details. |
| 215 | deny |
| 216 | message = sender envelope address $sender_address is locally blacklisted here. If you think this is wrong, get in touch with postmaster |
| 217 | !acl = acl_local_deny_exceptions |
| 218 | senders = ${if exists{CONFDIR/local_sender_blacklist}\ |
| 219 | {CONFDIR/local_sender_blacklist}\ |
| 220 | {}} |
| 221 | |
| 222 | |
| 223 | # deny bad sites (IP address) |
| 224 | # CONFDIR/local_host_blacklist holds a list of host names, IP addresses |
| 225 | # and networks (CIDR notation) that should have their access denied to |
| 226 | # The local host. Messages coming in from a listed host will have all |
| 227 | # RCPT statements rejected. |
| 228 | # |
| 229 | # The explicit white lists are honored as well as negative items in |
| 230 | # the black list. See exim4-config_files(5) for details. |
| 231 | deny |
| 232 | message = sender IP address $sender_host_address is locally blacklisted here. If you think this is wrong, get in touch with postmaster |
| 233 | !acl = acl_local_deny_exceptions |
| 234 | hosts = ${if exists{CONFDIR/local_host_blacklist}\ |
| 235 | {CONFDIR/local_host_blacklist}\ |
| 236 | {}} |
| 237 | |
| 238 | |
| 239 | # Warn if the sender host does not have valid reverse DNS. |
| 240 | # |
| 241 | # If your system can do DNS lookups without delay or cost, you might want |
| 242 | # to enable this. |
| 243 | # If sender_host_address is defined, it's a remote call. If |
| 244 | # sender_host_name is not defined, then reverse lookup failed. Use |
| 245 | # this instead of !verify = reverse_host_lookup to catch deferrals |
| 246 | # as well as outright failures. |
| 247 | .ifdef CHECK_RCPT_REVERSE_DNS |
| 248 | warn |
| 249 | message = X-Host-Lookup-Failed: Reverse DNS lookup failed for $sender_host_address (${if eq{$host_lookup_failed}{1}{failed}{deferred}}) |
| 250 | condition = ${if and{{def:sender_host_address}{!def:sender_host_name}}\ |
| 251 | {yes}{no}} |
| 252 | .endif |
| 253 | |
| 254 | |
| 255 | # Use spfquery to perform a pair of SPF checks (for details, see |
| 256 | # http://www.openspf.org/) |
| 257 | # |
| 258 | # This is quite costly in terms of DNS lookups (~6 lookups per mail). Do not |
| 259 | # enable if that's an issue. Also note that if you enable this, you must |
| 260 | # install "libmail-spf-query-perl" which provides the spfquery command. |
| 261 | # Missing libmail-spf-query-perl will trigger the "Unexpected error in |
| 262 | # SPF check" warning. |
| 263 | .ifdef CHECK_RCPT_SPF |
| 264 | deny |
| 265 | message = [SPF] $sender_host_address is not allowed to send mail from ${if def:sender_address_domain {$sender_address_domain}{$sender_helo_name}}. \ |
| 266 | 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 |
| 267 | log_message = SPF check failed. |
| 268 | !acl = acl_local_deny_exceptions |
| 269 | condition = ${run{/usr/bin/spfquery --ip \"$sender_host_address\" --mail-from \"$sender_address\" --helo \"$sender_helo_name\"}\ |
| 270 | {no}{${if eq {$runrc}{1}{yes}{no}}}} |
| 271 | |
| 272 | defer |
| 273 | message = Temporary DNS error while checking SPF record. Try again later. |
| 274 | condition = ${if eq {$runrc}{5}{yes}{no}} |
| 275 | |
| 276 | warn |
| 277 | message = Received-SPF: ${if eq {$runrc}{0}{pass}{${if eq {$runrc}{2}{softfail}\ |
| 278 | {${if eq {$runrc}{3}{neutral}{${if eq {$runrc}{4}{unknown}{${if eq {$runrc}{6}{none}{error}}}}}}}}}} |
| 279 | condition = ${if <={$runrc}{6}{yes}{no}} |
| 280 | |
| 281 | warn |
| 282 | log_message = Unexpected error in SPF check. |
| 283 | condition = ${if >{$runrc}{6}{yes}{no}} |
| 284 | |
| 285 | # Support for best-guess (see http://www.openspf.org/developers-guide.html) |
| 286 | warn |
| 287 | message = X-SPF-Guess: ${run{/usr/bin/spfquery --ip \"$sender_host_address\" --mail-from \"$sender_address\" \ --helo \"$sender_helo_name\" --guess true}\ |
| 288 | {pass}{${if eq {$runrc}{2}{softfail}{${if eq {$runrc}{3}{neutral}{${if eq {$runrc}{4}{unknown}\ |
| 289 | {${if eq {$runrc}{6}{none}{error}}}}}}}}}} |
| 290 | condition = ${if <={$runrc}{6}{yes}{no}} |
| 291 | |
| 292 | defer |
| 293 | message = Temporary DNS error while checking SPF record. Try again later. |
| 294 | condition = ${if eq {$runrc}{5}{yes}{no}} |
| 295 | .endif |
| 296 | |
| 297 | |
| 298 | # Check against classic DNS "black" lists (DNSBLs) which list |
| 299 | # sender IP addresses |
| 300 | .ifdef CHECK_RCPT_IP_DNSBLS |
| 301 | warn |
| 302 | message = X-Warning: $sender_host_address is listed at $dnslist_domain ($dnslist_value: $dnslist_text) |
| 303 | log_message = $sender_host_address is listed at $dnslist_domain ($dnslist_value: $dnslist_text) |
| 304 | dnslists = CHECK_RCPT_IP_DNSBLS |
| 305 | .endif |
| 306 | |
| 307 | |
| 308 | # Check against DNSBLs which list sender domains, with an option to locally |
| 309 | # whitelist certain domains that might be blacklisted. |
| 310 | # |
| 311 | # Note: If you define CHECK_RCPT_DOMAIN_DNSBLS, you must append |
| 312 | # "/$sender_address_domain" after each domain. For example: |
| 313 | # CHECK_RCPT_DOMAIN_DNSBLS = rhsbl.foo.org/$sender_address_domain \ |
| 314 | # : rhsbl.bar.org/$sender_address_domain |
| 315 | .ifdef CHECK_RCPT_DOMAIN_DNSBLS |
| 316 | warn |
| 317 | message = X-Warning: $sender_address_domain is listed at $dnslist_domain ($dnslist_value: $dnslist_text) |
| 318 | log_message = $sender_address_domain is listed at $dnslist_domain ($dnslist_value: $dnslist_text) |
| 319 | !senders = ${if exists{CONFDIR/local_domain_dnsbl_whitelist}\ |
| 320 | {CONFDIR/local_domain_dnsbl_whitelist}\ |
| 321 | {}} |
| 322 | dnslists = CHECK_RCPT_DOMAIN_DNSBLS |
| 323 | .endif |
| 324 | |
| 325 | |
| 326 | # This hook allows you to hook in your own ACLs without having to |
| 327 | # modify this file. If you do it like we suggest, you'll end up with |
| 328 | # a small performance penalty since there is an additional file being |
| 329 | # accessed. This doesn't happen if you leave the macro unset. |
| 330 | .ifdef CHECK_RCPT_LOCAL_ACL_FILE |
| 331 | .include CHECK_RCPT_LOCAL_ACL_FILE |
| 332 | .endif |
| 333 | |
| 334 | |
| 335 | ############################################################################# |
| 336 | # This check is commented out because it is recognized that not every |
| 337 | # sysadmin will want to do it. If you enable it, the check performs |
| 338 | # Client SMTP Authorization (csa) checks on the sending host. These checks |
| 339 | # do DNS lookups for SRV records. The CSA proposal is currently (May 2005) |
| 340 | # an Internet draft. You can, of course, add additional conditions to this |
| 341 | # ACL statement to restrict the CSA checks to certain hosts only. |
| 342 | # |
| 343 | # require verify = csa |
| 344 | ############################################################################# |
| 345 | |
| 346 | |
| 347 | # Accept if the address is in a domain for which we are an incoming relay, |
| 348 | # but again, only if the recipient can be verified. |
| 349 | |
| 350 | accept |
| 351 | domains = +relay_to_domains |
| 352 | endpass |
| 353 | verify = recipient |
| 354 | |
| 355 | |
| 356 | # At this point, the address has passed all the checks that have been |
| 357 | # configured, so we accept it unconditionally. |
| 358 | |
| 359 | accept |