# us. This is primarily only usefull for emergancy 'queue
# flushing' operations, but should be populated with a list
# of trusted machines. Wildcards are not permitted
+# bsmtp_domains - Domains that we deliver locally via bsmtp
<%=
out = ""
if nodeinfo['mailrelay']
# will trigger things like rcpt to rate limiting or possibly a reject if
# enough hits are triggered.
#
-# value is stored in acl_c1
+# value is stored in acl_c_scr
######################################################################
# MAIN CONFIGURATION SETTINGS #
end
out
%>
+acl_smtp_predata = acl_check_predata
# accept domain literal syntax in e-mail addresses. To actually make use of
# this a router is also required
domainlist submission_domains = ${if exists {/etc/exim4/submission-domains}{/etc/exim4/submission-domains}{}}
-domainlist handled_domains = +local_domains : +virtual_domains
+domainlist bsmtp_domains = ${if exists {/etc/exim4/bsmtp}{partial-lsearch;/etc/exim4/bsmtp}{}}
+
+domainlist handled_domains = +local_domains : +virtual_domains : +bsmtp_domains
localpartlist local_only_users = lsearch;/etc/exim4/localusers
message_size_limit = 100M
message_logs = false
-smtp_accept_max = 300
smtp_accept_max_per_host = ${if match_ip {$sender_host_address}{+debianhosts}{0}{7}}
+<% if nodeinfo.has_key?('heavy_exim') and not nodeinfo['heavy_exim'].empty? %>
+smtp_accept_max = 300
smtp_accept_queue = 200
smtp_accept_queue_per_connection = 50
+<% else %>
+smtp_accept_max = 30
+smtp_accept_queue = 20
+smtp_accept_queue_per_connection = 10
+<% end %>
smtp_accept_reserve = 25
smtp_reserve_hosts = +debianhosts
delay_warning =
+<% if nodeinfo.has_key?('heavy_exim') and not nodeinfo['heavy_exim'].empty? %>
queue_run_max = 50
deliver_queue_load_max = 50
queue_only_load = 15
+<% else %>
+queue_run_max = 5
+deliver_queue_load_max = 10
+queue_only_load = 5
+<% end %>
queue_list_requires_admin = false
<%= out = ""
######################################################################
begin acl
+acl_getprofile:
+ # This is a bad hack to reset the variable, by defining it be something
+ # never referenced.
+
+ warn set acl_m_rprf = $acl_m_undefined
+
+ warn recipients = survey@popcon.debian.org
+ set acl_m_rprf = PopconMail
+
+ accept condition = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+ warn local_parts = +local_only_users
+ domains = +local_domains
+ hosts = !+debianhosts
+ set acl_m_rprf = localonly
+
+ accept condition = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+<%=
+out=''
+if nodeinfo['rtmaster']
+ out='
+ warn domains = rt.debian.org
+ set acl_m_rprf = RTMail
+
+ accept condition = ${if eq {$acl_m_rprf}{}{no}{yes}}
+'
+end
+out
+%>
+<%=
+out = ''
+if nodeinfo['packagesmaster']
+ out = '
+ warn domains = packages.debian.org
+ set acl_m_rprf = PackagesMail
+
+ accept condition = ${if eq {$acl_m_rprf}{}{no}{yes}}
+'
+end
+out
+%>
+<%=
+out = ''
+if nodeinfo['packagesqamaster']
+ out='
+ warn recipients = owner@packages.qa.debian.org : postmaster@packages.qa.debian.org
+ set acl_m_rprf = PTSOwner
+
+ accept condition = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+ warn senders = :
+ domains = packages.qa.debian.org
+ condition = ${if match{$local_part}{\N^bounces+\N}}
+ set acl_m_rprf = PTSListBounce
+
+ accept condition = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+ warn domains = packages.qa.debian.org
+ set acl_m_rprf = PTSMail
+
+ accept condition = ${if eq {$acl_m_rprf}{}{no}{yes}}
+'
+end
+out
+%>
+ warn recipients = change@db.debian.org : changes@db.debian.org : chpasswd@db.debian.org : ping@db.debian.org : recommend@nm.debian.org
+ set acl_m_rprf = DBSignedMail
+
+ accept condition = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+ warn set acl_m_rprf = normal
+
+ accept
+
check_helo:
- warn set acl_c1 = 0
+ warn set acl_c_scr = 0
<%=
out = ""
warn dnslists = list.dnswl.org&0.0.0.3
log_message = Hit on list.dnswl.org for $sender_host_address
- set acl_c1 = ${eval:$acl_c1-30}
+ set acl_c_scr = ${eval:$acl_c_scr-30}
warn dnslists = list.dnswl.org&0.0.0.2
log_message = Hit on list.dnswl.org for $sender_host_address
- set acl_c1 = ${eval:$acl_c1-20}
+ set acl_c_scr = ${eval:$acl_c_scr-20}
warn dnslists = list.dnswl.org
log_message = Hit on list.dnswl.org for $sender_host_address
- set acl_c1 = ${eval:$acl_c1-10}
+ set acl_c_scr = ${eval:$acl_c_scr-10}
warn condition = ${if isip {$sender_helo_name}{true}{false}}
log_message = remote host used IP address in HELO/EHLO greeting
- set acl_c1 = ${eval:$acl_c1+20}
+ set acl_c_scr = ${eval:$acl_c_scr+20}
warn !hosts = +debianhosts
condition = ${if eq{$host_lookup_failed}{1}}
- set acl_c1 = ${eval:$acl_c1+20}
+ set acl_c_scr = ${eval:$acl_c_scr+20}
warn !hosts = +debianhosts
condition = ${if eq{$host_lookup_failed}{0}}
condition = ${if match{$sender_host_name}{\N(^[^\.]*[0-9]\-+[0-9]|^[^\.]*[0-9]{5,}[^\.]|^([^\.]+\.)?[0-9][^ \.]*\.[^\.]+\..+\.[a-z]|^[^\.]*[0-9]\.[^\.]*[0-9]-[0-9]|^(dyn|cable|dhcp|dialup|ppp|adsl)[^\.]*[0-9])\N}}
- set acl_c1 = ${eval:$acl_c1+20}
+ set acl_c_scr = ${eval:$acl_c_scr+20}
warn !hosts = +debianhosts
condition = ${if match{$sender_helo_name}{\N(^[^\.]*[0-9]\-+[0-9]|^[^\.]*[0-9]{5,}[^\.]|^([^\.]+\.)?[0-9][^ \.]*\.[^\.]+\..+\.[a-z]|^[^\.]*[0-9]\.[^\.]*[0-9]-[0-9]|^(dyn|cable|dhcp|dialup|ppp|adsl)[^\.]*[0-9])\N}}
- set acl_c1 = ${eval:$acl_c1+20}
+ set acl_c_scr = ${eval:$acl_c_scr+20}
warn !hosts = +debianhosts
dnslists = dul.dnsbl.sorbs.net
- set acl_c1 = ${eval:$acl_c1+15}
+ set acl_c_scr = ${eval:$acl_c_scr+15}
# If the sender's helo name is empty, the message will be rejected later
# because the helo is empty. If the rDNS lookup failed, we are already
condition = ${if def:sender_helo_name {yes}{no}}
condition = ${if eq {${lc:$sender_helo_name}}{${lc:$sender_host_name}}{no}{yes}}
log_message = HELO doesn't match rDNS
- set acl_c1 = ${eval:$acl_c1+8}
+ set acl_c_scr = ${eval:$acl_c_scr+8}
# Regexes of doom
# matches 098325879 - looks fishy
} \
}
log_message = non-FQDN HELO
- set acl_c1 = ${eval:$acl_c1+12}
+ set acl_c_scr = ${eval:$acl_c_scr+12}
# Matches DOMAIN99.com - looks bad
warn condition = ${if match {$sender_helo_name}{\N^[A-Z]+[A-Z0-9\-]+\.[A-Za-z0-9]+$\N}}
log_message = SHOUTING HELO
- set acl_c1 = ${eval:$acl_c1+7}
+ set acl_c_scr = ${eval:$acl_c_scr+7}
# Random HELO (run of 7 consonants) (constructed by viruses). We purposefully
# skip matching on machines named .*smtp.*, since that's 4 already. This is a fairly
condition = ${if match {${lc:$sender_helo_name}}{\N^[a-z0-9]+\.[a-z]+$\N}}
condition = ${if match {${lc:$sender_helo_name}}{\N.*[bcdfghjklmnpqrstvwxz]{7,}.*\.[a-z]+$\N}}
log_message = random HELO
- set acl_c1 = ${eval:$acl_c1+5}
+ set acl_c_scr = ${eval:$acl_c_scr+5}
# Implicit, but simpler to just say it
accept
# This logic gives you a list of commonly forged domains in helo to reject against
- warn set acl_m2 = ${lookup{$sender_helo_name} \
+ warn set acl_m_frg = ${lookup{$sender_helo_name} \
nwildlsearch{/etc/exim4/helo-check} \
{${if eq{$value}{}{$sender_helo_name}{$value}}}{}}
# say helo as a name in the list but we can't look them up
defer !hosts = +debianhosts
- condition = ${if eq{$acl_m2}{}{no}{yes}}
+ condition = ${if eq{$acl_m_frg}{}{no}{yes}}
condition = ${if eq{$sender_host_name}{}{yes}{no}}
condition = ${if eq{$host_lookup_failed}{1}{no}{yes}}
message = Access temporarily denied. Resolve failed PTR for $sender_host_address
# If DNS works, go ahead and reject them
- drop !hosts = +debianhosts
- condition = ${if and { {!eq{$acl_m2}{}}{!match{$sender_host_name}{${rxquote:$acl_m2}\N$\N}}}{yes}{no}}
+ drop !hosts = +debianhosts
+ condition = ${if and { {!eq{$acl_m_frg}{}}{!match{$sender_host_name}{${rxquote:$acl_m_frg}\N$\N}}}{yes}{no}}
message = HELO mismatch Forged HELO for ($sender_helo_name)
# disabled accounts don't even get local mail.
condition = ${if match_local_part {$sender_address_local_part}{${extract{directory}{VDOMAINDATA}{${value}/neversenders}}}{1}{0}}
message = no mail should ever come from <$sender_address>
- deny local_parts = +local_only_users
- domains = +local_domains
- hosts = !+debianhosts
- message = mail for $local_part is only accepted internally
+ warn acl = acl_getprofile
+ condition = ${if eq{$acl_m_prf}{}}
+ set acl_m_prf = $acl_m_rprf
+
+ defer condition = ${if eq{$acl_m_prf}{$acl_m_rprf}{no}{yes}}
+ log_message = Only one profile at a time, please
+
+ warn condition = ${if eq{$acl_m_prf}{localonly}}
+ set acl_m_lrc = ${if eq{$acl_m_lrc}{}{$local_part@$domain}{$acl_m_lrc, $local_part@$domain}}
<%=
out=''
end
out
%>
-
- deny !recipients = survey@popcon.debian.org
- !verify = sender
+<%=
+out=''
+if nodeinfo['packagesmaster']
+ out='
+ warn condition = ${if eq {$acl_m_prf}{PackagesMail}}
+ condition = ${if eq {$sender_address}{$local_part@$domain}}
+ message = X-Packages-FromTo-Same: yes
+'
+end
+out
+%>
+ deny condition = ${if eq {$acl_m_prf}{PopconMail}{no}{yes}}
+ !verify = sender
defer !hosts = +debianhosts
- condition = ${if >{${eval:$acl_c1}}{0}}
+ condition = ${if >{${eval:$acl_c_scr+0}}{0}}
ratelimit = 10 / 60m / per_rcpt / $sender_host_address
message = slow down (no reverse dns, mismatched ehlo, dialup, or in blacklists)
<%=
# closure, but I\'m fairly sure it\'s now worth it, since the backport of
# policyd-weight is trivial.
warn !hosts = +debianhosts
- set acl_m9 = ${readsocket{inet:127.0.0.1:12525}\
+ set acl_m_pw = ${readsocket{inet:127.0.0.1:12525}\
{request=smtpd_access_policy\n\
protocol_state=RCPT\n\
protocol_name=${uc:$received_protocol}\n\
# Defer on socket error
defer !hosts = +debianhosts
- condition = ${if eq{$acl_m9}{socket failure}{yes}{no}}
+ condition = ${if eq{$acl_m_pw}{socket failure}{yes}{no}}
message = Cannot connect to policyd-weight. Please try again later.
- # Set proposed action to $acl_m8 and message to $acl_m7
+ # Set proposed action to $acl_m_act and message to $acl_m_mes
warn !hosts = +debianhosts
- set acl_m8 = ${extract{action}{$acl_m9}}
- set acl_m7 = ${sg{$acl_m9}{\Naction=[^ ]+ (.*)\n\n\N}{\$1}}
+ set acl_m_mes = ${extract{action}{$acl_m_pw}}
+ set acl_m_act = ${sg{$acl_m_pw}{\Naction=[^ ]+ (.*)\n\n\N}{\$1}}
# Add X-policyd-weight header line to message
warn !hosts = +debianhosts
- message = $acl_m7
- condition = ${if eq{$acl_m8}{PREPEND}{yes}{no}}
+ message = $acl_m_mes
+ condition = ${if eq{$acl_m_act}{PREPEND}{yes}{no}}
# Write log message, if policyd-weight can\'t run checks
warn !hosts = +debianhosts
- log_message = policyd-weight message: $acl_m7
- condition = ${if eq{$acl_m8}{DUNNO}{yes}{no}}
+ log_message = policyd-weight message: $acl_m_mes
+ condition = ${if eq{$acl_m_act}{DUNNO}{yes}{no}}
# Deny mails which policyd-weight thinks are spam
deny !hosts = +debianhosts
- message = policyd-weight said: $acl_m7
- condition = ${if eq{$acl_m8}{550}{yes}{no}}
+ message = policyd-weight said: $acl_m_mes
+ condition = ${if eq{$acl_m_act}{550}{yes}{no}}
# Defer messages when policyd-weight suggests so.
defer !hosts = +debianhosts
- message = policyd-weight said: $acl_m7
- condition = ${if eq{$acl_m8}{450}{yes}{no}}
+ message = policyd-weight said: $acl_m_mes
+ condition = ${if eq{$acl_m_act}{450}{yes}{no}}
'
end
out
%>
- warn recipients = survey@popcon.debian.org
- set acl_m1 = PopconMail
-
<%=
out=''
if nodeinfo['rtmaster']
out='
- warn domains = rt.debian.org
- set acl_m1 = RTMail
- set acl_m12 = ${if def:acl_m12 {$acl_m12} {${if or{{match{$local_part}{\N[^+]+\+\d+\N}}{match{$local_part}{\N[^+]+\+new\N}}} {RTMailRecipientHasSubaddress}}}}
+ warn condition = ${if eq{$acl_m_prf}{RTMail}}
+ set acl_m12 = ${if def:acl_m12 {$acl_m12} {${if or{{match{$local_part}{\N[^+]+\+\d+\N}}{match{$local_part}{\N[^+]+\+new\N}}} {RTMailRecipientHasSubaddress}}}}
'
end
out
%>
-<%=
-out=''
-if nodeinfo['packagesqamaster']
- out='
- warn domains = packages.qa.debian.org
- set acl_m1 = PTSMail
-
- warn recipients = owner@packages.qa.debian.org : postmaster@packages.qa.debian.org
- set acl_m1 = PTSOwner
-
- warn senders = :
- domains = packages.qa.debian.org
- condition = ${if match{$local_part}{\N^bounces+\N}}
- set acl_m1 = PTSListBounce
-'
-end
-out
-%>
- warn recipients = change@db.debian.org : changes@db.debian.org : chpasswd@db.debian.org : ping@db.debian.org : recommend@nm.debian.org
- set acl_m1 = DBSignedMail
-
<%=
out = ""
if has_variable?("greylistd") && greylistd == "true"
elsif has_variable?("postgrey") && postgrey == "true"
out = '
# next three are greylisting, inspired by http://www.bebt.de/blog/debian/archives/2006/07/30/T06_12_27/index.html
- # this adds acl_m4 if there isn\'t one (so unique per message)
+ # this adds acl_m_grey if there isn\'t one (so unique per message)
warn
!senders = :
!hosts = : +debianhosts : WHITELIST
- condition = ${if def:acl_m4 {no}{yes}}
- set acl_m4 = $pid.$tod_epoch.$sender_host_port
+ condition = ${if def:acl_m_grey {no}{yes}}
+ set acl_m_grey = $pid.$tod_epoch.$sender_host_port
# and defers the message if postgrey thinks it should be defered ...
defer
!authenticated = *
domains = +handled_domains : +rcpthosts
local_parts = GREYLIST_LOCAL_PARTS
- set acl_m3 = request=smtpd_access_policy\n\
+ set acl_m_pgr = request=smtpd_access_policy\n\
protocol_state=RCPT\n\
protocol_name=${uc:$received_protocol}\n\
- instance=${acl_m4}\n\
+ instance=${acl_m_grey}\n\
helo_name=${sender_helo_name}\n\
client_address=${substr_-3:${mask:$sender_host_address/24}}\n\
client_name=${sender_host_name}\n\
sender=${sender_address}\n\
recipient=$local_part@$domain\n\n
- set acl_m3 = ${sg{\
- ${readsocket{/var/run/postgrey/socket}{$acl_m3}\
+ set acl_m_pgr = ${sg{\
+ ${readsocket{/var/run/postgrey/socket}{$acl_m_pgr}\
{5s}{}{action=DUNNO}}\
}{action=}{}}
- message = ${sg{$acl_m3}{^\\\\w+\\\\s*}{}}
+ message = ${sg{$acl_m_pgr}{^\\\\w+\\\\s*}{}}
log_message = greylisted.
- condition = ${if eq{${uc:${substr{0}{5}{$acl_m3}}}}{DEFER}}
+ condition = ${if eq{${uc:${substr{0}{5}{$acl_m_pgr}}}}{DEFER}}
# ... or adds a header with information about how long the delay was
warn
!authenticated = *
domains = +handled_domains : +rcpthosts
local_parts = GREYLIST_LOCAL_PARTS
- condition = ${if eq{${uc:${substr_0_7:$acl_m3}}}{PREPEND}}
- message = ${sg{$acl_m3}{^\\\\w+\\\\s*}{}}
+ condition = ${if eq{${uc:${substr_0_7:$acl_m_pgr}}}{PREPEND}}
+ message = ${sg{$acl_m_pgr}{^\\\\w+\\\\s*}{}}
'
end
out
acl_check_mime:
deny condition = ${if <{$message_size}{256000}}
- set acl_m5 = ${perl{surblspamcheck}}
- condition = ${if eq{$acl_m5}{false}{no}{yes}}
- log_message = $acl_m5
- message = $acl_m5
+ set acl_m_srb = ${perl{surblspamcheck}}
+ condition = ${if eq{$acl_m_srb}{false}{no}{yes}}
+ log_message = $acl_m_srb
+ message = $acl_m_srb
accept
'
out
%>
+acl_check_predata:
+ deny condition = ${if eq{$acl_m_lcl}{localonly}}
+ message = mail for $acl_m_lrc is only accepted internally
+
+ accept
+
+
#!!# ACL that is used after the DATA command
check_message:
require verify = header_syntax
out=''
if nodeinfo['rtmaster']
out='
- deny condition = ${if eq {$acl_m1}{RTMail}}
+ deny condition = ${if eq {$acl_m_prf}{RTMail}}
condition = ${if and{{!match {${lc:$rh_Subject:}} {debian rt}} \
{!match {${lc:$rh_Subject:]}} {\N\[rt.debian.org \N}} \
{!match {$acl_m12}{RTMailRecipientHasSubaddress}}}}
if nodeinfo['packagesqamaster']
out='
deny !hosts = +debianhosts : 217.196.43.134
- condition = ${if eq {$acl_m1}{PTSMail}}
+ condition = ${if eq {$acl_m_prf}{PTSMail}}
condition = ${if def:h_X-PTS-Approved:{false}{true}}
message = messages to the PTS require an X-PTS-Approved header
'
end
out
%>
- deny condition = ${if match {$message_body}{\Nhttp:\/\/[a-z\.-]+\/video1?.exe\N}}
- message = Blackisted URI found in body
-
- deny condition = ${if eq {$acl_m1}{DBSignedMail}}
+ deny condition = ${if eq {$acl_m_prf}{DBSignedMail}}
condition = ${if and {{!match {$message_body}{PGP MESSAGE}} \
{!match {$message_body}{PGP SIGNED MESSAGE}} \
{!match {$message_body}{PGP SIGNATURE}} \
end
out
%>
-
- deny spam = $value/defer_ok
- domains = +handled_domains : +rcpthosts
- message = message got a spam score of $spam_score
- local_parts = ${if exists {/etc/exim4/sa_users}\
- {${if match_domain{$domain}{+virtual_domains}\
- {${lookup{$local_part@$domain}nwildlsearch{/etc/exim4/sa_users}{$local_part}{}}}\
- {${lookup{$local_part}lsearch{/etc/exim4/sa_users}{$local_part}{}}}}}}
-
<%=
out=''
if nodeinfo.has_key?('heavy_exim') and not nodeinfo['heavy_exim'].empty?
out='
deny condition = ${if <{$message_size}{256000}}
- set acl_m5 = ${perl{surblspamcheck}}
- condition = ${if eq{$acl_m5}{false}{no}{yes}}
- log_message = $acl_m5
+ set acl_m_srb = ${perl{surblspamcheck}}
+ condition = ${if eq{$acl_m_srb}{false}{no}{yes}}
+ log_message = $acl_m_srb
+ message = $acl_m_srb
'
end
out
%>
# Check header_sender except for survey@popcon.d.o
- deny condition = ${if eq{$acl_m1}{PopconMail}{false}{true}}
- !verify = header_sender
- message = No valid sender found in the From:, Sender: and Reply-to: headers
+ deny condition = ${if eq{$acl_m_prf}{PopconMail}{false}{true}}
+ !verify = header_sender
+ message = No valid sender found in the From:, Sender: and Reply-to: headers
+<%=
+out = ""
+if nodeinfo['packagesmaster']
+ out = '
+ deny message = Congratulations, you scored $spam_score points.
+ log_message = spam: $spam_score points.
+ condition = ${if eq {$acl_m_prf}{PackagesMail}}
+ !authenticated = *
+ !verify = certificate
+ !hosts = +debianhosts
+ condition = ${if <{$message_size}{256000}}
+ spam = pkg_user : true
+ condition = ${if >{$spam_score_int}{59}}
+'
+end
+out
+%>
accept
bsmtp:
debug_print = "R: bsmtp for $local_part@$domain"
driver = manualroute
- domains = !+local_domains
+ domains = +bsmtp_domains
require_files = /etc/exim4/bsmtp
route_list = * ${extract{file}{\
${lookup{$domain}partial-lsearch{/etc/exim4/bsmtp}\
remote_smtp:
driver = smtp
connect_timeout = 1m
+ delay_after_cutoff = false
<%=
out = ""
if has_variable?("exim_ssl_certs") && exim_ssl_certs == "true"
remote_smtp_smarthost:
debug_print = "T: remote_smtp_smarthost for $local_part@$domain"
driver = smtp
+ delay_after_cutoff = false
port = '
out += nodeinfo['smarthost_port'].to_s + "\n"
if has_variable?("exim_ssl_certs") && exim_ssl_certs == "true"
begin retry
debian.org * F,2h,10m; G,16h,2h,1.5; F,14d,8h
-* * senders=: F,2h,10m
* rcpt_4xx F,2h,5m; F,4h,10m; F,4d,15m
* * F,2h,15m; G,16h,2h,1.5; F,4d,8h