Commit | Line | Data |
---|---|---|
e0f3765a PH |
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 |