| 1 | From: Nathan Ollerenshaw <nathan@valuecommerce.co.jp> |
| 2 | |
| 3 | ## I've been working quite hard to come up with a config that reasonably |
| 4 | ## matches the qmail-ldap setup, without the warts. I want to submit it |
| 5 | ## for inclusion in your config.samples archive, in case anyone else needs |
| 6 | ## to do the same as I. I hope its useful. |
| 7 | ## |
| 8 | ## A few notes; it supports catchalls but not dash extension addressing, |
| 9 | ## as I couldn't be bothered, and I'm unsure as to how many people |
| 10 | ## actually use the feature. Certainly nobody on my system. It supports |
| 11 | ## autoreplies, but not an autoreply on a catchall, because this just |
| 12 | ## kills your mailserver when someone does a dictionary spam attack |
| 13 | ## against a domain set up this way. |
| 14 | |
| 15 | |
| 16 | ###################################################################### |
| 17 | # Runtime configuration file for Exim # |
| 18 | ###################################################################### |
| 19 | |
| 20 | #domainlist local_domains = @ : lsearch:/apps/conf/mail/locals |
| 21 | domainlist local_domains = lsearch;/apps/conf/mail/locals |
| 22 | domainlist relay_to_domains = |
| 23 | |
| 24 | # the pop-before-smtp package at http://popbsmtp.sourceforge.net/ |
| 25 | # creates the /etc/mail/popauth.db file for us. We have to use dbmnz |
| 26 | # lookup type here. |
| 27 | |
| 28 | hostlist relay_from_hosts = 127.0.0.1 : net-dbmnz;/etc/mail/popauth.db |
| 29 | primary_hostname = [[[SET THIS TO LOCAL HOST NAME]]] |
| 30 | |
| 31 | # LDAP settings |
| 32 | |
| 33 | # Set the following to your ldap server(s) |
| 34 | ldap_default_servers = ldap::389 |
| 35 | BASEDN = [[[SET THIS TO YOUR BASE DN IN LDAP]]] |
| 36 | |
| 37 | acl_smtp_rcpt = acl_check_rcpt |
| 38 | acl_smtp_data = acl_check_data |
| 39 | |
| 40 | exim_user = vmail |
| 41 | exim_group = vmail |
| 42 | trusted_users = vmail |
| 43 | never_users = root |
| 44 | host_lookup = * |
| 45 | rfc1413_hosts = * |
| 46 | rfc1413_query_timeout = 0s |
| 47 | ignore_bounce_errors_after = 2d |
| 48 | timeout_frozen_after = 7d |
| 49 | bounce_return_body = false |
| 50 | accept_8bitmime = true |
| 51 | allow_mx_to_ip = true |
| 52 | auto_thaw = 60m |
| 53 | smtp_accept_max = 0 |
| 54 | smtp_load_reserve = 20 |
| 55 | delay_warning = 4h:8h:24h |
| 56 | dns_again_means_nonexist = !+local_domains : !+relay_to_domains |
| 57 | |
| 58 | spamd_address = 127.0.0.1 783 |
| 59 | av_scanner = clamd:127.0.0.1 3310 |
| 60 | |
| 61 | # Spool settings |
| 62 | |
| 63 | split_spool_directory = true |
| 64 | check_spool_space = 100M |
| 65 | check_spool_inodes = 1000 |
| 66 | |
| 67 | # Logging - enable a bunch of extra useful stuff. Never know, could help |
| 68 | # one day, and at least its better than qmail! Har har! |
| 69 | |
| 70 | log_selector = +delivery_size +received_sender +received_recipients \ |
| 71 | +subject +sender_on_delivery |
| 72 | |
| 73 | # NOTE TO SELF: Lets use syslog and have all six mail servers log to a |
| 74 | # central location so its easier to do statistics gathering and fault |
| 75 | # analysis. |
| 76 | |
| 77 | # MACROS |
| 78 | |
| 79 | # Secret for all machines in the cluster. Change it to whatever you feel |
| 80 | # is best. |
| 81 | |
| 82 | SECRET = Ni2opNyw2pNM3cmWn21nOSbwdq |
| 83 | |
| 84 | GET_ADDRESS_DATA = ${lookup ldap {\ |
| 85 | ldap:///BASEDN??sub?(&(uid=${quote_ldap:$local_part}@${quote_ldap:$domain}))\ |
| 86 | }\ |
| 87 | } |
| 88 | |
| 89 | GET_CATCHALL_DATA = ${lookup ldap {\ |
| 90 | ldap:///BASEDN??sub?(&(uid=catchall@${quote_ldap:$domain}))\ |
| 91 | }\ |
| 92 | } |
| 93 | |
| 94 | MSGCOOKIE = ${hmac{md5}{SECRET}{$body_linecount}} |
| 95 | |
| 96 | ###################################################################### |
| 97 | # ROUTERS CONFIGURATION # |
| 98 | # Specifies how addresses are handled # |
| 99 | ###################################################################### |
| 100 | |
| 101 | begin routers |
| 102 | |
| 103 | dnslookup: |
| 104 | driver = dnslookup |
| 105 | domains = ! +local_domains |
| 106 | transport = remote_smtp |
| 107 | ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 |
| 108 | no_more |
| 109 | |
| 110 | system_aliases: |
| 111 | driver = redirect |
| 112 | condition = ${if eq {{$primary_hostname}{$domain} {1}{0}} } |
| 113 | allow_fail |
| 114 | allow_defer |
| 115 | data = ${lookup{$local_part}lsearch{/etc/aliases}} |
| 116 | file_transport = address_file |
| 117 | pipe_transport = address_pipe |
| 118 | |
| 119 | # the forward router does the initial LDAP lookup. It then caches this in |
| 120 | # $address_data for use by any of the other routers. Each router will fall |
| 121 | # through if they then don't meet their condition. |
| 122 | |
| 123 | lookup: |
| 124 | driver = redirect |
| 125 | address_data = GET_ADDRESS_DATA |
| 126 | # data is intentionally left blank so that the router will decline |
| 127 | # we just want this router to do a lookup so the results are availble |
| 128 | # for the other routers. |
| 129 | data = |
| 130 | |
| 131 | # OK, this is where we start supporting crazy qmail-ldap stuff. First, we |
| 132 | # check if the address has a deliveryMode of 'forwardonly'. forwardonly is |
| 133 | # a misnomer, because its possible for and address to be a forward, a mailbox |
| 134 | # and an autoreply. So, we make it do the forward, and check to see if it is |
| 135 | # also a reply or localdelivery, if so we set unseen to yes to make Exim |
| 136 | # copy the message and send it to the next router. |
| 137 | |
| 138 | forward: |
| 139 | driver = redirect |
| 140 | condition = ${if match {${extract{deliveryMode}{$address_data}}}{forwardonly} {1}{0}} |
| 141 | data = ${extract{mailForwardingAddress}{$address_data}} |
| 142 | unseen = ${if or {{match {${extract{deliveryMode}{$address_data}}}{reply}} \ |
| 143 | {match {${extract{deliveryMode}{$address_data}}}{localdelivery}}} \ |
| 144 | {yes}{no}} |
| 145 | |
| 146 | # Same deal, check if its a reply, if so we send it to the correct transport. |
| 147 | # After, we see if it needs to go to localdelivery as well. |
| 148 | |
| 149 | reply: |
| 150 | driver = accept |
| 151 | condition = ${if match {${extract{deliveryMode}{$address_data}}}{reply} {1}{0}} |
| 152 | transport = auto_reply |
| 153 | unseen = ${if match {${extract{deliveryMode}{$address_data}}}{localdelivery} {yes}{no}} |
| 154 | |
| 155 | localdelivery: |
| 156 | driver = accept |
| 157 | condition = ${if match {${extract{deliveryMode}{$address_data}}}{localdelivery} {1}{0}} |
| 158 | transport = local_delivery |
| 159 | |
| 160 | # If we've reached this point, the account doesn't exist, so we need to |
| 161 | # check to see if there is a catchall account, and if so do the usual for |
| 162 | # it too. NOTE: we do not support auto-reply in a catch-all. |
| 163 | # |
| 164 | # This could, of course, be abused by someone assigning an auto-reply to |
| 165 | # a forward_catchall. |
| 166 | |
| 167 | # NOTE TO SELF: See if reply router can be failed if an address comes from |
| 168 | # a catchall. |
| 169 | |
| 170 | lookup_catchall: |
| 171 | driver = redirect |
| 172 | address_data = GET_CATCHALL_DATA |
| 173 | # data is intentionally left blank so that the router will decline |
| 174 | # just want this router to do a lookup. |
| 175 | data = |
| 176 | # could probably do a no_more = true based on the result of that LDAP |
| 177 | # lookup to skip the next few routers, but there is no point as they are |
| 178 | # not doing anything heavy so I'll just let them fall through and fail. |
| 179 | |
| 180 | # The catchall routers are exactly the same as the above routers, except |
| 181 | # they make use of the GET_CATCHALL_DATA address_data to decide what to do |
| 182 | # with the mail. |
| 183 | |
| 184 | forward_catchall: |
| 185 | driver = redirect |
| 186 | condition = ${if match {${extract{deliveryMode}{$address_data}}}{forwardonly} {1}{0}} |
| 187 | data = ${extract{mailForwardingAddress}{$address_data}} |
| 188 | unseen = ${if match {${extract{deliveryMode}{$address_data}}}{localdelivery} {yes}{no}} |
| 189 | |
| 190 | localdelivery_catchall: |
| 191 | driver = accept |
| 192 | condition = ${if match {${extract{deliveryMode}{$address_data}}}{localdelivery} {1}{0}} |
| 193 | transport = local_delivery |
| 194 | |
| 195 | ###################################################################### |
| 196 | # TRANSPORTS CONFIGURATION # |
| 197 | ###################################################################### |
| 198 | |
| 199 | begin transports |
| 200 | |
| 201 | remote_smtp: |
| 202 | driver = smtp |
| 203 | |
| 204 | # Deliver to the mailbox specified in the LDAP directory. We make sure |
| 205 | # that quota is obeyed, and we try to send a messge to the user if it |
| 206 | # gets to over 85%. |
| 207 | |
| 208 | local_delivery: |
| 209 | driver = appendfile |
| 210 | maildir_format |
| 211 | directory = ${extract{mailMessageStore}{$address_data}}/Maildir |
| 212 | create_directory |
| 213 | directory_mode = 0700 |
| 214 | delivery_date_add |
| 215 | envelope_to_add |
| 216 | return_path_add |
| 217 | group = vmail |
| 218 | user = vmail |
| 219 | mode = 0600 |
| 220 | quota = ${eval:${sg{${extract{1}{,}{${extract{mailQuota}{$address_data}}}}}{S}{}}/1024}K |
| 221 | maildir_use_size_file = true |
| 222 | quota_warn_threshold = 85% |
| 223 | |
| 224 | # We set this to iso-2022-jp because we're in japan. Set it to whatever. |
| 225 | |
| 226 | auto_reply: |
| 227 | driver = autoreply |
| 228 | subject = "[Auto-Reply] $header_subject" |
| 229 | headers = "Content-Type: text/plain; charset=iso-2022-jp" |
| 230 | to = "$sender_address" |
| 231 | text = ${extract{mailReplyText}{$address_data}} |
| 232 | from = $local_part@$domain |
| 233 | |
| 234 | |
| 235 | ###################################################################### |
| 236 | # ACL CONFIGURATION # |
| 237 | # Specifies access control lists for incoming SMTP mail # |
| 238 | ###################################################################### |
| 239 | |
| 240 | begin acl |
| 241 | |
| 242 | # You should probably set up exiscan-acl's mime check here to scan for viruses |
| 243 | # and spam and reject at SMTP time. As I won't be doing that for a while, I've |
| 244 | # left it as an exercise for the reader. |
| 245 | |
| 246 | acl_check_rcpt: |
| 247 | accept hosts = : |
| 248 | deny message = Restricted characters in address |
| 249 | domains = +local_domains |
| 250 | local_parts = ^[.] : ^.*[@%!/|] |
| 251 | deny message = Restricted characters in address |
| 252 | domains = !+local_domains |
| 253 | local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ |
| 254 | accept local_parts = postmaster |
| 255 | domains = +local_domains |
| 256 | require verify = sender |
| 257 | accept domains = +local_domains |
| 258 | endpass |
| 259 | verify = recipient |
| 260 | accept domains = +relay_to_domains |
| 261 | endpass |
| 262 | verify = recipient |
| 263 | accept hosts = +relay_from_hosts |
| 264 | accept authenticated = * |
| 265 | deny message = relay not permitted |
| 266 | |
| 267 | acl_check_data: |
| 268 | require verify = header_syntax |
| 269 | message = This message has malformed headers. |
| 270 | deny message = This message contains malformed MIME ($demime_reason). |
| 271 | demime = * |
| 272 | condition = ${if >{$demime_errorlevel}{2}{1}{0}} |
| 273 | deny message = We do not accept ".$found_extension" attachments here as \ |
| 274 | they are common file extensions for viruses. If you wish \ |
| 275 | to send such an attachment, please zip it first. |
| 276 | demime = bat:btm:cmd:com:cpl:dll:exe:lnk:msi:pif:prf:reg:scr:vbs:url |
| 277 | accept |
| 278 | |
| 279 | begin retry |
| 280 | |
| 281 | # Address or Domain Error Retries |
| 282 | # ----------------- ----- ------- |
| 283 | |
| 284 | * * F,2h,15m; G,16h,1h,1.5; F,4d,6h |
| 285 | |
| 286 | ###################################################################### |
| 287 | # REWRITE CONFIGURATION # |
| 288 | ###################################################################### |
| 289 | |
| 290 | # There are no rewriting specifications in this default configuration file. |
| 291 | |
| 292 | begin rewrite |
| 293 | |
| 294 | ###################################################################### |
| 295 | # AUTHENTICATION CONFIGURATION # |
| 296 | ###################################################################### |
| 297 | |
| 298 | # There are no authenticator specifications in this default configuration file. |
| 299 | |
| 300 | begin authenticators |
| 301 | |
| 302 | plain: |
| 303 | driver = plaintext |
| 304 | public_name = PLAIN |
| 305 | server_condition = ${if ldapauth {user="uid=${quote_ldap_dn:$2},BASEDN" \ |
| 306 | pass=${quote:$3} ldap:///}{yes}{no}} |
| 307 | server_set_id = $2 |
| 308 | |
| 309 | |
| 310 | login: |
| 311 | driver = plaintext |
| 312 | public_name = LOGIN |
| 313 | server_prompts = Username:: : Password:: |
| 314 | server_condition = ${if ldapauth {user="uid=${quote_ldap_dn:$1},BASEDN" \ |
| 315 | pass=${quote:$2} ldap:///}{yes}{no}} |
| 316 | server_set_id = $1 |
| 317 | |
| 318 | ###################################################################### |
| 319 | # CONFIGURATION FOR local_scan() # |
| 320 | ###################################################################### |
| 321 | |
| 322 | # begin local_scan |
| 323 | |
| 324 | # End of Exim configuration file |