1 # "exim -C /config/file.new -bV")
2 # information taken from vexim, http://geekbiker.net/exim-tricks.html,
3 # gentoo-wiki, debian administrators and others
6 primary_hostname = codemages.net
9 VIRTUO_DB = /etc/virtuo/virtuo.sdb
11 hostlist whitelist_hosts = sqlite;VIRTUO_DB select host from whitelist where host = '${quote_sqlite:$domain}';
12 hostlist blacklist_hosts = sqlite;VIRTUO_DB select host from blacklist where host = '${quote_sqlite:$domain}';
13 domainlist local_domains = @ : sqlite;VIRTUO_DB select domain_alias from domain_aliases where domain_alias = '${quote_sqlite:$domain}'; : sqlite;VIRTUO_DB select domain from domains where domain = '${quote_sqlite:$domain}';
14 domainlist relay_to_domains = sqlite;VIRTUO_DB select host from relay_to_domains where host = '${quote_sqlite:$domain}';
15 hostlist relay_from_hosts = localhost : sqlite;VIRTUO_DB select host from relay_from_hosts where host = '${quote_sqlite:$domain}';
18 daemon_smtp_ports = 25 : 465 : 587
19 tls_on_connect_ports = 465
20 acl_smtp_rcpt = acl_check_rcpt
22 acl_smtp_data = acl_check_content
24 acl_smtp_helo = acl_check_helo
26 acl_smtp_mime = acl_check_mime
35 rfc1413_query_timeout = 0s
37 av_scanner = clamd:127.0.0.1 3310
39 tls_advertise_hosts = *
40 tls_certificate = /etc/ssl/certs/freya_cert-2008-05-05.pem
41 tls_privatekey = /etc/ssl/private/freya_privatekey-2008-05-05.pem
43 ignore_bounce_errors_after = 2d
44 #helo_try_verify_hosts = !+relay_from_hosts
46 timeout_frozen_after = 7d
48 log_selector = +subject +tls_cipher +tls_peerdn
50 smtp_banner = "ESMTP Server Ready"
52 ######################################################################
54 # Specifies access control lists for incoming SMTP mail #
55 ######################################################################
60 defer message = Sorry, too busy. Try again later.
61 ratelimit = 3 / 1s / per_conn / leaky
69 accept hosts = +relay_from_hosts
75 deny message = HELO/EHLO with my ip address. You are not me.
76 log_message = HELO/EHLO 84.20.228.4
78 !hosts = +relay_from_hosts
79 condition = ${if eq {$sender_helo_name}{84.20.228.4} {yes}{no}}
81 deny message = HELO/EHLO with my domain name. You are not me.
82 log_message = HELO/EHLO my.domain
84 !hosts = +relay_from_hosts
85 condition = ${if match {$sender_helo_name}{mages.ath.cx} {yes}{no}}
87 deny message = HELO/EHLO with my domain name. You are not me.
88 log_message = HELO/EHLO my.domain
90 !hosts = +relay_from_hosts
91 condition = ${if match {$sender_helo_name}{codemages.net} {yes}{no}}
93 deny message = HELO/EHLO with my domain name. You are not me.
94 log_message = HELO/EHLO my.domain
96 !hosts = +relay_from_hosts
97 condition = ${if match {$sender_helo_name}{levstik.name} {yes}{no}}
99 deny message = Fine, then the mail I accept is also none
100 log_message = HELO/EHLO none
102 !hosts = +relay_from_hosts
103 condition = ${if match {$sender_helo_name}{none} {yes}{no}}
105 deny message = You are hardly local, fool
106 log_message = HELO/EHLO localhost
108 !hosts = +relay_from_hosts
109 condition = ${if match {$sender_helo_name}{localhost} {yes}{no}}
111 deny message = Invalid HELO. You must be spam or a virus, or your system administrator is an idiot.
113 !hosts = +relay_from_hosts
114 condition = ${if match{$sender_helo_name}{\\.}{no}{yes}}
117 deny condition = ${if match{$sender_helo_name}{^[0-9]\.[0-9]\.[0-9]\.[0-9]}{yes}{no} }
119 !hosts = +relay_from_hosts
120 message = HELO/EHLO with IP only.
121 log_message = HELO/EHLO IP only
125 # deny message = Faked Yahoo, so you must be spam.
126 # log_message = Fake Yahoo
128 # !hosts = +relay_from_hosts
129 # senders = *@yahoo.com
130 # condition = ${if match {$sender_host_name}{\Nyahoo.com$\N}{no}{yes}}
132 ## deny message = Faked Source Mage, so you must be spam.
133 # log_message = Fake Source Mage
135 # !hosts = +relay_from_hosts : +accept_from_hosts
136 # senders = *@sourcemage.org
137 # condition = ${if match {$sender_host_name}{\Nsourcemage.org$\N}{no}{yes}}
139 deny message = Faked hotmail, so you must be spam.
140 log_message = Fake hotmail
142 !hosts = +relay_from_hosts
143 senders = *@hotmail.com
144 condition = ${if match {$sender_host_name}{\Nhotmail.com$\N}{no}{yes}}
146 deny message = Faked MSN, so you must be spam.
147 log_message = Fake MSN
149 !hosts = +relay_from_hosts
151 condition = ${if match {$sender_host_name}{\N(hotmail|msn).com$\N}{no}{yes}}
153 deny message = Faked ebay, so you must be spam.
154 log_message = Fake ebay
156 !hosts = +relay_from_hosts
158 condition = ${if match {$sender_host_name}{\N(ebay).com$\N}{no}{yes}}
160 deny message = Faked Paypal, so you must be spam.
161 log_message = Fake paypal
163 !hosts = +relay_from_hosts
164 senders = *@paypal.com
165 condition = ${if match {$sender_host_name}{\N(paypal).com$\N}{no}{yes}}
168 deny message = Faked AOL, so you must be spam.
169 log_message = Fake AOL
171 !hosts = +relay_from_hosts
173 condition = ${if match {$sender_host_name}{\Nmx.aol.com$\N}{no}{yes}}
175 deny message = DNSBL listed at $dnslist_domain\n$dnslist_text
177 !hosts = +relay_from_hosts
178 dnslists = sqlite;VIRTUO_DB select host from dnsbl ;
180 # defer message = Greylisting in effect, please try again later.
181 # log_message = greylisted.
182 # domains = +local_domains : +relay_to_domains
183 # !senders = : postmaster@* : abuse@*
184 # !hosts = +relay_from_hosts
186 # condition = ${if eq {${readsocket{/var/run/greylstd/greylstd.sock}{check $sender_host_address $sender_address $local_part@$domain\n}{5s}{}{}}}{defer}{true}{false}}
190 deny local_parts = ^.*[@%!/|] : ^\\.
192 accept local_parts = postmaster
193 domains = +local_domains
195 accept domains = +local_domains
199 accept domains = +relay_to_domains
203 accept hosts = +relay_from_hosts
205 accept authenticated = *
207 deny message = relay not permitted
210 # Decode MIME parts to disk. This will support virus scanners later.
211 warn decode = default
213 deny condition = ${if > {$mime_anomaly_level}{2} \
215 message = This message contains a MIME error ($mime_anomaly_text)
216 log_message = DENY: MIME Error ($mime_anomaly_text)
218 # Too many MIME parts
220 deny condition = ${if >{$mime_part_count}{1024}{yes}{no}}
221 message = MIME error: Too many parts (max 1024)
222 log_message = DENY: MIME Error (Too many MIME parts: $mime_part_count)
224 # Excessive line length
226 deny regex = ^.{8000}
227 message = MIME error: Line length in message or single header exceeds 8000.
228 log_message = DENY: MIME Error (Maximum line length exceeded)
232 deny condition = ${if eq {$mime_content_type}{message/partial}{yes}{no}}
233 message = MIME error: MIME type message/partial not allowed here
234 log_message = DENY: MIME Error (MIME type message/partial found)
236 # Filename length too long (> 255 characters)
238 deny condition = ${if >{${strlen:$mime_filename}}{255}{yes}{no}}
239 message = MIME error: Proposed filename exceeds 255 characters
240 log_message = DENY: MIME Error (Proposed filename too long)
242 # MIME boundary length too long (> 1024)
244 deny condition = ${if >{${strlen:$mime_boundary}}{1024}{yes}{no}}
245 message = MIME error: MIME boundary length exceed 1024 characters
246 log_message = DENY: MIME Error (Boundary length too long)
248 # File extension filtering.
249 deny condition = ${if match \
250 {${lc:$mime_filename}} \
251 {\N(\.bat|\.btm|\.cmd|\.com|\.cpl|\.dll|\.exe|\.lnk|\.msi|\.pif|\.prf|\.reg|\.scr|\.vbs|\.url)$\N} \
253 message = Blacklisted file extension detected in "$mime_filename". If you legitimately need to send these files please zip them first.
254 log_message = DENY: Blacklisted extension ("$mime_filename")
256 # finally accept all the rest
260 deny condition = ${if !def:h_Message-ID: {1}}
262 !hosts = +relay_from_hosts : +whitelist_hosts
263 message = Message SHOULD have Message-ID: but does not
265 deny condition = ${if !def:h_Date: {1}}
267 !hosts = +relay_from_hosts : +whitelist_hosts
268 message = Message SHOULD have Date: but does not
270 deny message = Hiding of file extensions is not allowed!
271 log_message = Dangerous extension (CLSID hidden)
272 regex = ^(?i)Content-Disposition::(.*?)filename=\\s*"+((\{[a-hA-H0-9-]{25,}\})|((.*?)\\s{10,}(.*?)))"+\$
274 # Reject virus infested messages.
275 deny message = This message contains malware ($malware_name)
276 log_message = malware ($malware_name)
279 warn message = X-Antivirus-Scanner: Scanned with ClamAV
280 # finally accept all the rest
284 ######################################################################
285 # ROUTERS CONFIGURATION #
286 # Specifies how addresses are handled #
287 ######################################################################
288 # THE ORDER IN WHICH THE ROUTERS ARE DEFINED IS IMPORTANT! #
289 # An address is passed to each router in turn until it is accepted. #
290 ######################################################################
294 virtual_domain_aliases:
298 domains = ${lookup sqlite{VIRTUO_DB select domain_alias from domain_aliases }}
299 data = ${quote_local_part:$local_part}@${lookup sqlite{VIRTUO_DB select domain_target from domain_aliases where domain_alias = '${domain}' }}
306 data = ${lookup sqlite{VIRTUO_DB select alias_target from aliases where alias = '${local_part}' and domain= '${domain}' }}
307 local_part_suffix = +* : -* : _*
308 local_part_suffix_optional
310 # file_transport = dspam_spamcheck
311 # reply_transport = address_reply
312 # pipe_transport = address_pipe
318 headers_add = Precedence: list\n\
319 List-Id: "${lookup sqlite{VIRTUO_DB select description from lists where list = '${local_part}' and domain = '${domain}' }}" <${lookup sqlite{VIRTUO_DB select list from lists where list = '${local_part}' and domain = '${domain}' }}.${lookup sqlite{VIRTUO_DB select domain from lists where list = '${local_part}' and domain = '${domain}' }}>\n\
320 List-Post: <mailto:${lookup sqlite{VIRTUO_DB select list from lists where list = '${local_part}' and domain = '${domain}' }}@${lookup sqlite{VIRTUO_DB select domain from lists where list = '${local_part}' and domain = '${domain}' }}>
321 data = ${lookup sqlite{VIRTUO_DB select member from lists_members where list = '${local_part}' and domain= '${domain}' }}
325 domains = ! +local_domains
326 transport = remote_smtp
327 ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
331 dspam_false_positive_router:
333 local_part_prefix = notspam-
334 transport = dspam_false_positive
339 local_part_prefix = clean-
340 transport = dspam_clean
344 dspam_spam_miss_router:
346 local_part_prefix = spam-
347 transport = dspam_spam_miss
350 dspam_spam_corpus_router:
352 local_part_prefix = spamtrain-
353 transport = dspam_spam_corpus
358 local_part_suffix = +* : -* : _*
359 local_part_suffix_optional
361 domains = ! mages.ath.cx
362 condition = "${if and {{!def:h_X-FILTER-DSPAM:} {!eq {$received_protocol}{spam-scanned}}}{1}{0}}"
363 headers_add = "X-FILTER-DSPAM: by $primary_hostname on $tod_full"
365 transport = dspam_spamcheck
371 data = ${lookup sqlite{VIRTUO_DB select home_mail from users where username = '${local_part}' and domain= '${domain}' and home_mail != '' }}
372 local_part_suffix = +* : -* : _*
373 local_part_suffix_optional
375 file_transport = virtual_delivery
376 reply_transport = address_reply
377 pipe_transport = address_pipe
380 ######################################################################
381 # TRANSPORTS CONFIGURATION #
382 ######################################################################
383 # ORDER DOES NOT MATTER #
384 # Only one appropriate transport is called for each delivery. #
385 ######################################################################
387 # A transport is used only when referenced from a router that successfully
388 # handles an address.
394 command = "/usr/sbin/exim -oMr spam-scanned -bS"
395 transport_filter = "/usr/bin/dspam --process --stdout --deliver=innocent,spam --user ${lc:$local_part}@${lc:$domain}"
397 home_directory = "/tmp"
398 current_directory = "/tmp"
403 return_fail_output = true
404 return_path_add = false
410 command = "/usr/bin/dspam --user ${lc:$local_part}@${lc:$domain} --class=spam --source=error"
411 home_directory = "/tmp"
412 current_directory = "/tmp"
416 return_fail_output = true
417 return_path_add = false
423 command = "/usr/bin/dspam --user ${lc:$local_part}@${lc:$domain} --class=spam --source=corpus"
424 home_directory = "/tmp"
425 current_directory = "/tmp"
429 return_fail_output = true
430 return_path_add = false
434 dspam_false_positive:
436 command = "/usr/bin/dspam --user ${lc:$local_part}@${lc:$domain} --class=innocent --source=error"
437 home_directory = "/tmp"
438 current_directory = "/tmp"
442 return_fail_output = true
443 return_path_add = false
449 command = "/usr/bin/dspam --user ${lc:$local_part}@${lc:$domain} --class=innocent --source=corpus"
450 home_directory = "/tmp"
451 current_directory = "/tmp"
455 return_fail_output = true
456 return_path_add = false
467 command = /usr/libexec/dovecot/deliver -c /etc/dovecot/dovecot.conf -d $local_part@$domain
487 ######################################################################
488 # RETRY CONFIGURATION #
489 ######################################################################
493 # This single retry rule applies to all domains and all errors. It specifies
494 # retries every 15 minutes for 2 hours, then increasing retry intervals,
495 # starting at 1 hour and increasing each time by a factor of 1.5, up to 16
496 # hours, then retries every 6 hours until 4 days have passed since the first
499 # Domain Error Retries
500 # ------ ----- -------
502 * * F,2h,15m; G,16h,1h,1.5; F,14d,6h
506 ######################################################################
507 # REWRITE CONFIGURATION #
508 ######################################################################
510 # There are no rewriting specifications in this default configuration file.
516 ######################################################################
517 # AUTHENTICATION CONFIGURATION #
518 ######################################################################
520 # There are no authenticator specifications in this default configuration file.
527 server_socket = /var/run/dovecot/auth-client
528 server_set_id = $auth1
533 server_socket = /var/run/dovecot/auth-client
534 server_set_id = $auth1