# exim4u Config File /etc/exim/exim.conf # # Copyright (c) 2009 MailHub4U.com, LLC # exim4u is a derivative work of vexim copyrighted in 2003 by Avleen Vig and the Virtual Exim Development Team # # /etc/exim/exim.conf is the main exim configuration file for exim4u. # Other configuration files required in the /etc/exim directory for exim4u to work properly are: # exim4u_acl_check_dkim.conf.inc # exim4u_backup_mx_host_names # exim4u_backup_mx_rl_host_names # exim4u_global_spam_virus # exim4u_hostnames+hostIPs # exim4u_IPblacklist # exim4u_IPskip_sender_verify # exim4u_IPwhitelist # exim4u_local.conf.inc # exim4u_local_rl.conf.inc # exim4u_relay_from_hosts # exim4u_sender_rl_addr # exim4u_sender_rl_dom # exim-acl-check-spf.conf.inc # exim-greylist.conf.inc # exim-group-router.conf.inc # exim-mailinglist-router.conf.inc # exim-mailinglist-transport.conf.inc # exim.pl directory containing the following files: exim_surbl.pl surbl_whitelist.txt three-level-tlds two-level-tlds # ###################################################################### # Runtime configuration file for Exim # ###################################################################### # ########### IMPORTANT ########## IMPORTANT ########### IMPORTANT ########### # # # Whenever you change Exim's configuration file, you *must* remember to # # HUP the Exim daemon, because it will not pick up the new configuration # # until you do. However, any other Exim processes that are started, for # # example, a process started by an MUA in order to send a message, will # # see the new configuration as soon as it is in place. # # # # You do not need to HUP the daemon for changes in auxiliary files that # # are referenced from this file. They are read every time they are used. # # # # It is usually a good idea to test a new configuration for syntactic # # correctness before installing it (for example, by running the command # # "exim -C /config/file.new -bV"). # # # ########### IMPORTANT ########## IMPORTANT ########### IMPORTANT ########### # # # exim4u: local configuration file .include /etc/exim/exim4u_local.conf.inc # # exim4u: Define smtp_active_hostname # If MULTI_IP is turned off then make smtp_active_hostname = $primary_hostname, else; # If the $sender_host_address does not equal the $received_ip_address then the mail originated from another machine # and smtp_active_hostname is then equal to the reverse lookup of the incoming interface which is received_ip_address. # Otherwise, (if all else fails) set smtp_active_hostname = $primary_hostname. smtp_active_hostname = ${if eq{MULTI_IP}{YES} \ {${if !eq{$sender_host_address}{$received_ip_address}{${lookup dnsdb{ptr=$received_ip_address}}}{$primary_hostname}}} \ {$primary_hostname}} # MY_IP is the ptr record (reverse lookup) for $smtp_active_hostname MY_IP = ${lookup dnsdb{a=$smtp_active_hostname}} # # exim4u: smtp_banner is the line that is advertised during incoming SMTP sessions. smtp_banner = "$smtp_active_hostname ESMTP (Exim $version_number) $tod_full" # # exim4u: tls Certificates tls_certificate = ${if eq{MULTI_IP}{YES}{/etc/pki/tls/exim_tls/exim.MY_IP.cert}{/etc/pki/tls/exim_tls/exim.cert}} tls_privatekey = ${if eq{MULTI_IP}{YES}{/etc/pki/tls/exim_tls/exim.MY_IP.key}{/etc/pki/tls/exim_tls/exim.key}} # # exim4u: Define mail headers as follows: received_header_text = Received: \ ${if def:sender_rcvhost {from $sender_rcvhost\n\t}\ {${if def:sender_ident \ {from ${quote_local_part:$sender_ident} }}\ ${if def:sender_helo_name {(helo=$sender_helo_name)\n\t}}}}\ by $smtp_active_hostname \ ${if def:received_protocol {with $received_protocol}} \ ${if def:tls_cipher {($tls_cipher)\n\t}}\ (Exim $version_number)\n\t\ ${if def:sender_address \ {(envelope-from <$sender_address>)\n\t}}\ id $message_exim_id\ ${if def:received_for {\n\tfor $received_for}} # # exim4u: Is ClamAV enabled globally CLAMENABLED = ${lookup{ClamAV}lsearch{/etc/exim/exim4u_global_spam_virus}} # exim4u: Calculate the spamreject score SPAMREJECT = ${eval:${lookup{SpamRejectScore}lsearch{/etc/exim/exim4u_global_spam_virus}} * 10} # exim4u: Spam tag text SPAMTAGTEXT = ${lookup{SpamTagText}lsearch{/etc/exim/exim4u_global_spam_virus}} # exim4u: Max scan size for spamassassin MAXSCANSIZE = ${eval:${lookup{MaxScanSize}lsearch{/etc/exim/exim4u_global_spam_virus}}} # exim4u: Spamfolder name SPAMFOLDER = ${lookup{SpamFolder}lsearch{/etc/exim/exim4u_global_spam_virus}} SPAMHEADERTYPE = ${lookup{SpamHeaderType}lsearch{/etc/exim/exim4u_global_spam_virus}} # # exim4u: - Add all host names and IP addressess for the local machine hostlist MY_HOSTs = lsearch;/etc/exim/exim4u_hostnames+hostIPs # # exim4u: - Add hosts to be exempted from SMTP ratelimit checks as follows: hostlist backup_mx_rl_hosts = lsearch;/etc/exim/exim4u_backup_mx_rl_host_names # #exim4u: - Add hosts to be exempted from most all spam checks except recipient verify as follows: hostlist backup_mx_hosts = lsearch;/etc/exim/exim4u_backup_mx_host_names # # This setting specifies hosts that can use our host as an outgoing relay # to any other host on the Internet. Such a setting commonly refers to a # complete local network as well as the localhost. For example: # hostlist relay_from_hosts = 127.0.0.1 : 192.168.0.0/16 hostlist relay_from_hosts = net-iplsearch;/etc/exim/exim4u_relay_from_hosts # # exim4u: Skip sender verify checks for these hosts: hostlist skip_sender_verify_hosts = net-iplsearch;/etc/exim/exim4u_IPskip_sender_verify # # exim4u: Blacklist and Whitelist IP addresses here: hostlist IPblacklist = net-iplsearch;/etc/exim/exim4u_IPblacklist hostlist IPwhitelist = +MY_HOSTs : localhost : net-iplsearch;/etc/exim/exim4u_IPwhitelist # # exim4u: Setup MySQL. # exim4u: Define Virtual, relay and alias domains: VIRTUAL_DOMAINS = SELECT DISTINCT domain FROM domains WHERE type = 'local' AND enabled = '1' AND domain = '${quote_mysql:$domain}' RELAY_DOMAINS = SELECT DISTINCT domain FROM domains WHERE type = 'relay' AND domain = '${quote_mysql:$domain}' ALIAS_DOMAINS = SELECT DISTINCT alias FROM domainalias WHERE alias = '${quote_mysql:$domain}' # exim4u: Setup the list of local domains (local_domains). domainlist local_domains = @ : ${lookup mysql{VIRTUAL_DOMAINS}} : ${lookup mysql{ALIAS_DOMAINS}} # exim4u: Setup the list of destination domains for which we are an mx relay. domainlist relay_to_domains = ${lookup mysql{RELAY_DOMAINS}} # # exim4u: Uncomment the following line for DKIM to only verify mail that is signed. # BTW, this is the exim default setup if dkim_verify_signers is not specified: dkim_verify_signers = $dkim_signers # #trusted_users = trusteduser1:trusteduser2 #trusted_users = exim:apache # The name of the ACLs are defined here: acl_smtp_rcpt = acl_check_rcpt acl_smtp_data = acl_check_content acl_smtp_connect = acl_connect acl_smtp_notquit = acl_notquit acl_smtp_mime = acl_check_mime acl_smtp_mail = acl_check_mail acl_smtp_dkim = acl_check_dkim # Specify the domain you want to be added to all unqualified addresses # here. An unqualified address is one that does not contain an "@" character # followed by a domain. For example, "caesar@rome.example" is a fully qualified # address, but the string "caesar" (i.e. just a login name) is an unqualified # email address. Unqualified addresses are accepted only from local callers by # default. See the recipient_unqualified_hosts option if you want to permit # unqualified addresses from remote sources. If this option is not set, the # primary_hostname value is used for qualification. # qualify_domain = # If you want unqualified recipient addresses to be qualified with a different # domain to unqualified sender addresses, specify the recipient domain here. # If this option is not set, the qualify_domain value is used. # qualify_recipient = # The following line must be uncommented if you want Exim to recognize # addresses of the form "user@[10.11.12.13]" that is, with a "domain literal" # (an IP address) instead of a named domain. The RFCs still require this form, # but it makes little sense to permit mail to be sent to specific hosts by # their IP address in the modern Internet. This ancient format has been used # by those seeking to abuse hosts by using them for unwanted relaying. If you # really do want to support domain literals, uncomment the following line, and # see also the "domain_literal" router below. # allow_domain_literals # No deliveries will ever be run under the uids of these users (a colon- # separated list). An attempt to do so causes a panic error to be logged, and # the delivery to be deferred. This is a paranoic safety catch. Note that the # default setting means you cannot deliver mail addressed to root as if it # were a normal user. This isn't usually a problem, as most sites have an alias # for root that redirects such mail to a human administrator. never_users = root # The setting below causes Exim to do a reverse DNS lookup on all incoming # IP calls, in order to get the true host name. If you feel this is too # expensive, you can specify the networks for which a lookup is done, or # remove the setting entirely. host_lookup = * # By default, Exim expects all envelope addresses to be fully qualified, that # is, they must contain both a local part and a domain. If you want to accept # unqualified addresses (just a local part) from certain hosts, you can specify # these hosts by setting one or both of # # sender_unqualified_hosts = # recipient_unqualified_hosts = # # to control sender and recipient addresses, respectively. When this is done, # unqualified addresses are qualified using the settings of qualify_domain # and/or qualify_recipient (see above). # If you want Exim to support the "percent hack" for certain domains, # uncomment the following line and provide a list of domains. The "percent # hack" is the feature by which mail addressed to x%y@z (where z is one of # the domains listed) is locally rerouted to x@y and sent on. If z is not one # of the "percent hack" domains, x%y is treated as an ordinary local part. This # hack is rarely needed nowadays; you should not enable it unless you are sure # that you really need it. # # percent_hack_domains = # # As well as setting this option you will also need to remove the test # for local parts containing % in the ACL definition below. # When Exim can neither deliver a message nor return it to sender, it "freezes" # the delivery error message (aka "bounce message"). There are also other # circumstances in which messages get frozen. They will stay on the queue for # ever unless one of the following options is set. # This option unfreezes frozen bounce messages after two days, tries # once more to deliver them, and ignores any delivery failures. ignore_bounce_errors_after = 3d # This option cancels (removes) frozen messages that are older than a week. timeout_frozen_after = 7d # We also want a little more detail in our logs, helps with debugging log_selector = +subject # exim4u: Values to modify to fix "Connection Refused: Too Many Connections" #smtp_accept_keepalive = true smtp_accept_max = 400 smtp_accept_max_per_host = 9 #smtp_accept_queue = 200 #smtp_connect_backlog = 125 #smtp_receive_timeout = 10m smtp_receive_timeout = 3m message_size_limit = 50M # exim4u: I am going to just cancel all delay warnings with: #delay_warning = 0h # exim4u: Setup Perl Startup for SURBL/URIBL Scan Checks perl_startup = do '/etc/exim/exim.pl/exim_surbl.pl' perl_at_start = true message_body_visible = 5000 message_body_newlines = true ###################################################################### # ACL CONFIGURATION # # Specifies access control lists for incoming SMTP mail # ###################################################################### begin acl # SPF checks are here. ACL declerations and final accept declerations are included therein # This is a totally self contained ACL routine. .include /etc/exim/exim-acl-check-spf.conf.inc acl_connect: # Accept if the source is local SMTP (i.e. not over TCP/IP). We do this by # testing for an empty sending host field. accept hosts = : # exim4u: IP Whitelist accept hosts = +IPwhitelist # exim4u: Spammer IP Address Blacklist drop hosts = +IPblacklist message = Blacklisted log_message = Host Is Banned by IPblacklist # exim4u: Backup MX hosts and hosts for which we are an outgoing relay. accept hosts = +backup_mx_hosts : +relay_from_hosts : +backup_mx_rl_hosts # exim4u: Ratelimit mod # Rate limit port 25 only and allow other ports without ratelimit. accept condition = ${if eq {$interface_port}{25}{no}{yes}} defer message = Host has been ratelimited. You may try again at a later time. log_message = "Host has been ratelimited ($sender_rate/$sender_rate_period max:$sender_rate_limit)" ratelimit = 1.0 / 2h / strict / per_conn / noupdate accept acl_notquit: # accept authenticated hosts accept authenticated = * # exim4u: IP Whitelist accept hosts = +IPwhitelist # exim4u: Backup MX hosts and hosts for which we are outgoing relays accept hosts = +backup_mx_hosts : +relay_from_hosts : +backup_mx_rl_hosts # exim4u: Ratelimit mod # Rate limit port 25 only and allow other ports without ratelimit. accept condition = ${if eq {$interface_port}{25}{no}{yes}} warn condition = ${if match {$smtp_notquit_reason}{command}{yes}{no}} log_message = "Ratelimit incremented for notquit: $sender_fullhost: $smtp_notquit_reason ($sender_rate/$sender_rate_period max:$sender_rate_limit)" ratelimit = 1.0 / 2h / strict / per_conn accept acl_check_mail: # accept authenticated hosts accept authenticated = * # exim4u: IP Whitelist accept hosts = +IPwhitelist # Accept From Local SMTP. accept hosts = : # exim4u: Backup MX hosts and hosts for which we are outgoing relays accept hosts = +backup_mx_hosts : +relay_from_hosts : +backup_mx_rl_hosts # Hosts are required to say HELO (or EHLO) before sending mail. # So don't allow them to use the MAIL command if they haven't # done so. deny condition = ${if eq{$sender_helo_name}{} {1}} message = HELO error: Polite folks say HELO first! # The following was moved from the acl_smtp_helo ACL so that the HELO arguments # are checked after authenticated users are accepted. The acl_smtp_helo ACL # was subsequently deleted. # Drop all messages where the HELO argument is our local host name or IP address drop condition = ${lookup {$sender_helo_name} lsearch{/etc/exim/exim4u_hostnames+hostIPs} {yes}{no}} message = "HELO error: Dropped spammer pretending to be us" # Drop all other connections where HELO is an IP address drop condition = ${if match{$sender_helo_name}{^[0-9]\.[0-9]\.[0-9]\.[0-9]}{yes}{no} } message = "HELO error: Dropped IP-only or IP-starting helo" accept # exim4u: greylisting mod # Use the lack of reverse DNS to trigger greylisting. Some people # even reject for it but that would be a little excessive. warn condition = ${if eq{$sender_host_name}{} {1}} set acl_m_greylistreasons = Host $sender_host_address lacks reverse DNS\n $acl_m_greylistreasons accept acl_check_rcpt: # exim4u: Set the interface value for the SMPT transport for multi IPs. # First, if the mail is outgoing for a sender in a local domain then set the interface to the value defined by the user # in the web interface for the local domain. warn condition = ${if and {{eq{MULTI_IP}{YES}}\ {eq{${lookup mysql{select domains.type from domains where domain = '$sender_address_domain' AND enabled = '1'}}}{local}}}} set acl_m_interface = ${lookup mysql{select domains.outgoing_ip from domains where domains.domain = '$sender_address_domain'}} set acl_m_helo_data = ${lookup dnsdb{ptr=$acl_m_interface}} set acl_m_interface_opt = outgoing on set acl_m_flag = yes # Second, if the mail is incoming for a sender not in a local domain then set the interface to $smtp_active_hostname. warn condition = ${if and {{eq{MULTI_IP}{YES}}\ {!eq{${lookup mysql{select domains.type from domains where domain = '$sender_address_domain' AND enabled = '1'}}}{local}}}} # set acl_m_interface = ${lookup dnsdb{a=$smtp_active_hostname}} set acl_m_interface = MY_IP set acl_m_helo_data = $smtp_active_hostname set acl_m_interface_opt = incoming on set acl_m_flag = yes # exim4u: If not multi IP then set the interface warn condition = ${if !eq {MULTI_IP}{YES}} # set acl_m_interface = ${lookup dnsdb{a=$smtp_active_hostname}} set acl_m_interface = MY_IP set acl_m_helo_data = $smtp_active_hostname set acl_m_interface_opt = primary on set acl_m_flag = yes .include /etc/exim/exim4u_local_rl.conf.inc # exim4u: Accept authenticated so that spam header is not added to outgoing mail accept authenticated = * # Accept if the source is local SMTP (i.e. not over TCP/IP). We do this by # testing for an empty sending host field. accept hosts = : # exim4u: IP Whitelist accept hosts = +IPwhitelist # Accept if the message comes from one of the hosts for which we are an # outgoing relay. We must trust these hosts anyway since we listed them. # Recipient verification is omitted here, because in many # cases the clients are dumb MUAs that don't cope well with SMTP error # responses. If you are actually relaying out from MTAs, you should probably # add recipient verification here. accept hosts = +relay_from_hosts # Deny if the local part contains @ or % or / or | or !. These are rarely # found in genuine local parts, but are often tried by people looking to # circumvent relaying restrictions. # Also deny if the local part starts with a dot. Empty components aren't # strictly legal in RFC 2822, but Exim allows them because this is common. # However, actually starting with a dot may cause trouble if the local part # is used as a file name (e.g. for a mailing list). deny local_parts = ^.*[@%!/|] : ^\\. log_message = Local content not permitted # Insist that any other recipient address that we accept is either in one of # our local domains, or is in a domain for which we explicitly allow # relaying. Any other domain is rejected as being unacceptable for relaying. require message = relay not permitted domains = +local_domains : +relay_to_domains # exim4u: Recipient check for all mail relayed by backup mx hosts. This is for # supporting recipient callouts that originate from the backup mx hosts. deny hosts = +backup_mx_hosts !verify = recipient/defer_ok/callout=10s # exim4u: Accept if comming from a mx relay host accept hosts = +backup_mx_hosts # Deny unless the sender address can be routed. That is, the senders domain must exist # and have an MX record. This also verifies senders local part if sender domain is # also local. This is for relay hosts that are exempt from ratelimiting. # This was inserted here so sender verification could be done after dictionary attack # detection for mail that isn't from a relay while also doing sender verification # for mail from relays that are exempt from ratelimiting. deny hosts = +backup_mx_rl_hosts !verify = sender log_message = Cannot verify sender domain. # exim4u: Bypass rate limit checks. # Accept if comming from a mx relay host that is exempt from rate limiting. accept hosts = +backup_mx_rl_hosts # exim4u: Mod For Greylisting. # This does DNS lookups for SRV records. The CSA proposal is currently (May 2005) # an Internet draft. warn !verify = csa set acl_m_greylistreasons = Host failed CSA check\n $acl_m_greylistreasons # exim4u: increment ratelimit rate with dictionary attack detection. drop log_message = Dictionary Attack Rejected (Began blocking after $rcpt_fail_count recipients failed). Ratelimit incremented. condition = ${if > {${eval:$rcpt_fail_count}}{3}{yes}{no}} ratelimit = 0 / 2h / strict / per_conn message = Number of failed recipients exceeded. Come back in a few hours. # exim4u: Recipient check for all local recipients and all recipients relayed to relay_to_domains. require verify = recipient/defer_ok/callout=10s # Deny unless the sender address can be routed. That is, the senders domain must exist # and have an MX record. This also verifies senders local part if sender domain is # also local. This is for all local recipients and all recipients relayed to # relay_to_domains. deny !verify = sender log_message = Cannot verify sender domain. # exim4u: increment ratelimit rate with RBL detection and rejection. drop # dnslists = zen.spamhaus.org:bl.spamcop.net:psbl.surriel.com dnslists = zen.spamhaus.org:bl.spamcop.net # dnslists = zen.spamhaus.org log_message = Spammer rejected. DNSBL listed at $dnslist_domain at $dnslist_text. Ratelimit incremented. ratelimit = 0 / 2h / strict / per_conn message = Spammer rejected. DNSBL listed at $dnslist_domain at $dnslist_text. # exim4u: SPF check of sender address deny condition = ${if eq {${lookup mysql{select count(*) from domains \ where domain = '${quote_mysql:$domain}' \ and spamassassin='1'}}}{1} {yes}{no}} !acl = spf_rcpt_acl message = Your rcpt is not permitted (SPF - read spf.pobox.com) log_message = Sender address not permitted - SPF. # Accept if this mail is not relayed by backup mx host and # if the address is in a local domain, but only if the recipient can # be verified. Otherwise deny. The "endpass" line is the border between # passing on to the next ACL statement (if tests above it fail) or denying # access (if tests below it fail). accept domains = +local_domains endpass verify = recipient # Accept if this mail is not relayed by backup mx host and # the address is in a domain for which we are relaying, but again, # only if the recipient can be verified. accept domains = +relay_to_domains endpass verify = recipient # If control reaches this point, the domain is neither in +local_domains # nor in +relay_to_domains. # Reaching the end of the ACL causes a "deny", but we might as well give # an explicit message. deny message = relay not permitted # exim4u: DKIM ACL included from external file. .include /etc/exim/exim4u_acl_check_dkim.conf.inc acl_check_mime: # accept authenticated hosts accept authenticated = * # exim4u: IP Whitelist accept hosts = +IPwhitelist : +backup_mx_hosts : +relay_from_hosts # Accept From Local SMTP. accept hosts = : # File extension filtering. Reject typically wormish file extensions. deny message = Blacklisted file extension detected log_message = File extension rejected. condition = ${if match \ {${lc:$mime_filename}} \ {\N(\.exe|\.pif|\.bat|\.scr|\.lnk|\.com|\.vbs|\.vbe|\.bz2|\.cmd|\.js|\.reg|\.chm|\.cnf|\.hta|\.ins|\.scf|\.sct|\.wsc|\.wsf|\.wsh|\.xnk|\.mad|\.maf|\.mag|\.mam|\.maq|\.mar|\.mas|\.mat|\.mat|\.mav|\.maw)$\N} \ {1}{0}} # exim4u: SURBL/URIBL URL Check for blacklisted URL links embeded in mail. # Perl Script Scans 100K of Message deny condition = ${if <{$message_size}{100000}{yes}{no}} set acl_m0 = ${perl{surblspamcheck}} condition = ${if eq{$acl_m0}{false}{no}{yes}} message = $acl_m0 # ratelimit = 0 / 2h / strict / per_conn accept acl_check_content: # Unpack MIME containers and reject serious errors. deny message = This message contains a MIME error ($demime_reason) demime = * condition = ${if >{$demime_errorlevel}{2}{1}{0}} hosts = ! +IPwhitelist !hosts = : !authenticated = * # Reject virus infested messages. # exim4u: Mod to reject malware at SMTP time instead of sending rejection email in the ditch_malware router. # Run ClamAV if CLAMENABLED is on. # exim4u: Add ClamAV header to mail. The variables $acl_m_interface_opt, $acl_m_helo_data and $acl_m_interface # are included in the header to confirm MULTI_IP interface info. warn condition = ${if eq{CLAMENABLED}{on}{yes}{no}} add_header = X-Scanned-By: ${extract{1}{/}{${readsocket{inet:localhost:3310}{VERSION}{1s}{} {unscanned}}}} \ $acl_m_interface_opt $acl_m_helo_data ($acl_m_interface); $tod_full\n # Reject if ClamAV detects malware deny condition = ${if eq{CLAMENABLED}{on}{yes}{no}} message = This message contains malware ($malware_name) malware = * log_message = This message contains malware ($malware_name) # Set variables up for router to use for acl_m_bu_mxhost value . warn set acl_m_bu_mxhost = 0 # Set variables up for router to use for mail relayed by backup_mx_hosts warn hosts = +backup_mx_hosts set acl_m_spamscore = ${eval10:${extract{-1}{\n}{$h_X-Spam-Score-Integer:}}+0} set acl_m_bu_mxhost = 1 log_message = ACL Spamscore: $acl_m_spamscore computed from backup MX hosts Spam Score Integer: $h_X-Spam-Score-Integer # # exim4u: IP Whitelist accept hosts = +IPwhitelist : +backup_mx_hosts : +relay_from_hosts # # exim4u: MOD - accept authenticated Mail After Malware check but before spam check. accept authenticated = * # # Accept if the source is local SMTP (i.e. not over TCP/IP). We do this by # testing for an empty sending host field. accept hosts = : # exim4u: SPF check of Envelope From address - Enable at risk of fales positives. # deny hosts = ! +relay_from_hosts : ! +backup_mx_hosts # !acl = spf_from_acl # message = Your sender is not permitted (SPF - read spf.pobox.com) # log_message = From address not permitted - SPF. # hosts = ! +IPwhitelist # !hosts = : # !authenticated = * # # exim4u: SURBL/URIBL URL Check for blacklisted URL links embeded in mail. # This only checks non-mime emails via the second condition statement # Perl Script Scans 100K of Message deny condition = ${if <{$message_size}{100000}{yes}{no}} condition = ${if eq{$acl_m0}{}{yes}{no}} set acl_m1 = ${perl{surblspamcheck}} condition = ${if eq{$acl_m1}{false}{no}{yes}} message = $acl_m1 # ratelimit = 0 / 2h / strict / per_conn # # exim4u: Mod For Greylisting. Check for the presence of a # Message-Id: header, which RFC2822 says SHOULD be present. Some broken # or misconfigured mailer software occasionally omits this from genuine # messages too, though -- although it's not hard for the offender to fix # after they receive a bounce because of it. warn condition = ${if !def:h_Message-ID: {1}} set acl_m_greylistreasons = Message lacks Message-Id: header. Consult RFC2822.\n $acl_m_greylistreasons # # # Reject messages containing "viagra" in all kinds of whitespace/case combinations # WARNING: this is an example ! # deny message = This message matches a blacklisted regular expression ($regex_match_string) # regex = [Vv] *[Ii] *[Aa] *[Gg] *[Rr] *[Aa] # # # # Spamassassin Processing # # Generate log message if spamassassin is disabled globally warn condition = ${if >= {SPAMREJECT}{1000}} log_message = Spamassassin is disabled globally. # # exim4u:Accept if spamassassin is disabled globally accept condition = ${if >= {SPAMREJECT}{1000}} # #exim4u: Mod to not scan messages over 50K in size warn log_message = Skipping spam scan; message too large message = X-Spam-Report: Spam scan skipped;message too large condition = ${if >{$message_size}{MAXSCANSIZE}} add_header = X-Spam-Status: Spamassassin scan skipped. Max message size exceeded. accept condition = ${if >{$message_size}{MAXSCANSIZE}} # exim4u: Always add X-Spam-Score and X-Spam-Report headers if spamassassin is enabled globally using SA system-wide settings warn spam = spamd:true add_header = X-Spam-Score: $spam_score ($spam_bar) add_header = X-Spam-Report: $spam_report log_message = spam-score-int: $spam_score_int ($spam_bar). spamreject: SPAMREJECT. # # exim4u: MOD to reject all spam with a score over SpamRejectScore value at SMTP time instead of sending rejection # email in the ditch_malware router. deny message = This message is rejected as spam. spam = spamd condition = ${if >={$spam_score_int}{SPAMREJECT}} # ratelimit = 0 / 2h / strict / per_conn log_message = This message is rejected as spam. X-Spam-Score: $spam_score ($spam_bar). Ratelimit incremented. # exim4u: Compute acl_m_spamscore value for total spam score based on spam_score_int, large ISP host verification failure # and sender callout failure. Here we set the initial value of acl_m_spamscore warn set acl_m_spamscore = $spam_score_int # exim4u: Verify sender hosts for selected large ISPs: hotmail.com, aol.com, msn.com, yahoo.com and gmail.com. # Add a spamscore penalty of 25 if verification fails. warn senders = *@hotmail.com condition = ${if match {$sender_host_name} {\Nhotmail.com$\N}{no}{yes}} hosts =! +skip_sender_verify_hosts set acl_m_spamscore = ${eval:$acl_m_spamscore + 25} add_header = X-Faked-hotmail.com-Addr: YES log_message = Faked hotmail.com addr. X-Spam-Score-Integer: $acl_m_spamscore. warn senders = *@aol.com condition = ${if match {$sender_host_name} {\Naol.com$\N}{no}{yes}} hosts =! +skip_sender_verify_hosts set acl_m_spamscore = ${eval:$acl_m_spamscore + 25} add_header = X-Faked-aol.com-Addr: YES log_message = Faked aol.com addr. X-Spam-Score-Integer: $acl_m_spamscore. warn senders = *@msn.com # condition = ${if match {$sender_host_name} {\Nmsn.com$\N}{no}{yes}} condition = ${if match {$sender_host_name} {\Nhotmail.com$\N}{no}{yes}} hosts =! +skip_sender_verify_hosts set acl_m_spamscore = ${eval:$acl_m_spamscore + 25} add_header = X-Faked-msn.com-Addr: YES log_message = Faked msn.com addr. X-Spam-Score-Integer: $acl_m_spamscore. warn senders = *@yahoo.com condition = ${if match {$sender_host_name} {\Nyahoo.com$\N}{no}{yes}} hosts =! +skip_sender_verify_hosts set acl_m_spamscore = ${eval:$acl_m_spamscore + 25} add_header = X-Faked-yahoo.com-Addr: YES log_message = Faked yahoo.com addr. X-Spam-Score-Integer: $acl_m_spamscore. warn senders = *@gmail.com condition = ${if match {$sender_host_name} {\Ngoogle.com$\N}{no}{yes}} hosts =! +skip_sender_verify_hosts set acl_m_spamscore = ${eval:$acl_m_spamscore + 25} add_header = X-Faked-gmail.com-Addr: YES log_message = Faked gmail.com addr. X-Spam-Score-Integer: $acl_m_spamscore. # exim4u:Perform sender address callouts only for spammy mail (if spamscore >=0). # Add a spamscore penalty of 25 for sender callout failure. warn hosts =! +skip_sender_verify_hosts condition = ${if >={$acl_m_spamscore}{0}} !verify = sender/defer_ok/callout=15s set acl_m_spamscore = ${eval:$acl_m_spamscore + 25} add_header = X-Sender-Verify-Fail: YES log_message = Sender verify callout failed. X-Spam-Score-Integer: $acl_m_spamscore. # exim4u: Deny if acl_m_spamscore >= SpamRejectScore value deny condition = ${if >= {$acl_m_spamscore} {SPAMREJECT}} # ratelimit = 0 / 2h / strict / per_conn log_message = This message is rejected as SPAM. X-Spam-Score: $spam_score ($spam_bar). X-acl_m_spamscore-integer: $acl_m_spamscore. message = This message is rejected as spam. # exim4u: MOD For Greylisting: Trigger greylisting (if enabled) if the SpamAssassin score is greater than 0.0 # Default is score > 0.5 where the statement would be: condition = ${if >{$spam_score_int}{5} {1}} # # exim4u: MOD to greylisting to use $acl_m_spamscore instead of $spam_score_int # warn condition = ${if >{$spam_score_int}{0} {1}} # set acl_m_greylistreasons = Message has $spam_score SpamAssassin points\n$acl_m_greylistreasons warn condition = ${if >{$acl_m_spamscore}{0} {1}} set acl_m_greylistreasons = Message has $acl_m_spamscore integer spamscore points\n $acl_m_greylistreasons # If you want to greylist _all_ mail rather than only mail which looks like there # might be something wrong with it, then you can do this... # # warn set acl_m_greylistreasons = We greylist all mail\n$acl_m_greylistreasons # exim4u: Mod For Greylisting # Now, invoke the greylisting. For this you need to have installed the exim-greylist # package which contains this subroutine, and you need to uncomment the bit below # which includes it too. Whenever the $acl_m_greylistreasons variable is non-empty, # greylisting will kick in and will defer the mail to check if the sender is a # proper mail which which retries, or whether it's a zombie. For more details, see # the exim-greylist.conf file itself. # require acl = greylist_mail # accept hosts = 127.0.0.1:+relay_from_hosts: +backup_mx_hosts # # add spamscore_integer header warn add_header = X-Spam-Score-Integer: $acl_m_spamscore # # finally accept all the rest accept # exim4u: Mod For Greylisting # To enable the greylisting, uncomment this line: .include /etc/exim/exim-greylist.conf.inc ###################################################################### # ROUTERS CONFIGURATION # # Specifies how addresses are handled # ###################################################################### # THE ORDER IN WHICH THE ROUTERS ARE DEFINED IS IMPORTANT! # # An address is passed to each router in turn until it is accepted. # ###################################################################### # # exim4u commented out all instances of "local_part_suffix = -*" and # "local_part_suffix_optional" in all of the routers so that hyphens # will work in the local parts of mail addresses. # Example done in all routers: # # local_part_suffix = -* # # local_part_suffix_optional # begin routers # This router routes to remote hosts over SMTP by explicit IP address, # when an email address is given in "domain literal" form, for example, # . The RFCs require this facility. However, it is # little-known these days, and has been exploited by evil people seeking # to abuse SMTP relays. Consequently it is commented out in the default # configuration. If you uncomment this router, you also need to uncomment # allow_domain_literals above, so that Exim can recognize the syntax of # domain literal addresses. # domain_literal: # driver = ipliteral # domains = ! +local_domains # transport = remote_smtp # # exim4u: Ditch spam for relay_MX_direct ditch_spam_for_relay_MX_direct: driver = redirect allow_fail data = :blackhole: condition = ${if >={$acl_m_spamscore}{${lookup mysql{select domains.sa_refuse * 10 from domains \ where domain = '${quote_mysql:$domain}' \ and domains.type = 'relay' \ and domains.spamassassin = '1' \ and domains.sa_refuse > 0 }{$value}fail}} {yes}{no}} # exim4u: This router routes to MX relay hosts when spamassassin is disabled globally relay_MX_direct_SA_off: condition = ${if and {{eq{SPAMREJECT}{1000}} {eq{${lookup mysql{select domains.type from domains where domain = '${quote_mysql:$domain}'}}}{relay}}}} driver = manualroute domains = ! +local_domains # transport = remote_smtp transport = ${if eq{MULTI_IP}{YES}{remote_smtp_multi_IP}{remote_smtp}} route_data = ${lookup mysql{select domains.relay_address from domains where domain = '${quote_mysql:$domain}'}} no_more # exim4u: This router routes to MX relay hosts after spam processing if spam tagging is turned off # via the tag score being set greater than the refuse score. relay_MX_direct_no_header_mod: driver = manualroute domains = ! +local_domains # transport = remote_smtp transport = ${if eq{MULTI_IP}{YES}{remote_smtp_multi_IP}{remote_smtp}} condition = ${if and {{eq {${lookup mysql{select domains.type from domains where domain = '${quote_mysql:$domain}'}}}{relay}} \ {>{${lookup mysql{select domains.sa_tag from domains where domain = '${quote_mysql:$domain}'}}} \ {${lookup mysql{select domains.sa_refuse from domains where domain = '${quote_mysql:$domain}'}}} } } } route_data = ${lookup mysql{select domains.relay_address from domains where domain = '${quote_mysql:$domain}'}} no_more # exim4u: This router routes to MX relay hosts after spam processing if spam tagging is turned on # via the tag score being set less than or equal to the refuse score. relay_MX_direct_header_mod: driver = manualroute domains = ! +local_domains # transport = remote_smtp transport = ${if eq{MULTI_IP}{YES}{remote_smtp_multi_IP}{remote_smtp}} condition = ${if eq {${lookup mysql{select domains.type from domains where domain = '${quote_mysql:$domain}'}}}{relay}} route_data = ${lookup mysql{select domains.relay_address from domains where domain = '${quote_mysql:$domain}'}} # exim4u Added this for spam processing for relay domains. # exim4u header_remove to remove subject if spam. headers_remove = ${if >={$acl_m_spamscore}{${lookup mysql{select domains.sa_tag * 10 from domains \ where domain = '${quote_mysql::$domain}' \ and domains.spamassassin = '1'}}} \ {Subject} \ } # exim4u header_add to add X-Spam-Flag for all mail and rewrite Subject if spam. headers_add = ${if >={$acl_m_spamscore}{${lookup mysql{select domains.sa_tag * 10 from domains \ where domain = '${quote_mysql:$domain}' \ and domains.spamassassin = '1'}}} \ {X-Spam-Flag: YES\nSubject: [SPAMTAGTEXT] $h_Subject:\n}{X-Spam-Flag: NO\n}\ } no_more # exim4u: This router relays local and authenticated smtp mail. dnslookup: driver = dnslookup domains = ! +local_domains # transport = remote_smtp # transport = ${if eq{MULTI_IP}{YES}{remote_smtp_multi_IP}{remote_smtp}} transport = ${if and {{eq{MULTI_IP}{YES}}{eq{DKIM_ON}{YES}}}{remote_smtp_multi_IP_DK}\ {${if and {{eq{MULTI_IP}{YES}}{eq{DKIM_ON}{NO}}}{remote_smtp_multi_IP}\ {${if and {{eq{MULTI_IP}{NO}}{eq{DKIM_ON}{YES}}}{remote_smtp_DK}\ {remote_smtp}}}}}} ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 no_more ditch_maxmsgsize: driver = redirect allow_fail condition = ${if >{$message_size}{${lookup mysql{select users.maxmsgsize from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.maxmsgsize > 0 \ and users.domain_id=domains.domain_id }{${value}K}fail}} {yes}{no}} data = :fail:\n\Your message is too big.\n \ Your message was rejected because the user $local_part@$domain\n \ does not accept messages larger than \ ${lookup mysql{select users.maxmsgsize from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.maxmsgsize > 0 \ and users.domain_id=domains.domain_id}{${value}K}fail} Kb. # local_part_suffix = -* # local_part_suffix_optional retry_use_local_part ditch_spam: driver = redirect allow_fail data = :blackhole: condition = ${if >={$acl_m_spamscore}{${lookup mysql{select users.sa_refuse * 10 from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.on_spamassassin = '1' \ and users.domain_id=domains.domain_id \ and users.sa_refuse > 0 }{$value}fail}} {yes}{no}} # local_part_suffix = -* # local_part_suffix_optional retry_use_local_part ditch_hdrmailer: driver = redirect allow_fail data = :blackhole: condition = ${if eq {${lookup mysql{select count(*) from blocklists,users,domains \ where blocklists.blockhdr = 'x-mailer' \ and blocklists.blockval = '${quote_mysql:$h_x-mailer:}' \ and users.localpart = '${quote_mysql:$local_part}' \ and domains.domain = '${quote_mysql:$domain}' \ and domains.domain_id=blocklists.domain_id \ and users.user_id=blocklists.user_id}}}{1} {yes}{no}} # local_part_suffix = -* # local_part_suffix_optional retry_use_local_part ditch_hdrto: driver = redirect allow_fail data = :blackhole: condition = ${if eq {${lookup mysql{select count(*) from blocklists,users,domains \ where blocklists.blockhdr = 'to' \ and blocklists.blockval = '${quote_mysql:$h_to:}' \ and users.localpart = '${quote_mysql:$local_part}' \ and domains.domain = '${quote_mysql:$domain}' \ and domains.domain_id=blocklists.domain_id \ and users.user_id=blocklists.user_id}}}{1} {yes}{no}} # local_part_suffix = -* # local_part_suffix_optional retry_use_local_part ditch_hdrfrom: driver = redirect allow_fail data = :blackhole: condition = ${if eq {${lookup mysql{select count(*) from blocklists,users,domains \ where blocklists.blockhdr = 'from' \ and blocklists.blockval = '${quote_mysql:$h_from:}' \ and users.localpart = '${quote_mysql:$local_part}' \ and domains.domain = '${quote_mysql:$domain}' \ and domains.domain_id=blocklists.domain_id \ and users.user_id=blocklists.user_id}}}{1} {yes}{no}} # local_part_suffix = -* # local_part_suffix_optional retry_use_local_part ditch_hdrsubject: driver = redirect allow_fail data = :blackhole: condition = ${if eq {${lookup mysql{select count(*) from blocklists,users,domains \ where blocklists.blockhdr = 'subject' \ and blocklists.blockval = '${quote_mysql:$h_subject:}' \ and users.localpart = '${quote_mysql:$local_part}' \ and domains.domain = '${quote_mysql:$domain}' \ and domains.domain_id=blocklists.domain_id \ and users.user_id=blocklists.user_id}}}{1} {yes}{no}} # local_part_suffix = -* # local_part_suffix_optional retry_use_local_part virtual_vacation: driver = accept condition = ${if and { {!match {$h_precedence:}{(?i)junk|bulk|list}} \ {eq {${lookup mysql{select users.on_vacation from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.on_vacation = '1' \ and users.domain_id=domains.domain_id}}}{1} }} {yes}{no} } no_verify no_expn unseen transport = virtual_vacation_delivery virtual_forward: driver = redirect check_ancestor unseen = ${if eq {${lookup mysql{select unseen from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.on_forward = '1' \ and users.domain_id=domains.domain_id}}}{1} {yes}{no}} data = ${lookup mysql{select forward from users,domains \ where localpart='${quote_mysql:$local_part}' \ and domain='${quote_mysql:$domain}' \ and users.domain_id=domains.domain_id \ and on_forward = '1'}} # We explicitly make this condition NOT forward mailing list mail! condition = ${if and { {!match {$h_precedence:}{(?i)junk}} \ {eq {${lookup mysql{select users.on_forward from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.on_forward = '1' \ and users.domain_id=domains.domain_id}}}{1} }} {yes}{no} } # exim4u: This router routes to virtual domains when spamassassin is disabled globally and # mail was not processed with spamassassin by a backup mx server. virtual_domains_SA_off: condition = ${if and {{>= {SPAMREJECT}{1000}} {={$acl_m_bu_mxhost}{0}}}} driver = redirect allow_fail data = ${lookup mysql{select smtp from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and domains.enabled = '1' \ and users.enabled = '1' \ and users.domain_id = domains.domain_id}} # local_part_suffix = -* # local_part_suffix_optional retry_use_local_part file_transport = virtual_delivery reply_transport = address_reply pipe_transport = address_pipe # exim4u: Route mail that is tagged as spam by spamassassin to the spam boxes. virtual_spam_boxes: driver = redirect allow_fail data = ${lookup mysql{select concat(smtp,'/','SPAMFOLDER') \ from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and domains.enabled = '1' \ and users.enabled = '1' \ and users.domain_id = domains.domain_id}} condition = ${if and {{<{SPAMREJECT}{1000}} {>={$acl_m_spamscore}{${lookup mysql{select \ users.sa_tag * 10 from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.on_spamassassin = '1' \ and users.on_forward = '0' \ and users.type = 'local' \ and users.domain_id=domains.domain_id \ and users.sa_refuse > 0 \ and users.on_spambox = 1 \ }{$value}fail}}}}} # exim4u header_remove to remove subject headers_remove = Subject # exim4u header_add to add X-Spam-Flag for all mail and rewrite Subject if spam. headers_add = X-Spam-Flag: YES\nSubject: [SPAMTAGTEXT] $h_Subject:\n # local_part_suffix = -* # local_part_suffix_optional retry_use_local_part file_transport = virtual_spam_box_delivery reply_transport = address_reply pipe_transport = address_pipe # exim4u: This router routes to virtual domains with spamassassin filtering virtual_domains: condition = ${if < {SPAMREJECT}{1000}} driver = redirect allow_fail data = ${lookup mysql{select smtp from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and domains.enabled = '1' \ and users.enabled = '1' \ and users.domain_id = domains.domain_id}} # exim4u header_remove to remove subject if spam or X-Spam-Report if not spam and SPAMHEADERTYPE=0. headers_remove = ${if >={$acl_m_spamscore}{${lookup mysql{select users.sa_tag * 10 from users,domains \ where localpart = '${quote_mysql::$local_part}' \ and domain = '${quote_mysql::$domain}' \ and users.on_spamassassin = '1' \ and users.domain_id=domains.domain_id }{$value}fail}} \ {Subject}{${if eq{SPAMHEADERTYPE}{0}{X-Spam-Report}}} \ } # exim4u header_add to add X-Spam-Flag for all mail and rewrite Subject if spam. headers_add = ${if >={$acl_m_spamscore}{${lookup mysql{select users.sa_tag * 10 from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.on_spamassassin = '1' \ and users.domain_id=domains.domain_id }{$value}fail}} \ {X-Spam-Flag: YES\nSubject: [SPAMTAGTEXT] $h_Subject:\n}{X-Spam-Flag: NO\n}\ } # local_part_suffix = -* # local_part_suffix_optional retry_use_local_part file_transport = virtual_delivery reply_transport = address_reply pipe_transport = address_pipe # exim4u: Move mailman router here with spam filtering # First, apply additional spam filtering to mailman. # ditch_mailman_spam: # driver = redirect # require_files = MAILMAN_HOME/lists/$local_part/config.pck # domains = +mm_domains # allow_fail # data = :blackhole: # condition = ${if >{$acl_m_spamscore}{50}{yes}{no}} # retry_use_local_part # mailman_router: driver = accept require_files = MAILMAN_HOME/lists/$local_part/config.pck domains = +mm_domains local_part_suffix_optional local_part_suffix = -bounces : -bounces+* : \ -confirm+* : -join : -leave : \ -owner : -request : -admin # headers_remove = X-Spam-Score:X-Spam-Report:X-Spam-Flag:X-Spam-Score-Integer headers_remove = ${if eq{SPAMHEADERTYPE}{0}{X-Spam-Score::X-Spam-Report::X-Spam-Flag::X-Spam-Score-Integer}} transport = mailman_transport .include /etc/exim/exim-group-router.conf.inc .include /etc/exim/exim-mailinglist-router.conf.inc virtual_domains_catchall: driver = redirect allow_fail data = ${lookup mysql{select smtp from users,domains where localpart = '*' \ and domain = '${quote_mysql:$domain}' \ and users.domain_id = domains.domain_id}} retry_use_local_part file_transport = virtual_delivery reply_transport = address_reply pipe_transport = address_pipe_catchall virtual_domain_alias: driver = redirect allow_fail data = ${lookup mysql{select concat('${quote_mysql:$local_part}@', domain) \ from domains,domainalias where domainalias.alias = '${quote_mysql:$domain}' \ and domainalias.domain_id = domains.domain_id}} retry_use_local_part # This router handles aliasing using a linearly searched alias file with the # name /etc/aliases. When this configuration is installed automatically, # the name gets inserted into this file from whatever is set in Exim's # build-time configuration. The default path is the traditional /etc/aliases. # If you install this configuration by hand, you need to specify the correct # path in the "data" setting below. # ##### NB You must ensure that the alias file exists. It used to be the case ##### NB that every Unix had that file, because it was the Sendmail default. ##### NB These days, there are systems that don't have it. Your aliases ##### NB file should at least contain an alias for "postmaster". # # If any of your aliases expand to pipes or files, you will need to set # up a user and a group for these deliveries to run under. You can do # this by uncommenting the "user" option below (changing the user name # as appropriate) and adding a "group" option if necessary. Alternatively, you # can specify "user" on the transports that are used. Note that the transports # listed below are the same as are used for .forward files; you might want # to set up different ones for pipe and file deliveries from aliases. system_aliases: driver = redirect allow_fail allow_defer data = ${lookup{$local_part}lsearch{/etc/aliases}} user = LOCAL_USER group = LOCAL_GROUP file_transport = address_file pipe_transport = address_pipe # This router handles forwarding using traditional .forward files in users' # home directories. If you want it also to allow mail filtering when a forward # file starts with the string "# Exim filter", uncomment the "allow_filter" # option. # The no_verify setting means that this router is skipped when Exim is # verifying addresses. Similarly, no_expn means that this router is skipped if # Exim is processing an EXPN command. # The check_ancestor option means that if the forward file generates an # address that is an ancestor of the current one, the current one gets # passed on instead. This covers the case where A is aliased to B and B # has a .forward file pointing to A. # The three transports specified at the end are those that are used when # forwarding generates a direct delivery to a file, or to a pipe, or sets # up an auto-reply, respectively. userforward: driver = redirect check_local_user file = $home/.forward no_verify no_expn check_ancestor # allow_filter file_transport = address_file pipe_transport = address_pipe_local reply_transport = address_reply condition = ${if exists{$home/.forward} {yes} {no} } group = LOCAL_GROUP # This router matches local user mailboxes. If the router fails, the error # message is "Unknown user". localuser: driver = accept check_local_user transport = local_delivery cannot_route_message = No such person at this address ###################################################################### # TRANSPORTS CONFIGURATION # ###################################################################### # ORDER DOES NOT MATTER # # Only one appropriate transport is called for each delivery. # ###################################################################### # A transport is used only when referenced from a router that successfully # handles an address. begin transports # exim4u: SMTP Transport for MULTI_IP == YES and DKIM == NO # This transport is for domains for which we are a relay and/or backup MX host. remote_smtp_multi_IP: driver = smtp interface = ${if eq{$acl_m_flag}{yes}{$acl_m_interface}{MY_IP}} helo_data = ${if eq{$acl_m_flag}{yes}{$acl_m_helo_data}{$smtp_active_hostname}} tls_certificate = ${if eq{$acl_m_flag}{yes}{/etc/pki/tls/exim_tls/exim.$acl_m_interface.cert}{/etc/pki/tls/exim_tls/exim.MY_IP.cert}} tls_privatekey = ${if eq{$acl_m_flag}{yes}{/etc/pki/tls/exim_tls/exim.$acl_m_interface.key}{/etc/pki/tls/exim_tls/exim.MY_IP.key}} # exim4u: SMTP Transport for MULTI_IP == YES and DKIM == YES # This transport is for domains for which we are a relay and/or backup MX host. remote_smtp_multi_IP_DK: driver = smtp interface = ${if eq{$acl_m_flag}{yes}{$acl_m_interface}{MY_IP}} helo_data = ${if eq{$acl_m_flag}{yes}{$acl_m_helo_data}{$smtp_active_hostname}} tls_certificate = ${if eq{$acl_m_flag}{yes}{/etc/pki/tls/exim_tls/exim.$acl_m_interface.cert}{/etc/pki/tls/exim_tls/exim.MY_IP.cert}} tls_privatekey = ${if eq{$acl_m_flag}{yes}{/etc/pki/tls/exim_tls/exim.$acl_m_interface.key}{/etc/pki/tls/exim_tls/exim.MY_IP.key}} dkim_domain = ${sender_address_domain} dkim_selector = exim4u dkim_private_key = "/etc/pki/tls/dk/rsa.private" # exim4u: SMTP Transport for MULTI_IP == NO and DKIM == NO # This transport is for local and authenticated mail sent from local domains. remote_smtp: driver = smtp # exim4u: SMTP Transport for MULTI_IP == NO and DKIM == YES # This transport is for local and authenticated mail sent from local domains. remote_smtp_DK: driver = smtp dkim_domain = ${sender_address_domain} dkim_selector = exim4u dkim_private_key = "/etc/pki/tls/dk/rsa.private" # This transport is used for local delivery to user mailboxes in traditional # BSD mailbox format. By default it will be run under the uid and gid of the # local user, and requires the sticky bit to be set on the /var/mail directory. # Some systems use the alternative approach of running mail deliveries under a # particular group instead of using the sticky bit. The commented options below # show how this can be done. local_delivery: driver = appendfile file = /var/mail/$local_part delivery_date_add envelope_to_add return_path_add group = LOCAL_GROUP user = $local_part mode = 0660 no_mode_fail_narrower #exim4u: Virtual spam box delivery transport. virtual_spam_box_delivery: driver = appendfile envelope_to_add return_path_add mode = 0600 maildir_format = true create_directory = true user = ${lookup mysql{select users.uid from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.domain_id = domains.domain_id}} group = ${lookup mysql{select users.gid from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.domain_id = domains.domain_id}} maildir_use_size_file = false virtual_delivery: driver = appendfile envelope_to_add return_path_add mode = 0600 maildir_format = true create_directory = true directory = ${lookup mysql{select smtp from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.domain_id = domains.domain_id}} user = ${lookup mysql{select users.uid from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.domain_id = domains.domain_id}} group = ${lookup mysql{select users.gid from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.domain_id = domains.domain_id}} quota = ${lookup mysql{select users.quota from users,domains \ where localpart = '${quote_mysql:$local_part}' \ and domain = '${quote_mysql:$domain}' \ and users.domain_id = domains.domain_id}{${value}M}} quota_is_inclusive = false #quota_size_regex = ,S=(\d+): quota_warn_threshold = 80% # exim4u mod to get quota size from the maildirsize file in each user's directory # maildir_use_size_file = false maildir_use_size_file = true quota_warn_message = "To: $local_part@$domain\n\ Subject: Mailbox quota warning\n\n\ This message was automatically generated by the mail delivery software.\n\n\ You are now using over 75% of your allocated mail storage quota.\n\n\ If your mailbox fills completely, further incoming messages will be automatically\n\ returned to their senders.\n\n\ Please take note of this and remove unwanted mail from your mailbox.\n" virtual_vacation_delivery: driver = autoreply once = AR_ONCE_FILE once_repeat = AR_ONCE_REPEAT from = "${local_part}@${domain}" to = ${sender_address} subject = AR_SUBJECT_TXT headers = "Content-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: quoted-printable" text = ${lookup mysql{select vacation from users,domains \ where \ domain='${quote_mysql:$domain}' \ and localpart='${quote_mysql:$local_part}' \ and users.domain_id=domains.domain_id}} mailman_transport: driver = pipe command = MAILMAN_WRAP \ '${if def:local_part_suffix \ {${sg{$local_part_suffix}{-(\\w+)(\\+.*)?}{\$1}}} \ {post}}' \ $local_part current_directory = MAILMAN_HOME home_directory = MAILMAN_HOME user = MAILMAN_USER group = MAILMAN_GROUP # This transport returns mail to unauthorized senders that send mail to # closed mailing lists. .include /etc/exim/exim-mailinglist-transport.conf.inc # This transport is used for handling pipe deliveries generated by alias or # .forward files. If the pipe generates any standard output, it is returned # to the sender of the message as a delivery error. Set return_fail_output # instead of return_output if you want this to happen only when the pipe fails # to complete normally. You can set different transports for aliases and # forwards if you want to - see the references to address_pipe in the routers # section above. address_pipe: driver = pipe return_output user = ${lookup mysql{select users.uid from users,domains where localpart = '${quote_mysql:$local_part}' and domain = '${quote_mysql:$domain}' and users.domain_id = domains.domain_id}} group = ${lookup mysql{select users.gid from users,domains where localpart = '${quote_mysql:$local_part}' and domain = '${quote_mysql:$domain}' and users.domain_id = domains.domain_id}} address_pipe_catchall: driver = pipe return_output user = ${lookup mysql{select users.uid from users,domains where localpart = '*' and domain = '${quote_mysql:$domain}' and users.domain_id = domains.domain_id}} group = ${lookup mysql{select users.gid from users,domains where localpart = '*' and domain = '${quote_mysql:$domain}' and users.domain_id = domains.domain_id}} address_pipe_local: driver = pipe return_output # This transport is used for handling deliveries directly to files that are # generated by aliasing or forwarding. address_file: driver = appendfile delivery_date_add envelope_to_add return_path_add # This transport is used for handling autoreplies generated by the filtering # option of the userforward router. address_reply: driver = autoreply ###################################################################### # RETRY CONFIGURATION # ###################################################################### begin retry # This single retry rule applies to all domains and all errors. It specifies # retries every 15 minutes for 2 hours, then increasing retry intervals, # starting at 1 hour and increasing each time by a factor of 1.5, up to 16 # hours, then retries every 6 hours until 4 days have passed since the first # failed delivery. # Domain Error Retries # ------ ----- ------- # exim4u MOD the original config file had retries for 14 days: # * * F,2h,15m; G,16h,1h,1.5; F,14d,6h # exim4u changed retries to 5 minuites (first interval) and 4 days (last interval) as follows: * * F,2h,5m; G,16h,1h,1.5; F,4d,6h ###################################################################### # REWRITE CONFIGURATION # ###################################################################### # There are no rewriting specifications in this default configuration file. begin rewrite ###################################################################### # AUTHENTICATION CONFIGURATION # ###################################################################### # There are no authenticator specifications in this default configuration file. begin authenticators plain_login: driver = plaintext public_name = PLAIN server_condition = ${lookup mysql{SELECT '1' FROM users \ WHERE username = '${quote_mysql:$2}' \ AND clear = '${quote_mysql:$3}'} {yes}{no}} server_set_id = $2 fixed_login: driver = plaintext public_name = LOGIN server_prompts = "Username:: : Password::" server_condition = ${lookup mysql{SELECT '1' FROM users \ WHERE username = '${quote_mysql:$1}' \ AND clear = '${quote_mysql:$2}'} {yes}{no}} server_set_id = $1 fixed_cram: driver = cram_md5 public_name = CRAM-MD5 server_secret = ${lookup mysql{SELECT clear FROM users \ WHERE username = '${quote_mysql:$1}'}{$value}fail} server_set_id = $1 ###################################################################### # CONFIGURATION FOR local_scan() # ###################################################################### # If you have built Exim to include a local_scan() function that contains # tables for private options, you can define those options here. Remember to # uncomment the "begin" line. It is commented by default because it provokes # an error with Exim binaries that are not built with LOCAL_SCAN_HAS_OPTIONS # set in the Local/Makefile. # begin local_scan