#queue_only = true # exim4u Config File /etc/exim4/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/exim4/exim.conf is the main exim configuration file for exim4u. # Other configuration files required in the /etc/exim4 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: ccTLD.txt, exim.pl, and surbl_whitelist.txt. # ###################################################################### # 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/exim4/exim4u_local.conf.inc # REQUEST TRACKER #.include /etc/exim4/exim4u_rt.conf.inc # Mailman3 .include /etc/exim4/mm3.conf # # 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 responding at $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}} #tls_certificate = /etc/dovecot/private/dovecot.pem #tls_privatekey = /etc/dovecot/private/dovecot.key tls_certificate = /etc/letsencrypt/live/newideatest.site/fullchain.pem tls_privatekey = /etc/letsencrypt/live/newideatest.site/privkey.pem tls_dhparam = /etc/ssl/dh.pem # # 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/exim4/exim4u_global_spam_virus}} # exim4u: Calculate the spamreject score SPAMREJECT = ${eval:${lookup{SpamRejectScore}lsearch{/etc/exim4/exim4u_global_spam_virus}} * 10} # exim4u: Spam tag text SPAMTAGTEXT = ${lookup{SpamTagText}lsearch{/etc/exim4/exim4u_global_spam_virus}} # exim4u: Max scan size for spamassassin MAXSCANSIZE = ${eval:${lookup{MaxScanSize}lsearch{/etc/exim4/exim4u_global_spam_virus}}} # exim4u: Spamfolder name SPAMFOLDER = ${lookup{SpamFolder}lsearch{/etc/exim4/exim4u_global_spam_virus}} # # exim4u: - Add all host names and IP addressess for the local machine hostlist MY_HOSTs = lsearch;/etc/exim4/exim4u_hostnames+hostIPs # # exim4u: - Add hosts to be exempted from SMTP ratelimit checks as follows: hostlist backup_mx_rl_hosts = lsearch;/etc/exim4/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/exim4/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/exim4/exim4u_relay_from_hosts # # exim4u: Skip sender verify checks for these hosts: hostlist skip_sender_verify_hosts = net-iplsearch;/etc/exim4/exim4u_IPskip_sender_verify # # exim4u: Blacklist and Whitelist IP addresses here: hostlist IPblacklist = net-iplsearch;/etc/exim4/exim4u_IPblacklist hostlist IPwhitelist = +MY_HOSTs : localhost : net-iplsearch;/etc/exim4/exim4u_IPwhitelist # hostlist kixp_hosts = 196.200.32.0/20 : 62.8.64.0/19 : 196.202.192.0/19 : 212.49.64.0/19 : \ 62.24.96.0/19 : 195.202.64.0/19 : 217.199.144.0/20 : 41.209.0.0/18 : \ 194.9.82.0/23 : 194.9.64.0/23 : 212.22.160.0/19 : 213.147.64.0/19 : \ 213.150.96.0/19 : 80.240.192.0/20 : 217.21.112.0/21 : 217.21.120.0/21 : \ 196.216.64.0/19 : 41.220.112.0/20 : 196.207.16.0/20 : 196.200.16.0/20 : \ 62.24.101.0/24 : 62.24.115.0/24 : 62.24.120.0/22 : 196.216.128.0/22 : \ 62.56.219.0/24 : 64.110.109.0/24 : 66.178.100.0/24 : 66.178.102.0/24 : \ 80.231.77.0/24 : 80.247.158.0/24 : 194.201.253.0/24 : 193.109.66.0/23 : \ 198.32.67.0/24 # 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}} : jupiter.newideatest.site # exim4u: Setup the list of destination domains for which we are an mx relay. domainlist relay_to_domains = ${lookup mysql{RELAY_DOMAINS}} # domainlist mm_domains = newideatest.site # # 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 = Debian-exim : www-data # The name of the ACLs are defined here: # 20110428 acl_smtp_rcpt = acl_check_rcpt # ACL Pointers for MTA and MUA #acl_smtp_rcpt = ${if IS_MTA_PORT {acl_check_rcpt}{acl_check_rcpt_mua}} acl_smtp_data = acl_check_content acl_smtp_helo = acl_check_helo 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 acl_smtp_auth = acl_check_auth acl_smtp_quit = acl_check_quit acl_smtp_notquit = acl_check_notquit # 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 = \ -retry_defer \ -skip_delivery \ +all_parents \ +arguments \ +received_sender \ +received_recipients \ +smtp_connection \ +smtp_syntax_error \ +delivery_size \ +incoming_interface \ +smtp_protocol_error \ +subject \ +tls_peerdn \ -host_lookup_failed \ -rejected_header \ +queue_time_overall +millisec +queue_time +deliver_time # System Filter system_filter = EXIM_HOME/filters/FILTER2008 system_filter_file_transport = address_file system_filter_pipe_transport = address_pipe_local system_filter_reply_transport = address_reply system_filter_directory_transport = address_directory system_filter_user = Debian-exim system_filter_group = Debian-exim log_file_path = /var/log/exim4/%s.log #LIM = 100 #PERIOD = 1h #WARNTO = odhiambo@gmail.com EXIMBINARY = /usr/sbin/exim -f root #SHELL = /bin/sh # 20171219 IPNOTIF = echo Subject: blocked $sender_host_address $dnslist_text \ ${sg{${lookup dnsdb{>, defer_never,ptr=$sender_host_address}}}{\N[^\w.,-]\N}{}}; \ echo; echo for bruteforce auth cracking attempt.; WRONG_RCPT_LIMIT = 100 PERIOD = 1h WARNTO = odhiambo@gmail.com SHELL = /bin/sh # these two masks are used only in case of IPv6: # how many IPv6 addresses you give to your single user: MASKL = ${if match{$acl_m_user}{:}{/64}} # how many external IPv6 addresses you treat as one attacker: MASKW = ${if match{$sender_host_address}{:}{/56}} hostlist blocked_ips = $spool_directory/blocked_IPs # intentionally not cached # 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_per_connection = 30 #smtp_accept_queue = 200 #smtp_connect_backlog = 125 #smtp_receive_timeout = 10m smtp_receive_timeout = 3m message_size_limit = 20M # 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/exim4/exim.pl/exim_surbl.pl' perl_at_start = true message_body_visible = 75000 disable_ipv6 = true smtp_enforce_sync = false # This is important to streamline deferred messages. See the redirect router below queue_run_in_order # ENV # keep_environment should contain a list of trusted environment variables. keep_environment = add_environment = <; PATH=/sbin:/usr/bin:/usr/sbin #PRDR - 4.87 prdr_enable = true # DSN - only in 4.87 and above dsn_advertise_hosts = * P7ZIP = /usr/bin/7z # port archivers/p7zip in case of FreeBSD #WINBIN = exe|com|js|pif|scr|bat|jse|cpl|vbe|vbs|ace # more cautious: WINBIN = exe|com|js|pif|scr|bat|flv|reg|btm|chm|cmd|cpl|dll|hta|jse|jsp|lnk|msi|prf|sys|vb|vbe|vbs|ace # WinRAR can uncompress .ace, so trojans are sometimes compressed .ace COMPREXT = zip|rar|7z|arj|bz2|gz|uue|xz|z BINFORBIDDEN = Windows-executable attachments forbidden check_rfc2047_length = false DNSLISTS1 = sbl-xbl.spamhaus.org : nomail.rhsbl.sorbs.net/$sender_address_domain : cbl.abuseat.org : web.dnsbl.sorbs.net : socks.dnsbl.sorbs.net : http.dnsbl.sorbs.net : \ zen.spamhaus.org : b.barracudacentral.org : psbl.surriel.com : xbl.spamhaus.org #: ubl.unsubscore.com #: hostkarma.junkemailfilter.com # DMARC #dmarc_history_file = /var/spool/exim4/opendmarc.dat #dmarc_tld_file = /etc/exim4/opendmarc/exim_opendmarc.tlds #dmarc_forensic_sender = dmarc_noreply@newideatest.site ###################################################################### # 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/exim4/exim-acl-check-spf.conf.inc acl_check_auth: drop message = authentication is allowed only once per message in order \ to slow down bruteforce cracking set acl_m_auth = ${eval10:0$acl_m_auth+1} condition = ${if >{$acl_m_auth}{2}} delay = 22s drop message = blacklisted for bruteforce cracking attempt set acl_c_authnomail = ${eval10:0$acl_c_authnomail+1} condition = ${if >{$acl_c_authnomail}{4}} condition = ${if exists{$spool_directory/blocked_IPs}\ {${lookup{$sender_host_address}iplsearch\ {$spool_directory/blocked_IPs}{0}{1}}}\ {1}} acl = setdnslisttext continue = ${run{SHELL -c 'echo \\\"$sender_host_addressMASKW\\\" \ >>$spool_directory/blocked_IPs; \ \N{\N IPNOTIF \N}\N | $exim_path -f root WARNTO'}} drop message = blacklisted for bruteforce cracking attempt condition = ${if >{$acl_c_authnomail}{4}} accept set acl_c_authhash = ${if match{$smtp_command_argument}\ {\N(?i)^(?:plain|login) (.+)$\N}{${nhash_1000:$1}}} acl_check_quit: warn condition = $authentication_failed condition = ${if def:acl_c_authhash} ratelimit = 0 / 5m / strict / $sender_host_address-$acl_c_authhash set acl_c_hashrate = ${sg{$sender_rate}{[.].*}{}} warn condition = $authentication_failed logwrite = :reject: quit after authentication failed: \ ${sg{$sender_rcvhost}{\N[\n\t]+\N}{\040}} condition = ${if or{\ {!def:acl_c_authhash}\ {<{$acl_c_hashrate}{2}}\ }} ratelimit = 7 / 5m / strict / per_conn condition = ${if exists{$spool_directory/blocked_IPs}\ {${lookup{$sender_host_address}iplsearch\ {$spool_directory/blocked_IPs}{0}{1}}}\ {1}} acl = setdnslisttext continue = ${run{SHELL -c 'echo \\\"$sender_host_addressMASKW\\\" \ >>$spool_directory/blocked_IPs; \ \N{\N IPNOTIF \N}\N | $exim_path -f root WARNTO'}} acl_check_notquit: warn condition = $authentication_failed condition = ${if def:acl_c_authhash} ratelimit = 0 / 2h / strict / $sender_host_address-$acl_c_authhash set acl_c_hashrate = ${sg{$sender_rate}{[.].*}{}} warn condition = $authentication_failed logwrite = :reject: $smtp_notquit_reason after authentication failed: \ ${sg{$sender_rcvhost}{\N[\n\t]+\N}{\040}} condition = ${if eq{$smtp_notquit_reason}{connection-lost}} condition = ${if or{\ {!def:acl_c_authhash}\ {<{$acl_c_hashrate}{2}}\ }} ratelimit = 7 / 2h / strict / per_conn condition = ${if exists{$spool_directory/blocked_IPs}\ {${lookup{$sender_host_address}iplsearch\ {$spool_directory/blocked_IPs}{0}{1}}}\ {1}} acl = setdnslisttext continue = ${run{SHELL -c 'echo \\\"$sender_host_addressMASKW\\\" \ >>$spool_directory/blocked_IPs; \ \N{\N IPNOTIF \N}\N | $exim_path -f root WARNTO'}} 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 = : +relay_from_hosts # deny hosts = 192.168.55.168 # message = Something is wrong with connections from you. accept hosts = : +relay_from_hosts # Bruteforce checks drop message = $sender_host_address locally blacklisted for a bruteforce \ auth (username+password) cracking attempt condition = ${if exists{$spool_directory/blocked_IPs}} condition = ${lookup{$sender_host_address}iplsearch\ {/var/..$spool_directory/blocked_IPs}{1}{0}} # Another path to the same file in order to circumvent lookup caching. # accept # exim4u: IP Whitelist accept hosts = +IPwhitelist # 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: Spammer IP Address Blacklist drop hosts = +IPblacklist message = Blacklisted log_message = Host Is Banned by IPblacklist # 'Present Day' - Turn it ON with a 'warn verb' and a log_message instead of a 'deny' # in acl_smtp_connect: warn # check only port 25, not users submitting on port 587 condition = ${if eq{$interface_port}{25}} !verify = reverse_host_lookup log_message = rDNS fail for $sender_host_address/$sender_address # 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 # HASH - is this allowed? #20171219 #hash: # accept set acl_c_authhash = ${nhash_1000:$acl_arg1} # notquit # accept authenticated hosts # accept authenticated = * drop authenticated = * set acl_m_user = ${sg{$authenticated_id}{\N[^\w.=@-]\N}{}} condition = ${if exists{$spool_directory/blocked_authenticated_users}} set acl_m_wasfree = ${if def:acl_c_blocked{$acl_c_spoolfree}\ {${lookup{$acl_m_user}lsearch\ {$spool_directory/blocked_authenticated_users}}}} condition = ${if match{$acl_m_wasfree}{\N^\d+$\N}} condition = ${if match{$spool_space}{\N^\d+$\N}} condition = ${if <={$spool_space}{${eval:$acl_m_wasfree/2}}} log_message = free space on spool disk $spool_space KB - less than \ half than it was when the user $acl_m_user was blocked message = spool disk too full accept authenticated = * condition = ${if exists{$spool_directory/blocked_authenticated_users}} condition = ${lookup{$acl_m_user}lsearch\ {$spool_directory/blocked_authenticated_users}\ {1}{$acl_c_blocked}} # The variable acl_c_blocked is used because lookup can be cached. control = freeze/no_tell control = submission/domain= add_header = X-Authenticated-As: $acl_m_user accept authenticated = * !verify = recipient/defer_ok/callout=10s,defer_ok,use_sender ratelimit = WRONG_RCPT_LIMIT / PERIOD / per_rcpt / user-$acl_m_user set acl_c_blocked = 1 set acl_c_spoolfree = $spool_space continue = ${run{SHELL -c "echo $acl_m_user:$acl_c_spoolfree \ >>$spool_directory/blocked_authenticated_users; \ \N{\N echo Subject: user $acl_m_user blocked; echo; echo because \ has sent mail to WRONG_RCPT_LIMIT invalid recipients during PERIOD.; \ \N}\N | $exim_path -f root WARNTO"}} control = freeze/no_tell control = submission/domain= add_header = X-Authenticated-As: $acl_m_user accept authenticated = * control = submission/domain= # 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 = * accept set acl_c_authnomail = 0 deny authenticated = * condition = ${if eq{$authenticated_id}{$sender_address}{no}{yes}} message = Your authenticating ID must match your sending address. log_message = 4-3: Authenticated ID ($authenticated_id) does not \ match the sending address ($sender_address). # 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/exim4/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" #!!!2016!! 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 # Deny if the message contains an overlong line. Per the standards # we should never receive one such via SMTP. deny !senders = : message = Maximum body line length is $max_received_linelength \ (over 998 chars limit), message rejected. condition = ${if > {$max_received_linelength}{998}} accept acl_check_helo: drop message = Cutwail/PushDo bot blacklisted condition = ${if eq{$sender_helo_name}{ylmf-pc}} acl = setdnslisttext continue = ${run{SHELL -c 'echo \\\"$sender_host_addressMASKW\\\" \ >>$spool_directory/blocked_IPs; \ \N{\N IPNOTIF \N}\N | $exim_path -f root WARNTO'}} # if this bot is dropped at helo, it repeats multiple times, # but if dropped at connect, it tries only twice # HELO is an open Proxy or Subnet drop message = Open Proxy in HELO/EHLO (HELO was $sender_helo_name) condition = ${if eqi {$sender_helo_name}{$sender_host_address}{no}{yes}} condition = ${if isip {$sender_helo_name}{yes}{no}} log_message = Sender Helo name is an IP address ($sender_helo_name) delay = 45s # HELO is an IP address drop condition = ${if isip{$sender_helo_name}} message = Access denied - Invalid HELO name (See RFC2821 4.1.3) log_message = Sender Helo name is an IP address ($sender_helo_name) # HELO contains a IP part - this is not working with Apple clients on the phone # drop message = Helo name contains a ip address (HELO was $sender_helo_name) and not is valid # condition = ${if match{$sender_helo_name}{\N((\d{1,3}[.-]\d{1,3}[.-]\d{1,3}[.-]\d{1,3})|([0-9a-f]{8})|([0-9A-F]{8}))\N}{yes}{no}} # condition = ${if match {${lookup dnsdb{>: defer_never,ptr=$sender_host_address}}}{$sender_helo_name}{no}{yes}} # delay = 45s # log_message = Sender Helo name is partly an IP address ($sender_helo_name) # HELO is faked interface address # Type: forgery # Some spammers put the server's interface address they connect to in their HELO, maybe asuming it is whitelisted or something. # If you are running your mail server behind NAT, you should replace $interface_address with your external IP address. drop condition = ${if eq{[$interface_address]}{$sender_helo_name}} !hosts = 127.0.0.1 message = $interface_address is _my_ address log_message = Sender Helo name is my own interface IP address ($sender_helo_name) accept setdnslisttext: accept dnslists = zz.countries.nerd.dk accept hash: accept set acl_c_authhash = ${nhash_1000:$acl_arg1} # For the ACL part, try the easy bits first, MUA, this is pretty much a # complete example which should work. # # As you will see, I don't have the submission-mode on, as I allow my # users to use different sender addresses, but I do check that they are # valid. For the empty sender, like automated replays, the null-sender is # accepted as well. No more checks like validity of recipient domain or # the like, as MUA, esp M$ ones, chock on 55x rejects and don't report # back much information about the reason. So send them a "normal" NDM. # 20110428 acl_check_rcpt_mua: # MUA must authenticate deny message = Authentication is required to send messages log_message = SMTP-SUBMISSION-NO-AUTHENTICATION !authenticated = * control = submission # If a null-sender is given, go on with it, can't do anything more accept senders = : # Accept the message, if the sender email address is from the local system accept sender_domains = +local_domains verify = sender control = submission deny message = Sender address not valid. log_message = SMTP-SUBMISSION-SENDER-NOT-VALID acl_check_rcpt: # DMARC warn authenticated = * hosts = +relay_from_hosts domains = +local_domains control = dmarc_disable_verify #warn !authenticated = * # hosts = !+relay_from_hosts # domains = !+local_domains # control = dmarc_enable_forensic # Blacklisted Senders deny message = Users have complained that you send unsolicited mail.\n\You're therefore blacklisted.\n\ Please contact abuse@newideatest.site for redress. senders = ${if exists {/etc/exim4/blacklisted_senders}{/etc/exim4/blacklisted_senders}{}} condition = ${lookup{$sender_domains}wildlsearch{/etc/exim4/blacklisted_senders}}{no}{yes}} #senders = /etc/exim4/blacklisted_senders # 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 # FORGERIES ## Spammers forging our domain in their from: address deny message = You are not allowed to use $primary_hostname in your headers !hosts = : localhost : 41.242.2.46 !authenticated = * condition = ${if match{${lc:$h_from:}}{${lc:$qualify_domain}}} condition = ${if match{${lc:$h_from:}}{\Nnewideatest.site\N}} condition = ${if match{${lc:$h_from:}}{\Nnewideatest.site\N}} log_message = 1_FAKE_HEADER_FROM: $rh_from noticed in $sender_address from $sender_host_address. deny message = You are not allowed to use $sender_address_domain in your headers !authenticated = * !hosts = : localhost : 41.242.2.46 condition = ${if match_domain{$sender_address_domain}{+local_domains}} sender_domains = +local_domains log_message = 2_FAKE_HEADER_FROM: $h_from: seen in $sender_address from $sender_host_address. # deny !authenticated = * # condition = ${if match_domain{${domain:${address:$h_from:}}}{+local_domains}} # message = Sorry, external MTA's and unauthenticated MTA's don't have\ # permission to send email to this server with a header that\ # states the email is from ${lc:${domain:${address:$h_from:}}}. # log_message = 3_FAKE_HEADER_FROM: ${lc:${domain:${address:$h_from:}}} from $sender_host_address. .include /etc/exim4/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 drop hosts = !@[] : +relay_from_hosts set acl_m_user = $sender_host_address # or username from RADIUS, then change # iplsearch to lsearch in this and next paragraphs condition = ${if exists{$spool_directory/blocked_relay_users}} set acl_m_wasfree = ${if def:acl_c_blocked{$acl_c_spoolfree}\ {${lookup{$acl_m_user}iplsearch\ {$spool_directory/blocked_relay_users}}}} condition = ${if match{$acl_m_wasfree}{\N^\d+$\N}} condition = ${if match{$spool_space}{\N^\d+$\N}} condition = ${if <={$spool_space}{${eval:$acl_m_wasfree/2}}} log_message = free space on spool disk $spool_space KB - less than \ half than it was when the user $acl_m_user was blocked message = spool disk too full accept hosts = !@[] : +relay_from_hosts condition = ${if exists{$spool_directory/blocked_relay_users}} condition = ${lookup{$acl_m_user}iplsearch\ {$spool_directory/blocked_relay_users}\ {1}{$acl_c_blocked}} control = freeze/no_tell control = submission/domain= add_header = X-Relayed-From: $acl_m_user accept hosts = !@[] : +relay_from_hosts !verify = recipient/defer_ok/callout=10s,defer_ok,use_sender ratelimit = WRONG_RCPT_LIMIT / PERIOD / per_rcpt / relayuser-$acl_m_user set acl_c_blocked = 1 set acl_c_spoolfree = $spool_space continue = ${run{SHELL -c 'echo \\\"$acl_m_userMASKL\\\":$acl_c_spoolfree \ >>$spool_directory/blocked_relay_users; \ \N{\N echo Subject: relay user $acl_m_user blocked; echo; echo \ because has sent mail to WRONG_RCPT_LIMIT invalid recipients during PERIOD.; \ \N}\N | $exim_path -f root WARNTO'}} control = freeze/no_tell control = submission/domain= add_header = X-Relayed-From: $acl_m_user accept hosts = +relay_from_hosts control = submission/domain= # 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 authenticated = * # 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=use_postmaster,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=use_postmaster,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:psbl.surriel.com # dnslists = zen.spamhaus.org:bad.psky.me:truncate.gbudb.net dnslists = DNSLISTS1 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. Please contact postmaster@newideatest.site if you feel this is in error. # 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/exim4/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 = : # deny message = BINFORBIDDEN log_message = forbidden attachment: filename=$mime_filename, \ content-type=$mime_content_type, recipients=$recipients condition = ${if or{\ {match{$mime_content_type}\ {(?i)executable|application/x-ace-compressed}}\ {match{$mime_filename}{\N(?i)\.(WINBIN)(\.(COMPREXT))*$\N}}\ }} deny message = Compressed BINFORBIDDEN condition = ${if or{\ {match{$mime_content_type}{(?i)application/\ (octet-stream|x(-zip)?-compressed|zip)}}\ {match{$mime_filename}{\N(?i)\.(COMPREXT)$\N}}\ }} condition = ${if <{$message_size}{1500K}} decode = default log_message = forbidden binary in attachment: filename=$mime_filename, \ recipients=$recipients condition = ${if match{${run{P7ZIP l -y $mime_decoded_filename}}}\ {\N(?i)\n[12].+\.(COMPREXT|WINBIN)\n\N}} #!!! accept # 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}} # https://lists.exim.org/lurker/message/20140114.121803.09f5d887.en.html deny message = A .zip attachment contains a Windows-executable file - blocked because we are afraid of new viruses not recognized [yet] by antiviruses. condition = ${if match{$mime_filename}{\N(?i)\.zip$\N}} condition = ${if def:sender_host_address} !authenticated = * decode = default log_message = forbidden binary in attachment: filename=$mime_filename, recipients=$recipients condition = ${if match{${run{/usr/bin/unzip -l $mime_decoded_filename}}}\ {\N(?i)\.(exe|com|vbs|bat|pif|scr|hta|js|cmd|chm|cpl|jsp|reg|vbe|lnk|dll|sys|btm|msi|prf|vb)\n\N}} deny message = Windows-executable attachments forbidden because we are afraid of new viruses not recognized [yet] by antiviruses. condition = ${if def:sender_host_address} !authenticated = * log_message = forbidden attachment: filename=$mime_filename, content-type=$mime_content_type, recipients=$recipients condition = ${if or{\ {match{$mime_content_type}{(?i)executable}}\ {match{$mime_filename}{\N(?i)\.(exe|com|vbs|bat|pif|scr|hta|js|cmd|chm|cpl|jsp|reg|vbe|lnk|dll|sys|btm|msi|prf|vb)$\N}}\ }} # exim4u: SURBL/URIBL URL Check for blacklisted URL links embeded in mail. # Perl Script Scans First 75K of Message deny !sender_domains = pkfea.com !hosts = 192.168.54.0/23 condition = ${if <{$message_size}{75000}{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: # DMARC Checks # warn # dmarc_status = accept : none : off # !authenticated = * # log_message = DMARC DEBUG: $dmarc_status $dmarc_used_domain # warn # dmarc_status = !accept # !authenticated = * # log_message = DMARC DEBUG: '$dmarc_status' for $dmarc_used_domain # warn # dmarc_status = quarantine # !authenticated = * # set acl_m_quarantine = 1 # # Do something in a transport with this flag variable #deny # warn # hosts = !+relay_from_hosts # condition = ${if eq{$dmarc_domain_policy}{reject}} # condition = ${if eq{$acl_m_mailing_list}{1}} # message = Messages from $dmarc_used_domain break mailing lists #deny # warn # dmarc_status = reject # !authenticated = * # hosts = !+relay_from_hosts # message = Message from $dmarc_used_domain failed sender's DMARC policy, REJECT # warn # add_header = :at_start:${authresults {$primary_hostname}} # Deprecated as from 4.88 ## 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. # Accept any messages that are larger than 256k because they are not likely to contain # viruses... that large size of virus will take too long to replicate ;) accept condition = ${if >{$message_size}{256k}{yes}{no}} # Now process the rest 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 = */defer_ok 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 = : accept hosts = 192.168.54.0/23 # 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 First 75K of Message deny condition = ${if <{$message_size}{75000}{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/defer_ok 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/defer_ok 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. # RSPAMD # do not scan messages from submission port (or maybe you want to?) accept condition = ${if eq{$interface_port}{587}} # skip scanning for authenticated users (if desired?) # accept authenticated = * # scan the message with rspamd warn spam = nobody:true # This will set variables as follows: # $spam_action is the action recommended by rspamd # $spam_score is the message score (we unlikely need it) # $spam_score_int is spam score multiplied by 10 # $spam_report lists symbols matched & protocol messages # $spam_bar is a visual indicator of spam/ham level # use greylisting available in rspamd v1.3+ defer message = Please try again later condition = ${if eq{$spam_action}{soft reject}} deny message = Message discarded as high-probability spam condition = ${if eq{$spam_action}{reject}} # Remove foreign headers warn remove_header = x-spam-bar : x-spam-score : x-spam-report : x-spam-status # add spam-score and spam-report header when "add header" action is recommended by rspamd warn condition = ${if eq{$spam_action}{add header}} add_header = X-Spam-Score: $spam_score ($spam_bar) add_header = X-Spam-Report: $spam_report # add x-spam-status header if message is not ham warn ! condition = ${if match{$spam_action}{^no action\$|^greylist\$}} add_header = X-Spam-Status: Yes # add x-spam-bar header if score is positive warn condition = ${if >{$spam_score_int}{0}} add_header = X-Spam-Bar: $spam_bar #/RSPAMD # 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 !senders = ashit@accumaximum.com 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. # 20180926 Adds deny message = REJECTED - Sender Verify Failed - The email server for the domain [$sender_address_domain] tells me that the sender's email address [$sender_address] is not a valid. $sender_verify_failure log_message = REJECTED - Sender Verify Failed - The email server for the domain [$sender_address_domain] tells me that the sender's email address [$sender_address] is not a valid. $sender_verify_failure condition = ${lookup{$sender_address_domain}wildlsearch{/etc/exim4/noverify.txt}{no}{yes}} condition = ${lookup{$sender_host_address}wildlsearch{/etc/exim4/noverify.txt}{no}{yes}} !verify = header_sender/callout=2m,defer_ok,mailfrom=postmaster@newideatest.site condition = ${if eq{recipient}{$sender_verify_failure}} # Null Address Check Headers drop message = Header From exist, but not have a valid address condition = ${if def:h_from: {yes}{no}} condition = ${if or { \ { eq{${address:$h_from:}}{} } \ { eq{${domain:$h_from:}}{} } \ { eq{${local_part:$h_from:}}{} } \ } {yes}{no}} delay = 45s drop message = Header Reply-to exist, but not have a valid address condition = ${if def:h_reply-to: {yes}{no}} condition = ${if or { \ { eq{${address:$h_reply-to:}}{} } \ { eq{${domain:$h_reply-to:}}{} } \ { eq{${local_part:$h_reply-to:}}{} } \ } {yes}{no}} delay = 45s drop message = Header Sender exists, but not have a valid address condition = ${if def:h_sender: {yes}{no}} condition = ${if or { \ { eq{${address:$h_sender:}}{} } \ { eq{${domain:$h_sender:}}{} } \ { eq{${local_part:$h_sender:}}{} } \ } {yes}{no}} delay = 45s # Fast Check Mx Headers Address drop message = Header From have a invalid ${sender_verify_failure}: <${address:$h_from:}> log_message = Header From have a invalid ${sender_verify_failure}: <${address:$h_from:}> condition = ${if def:h_from: {yes}{no}} !verify = sender=${address:$h_from:}/no_details delay = 45s drop message = Header Reply have a invalid ${sender_verify_failure}: <${address:$h_reply-to:}> log_message = Header Reply have a invalid ${sender_verify_failure}: <${address:$h_reply-to:}> condition = ${if def:h_reply-to: {yes}{no}} !verify = sender=${address:$h_reply-to:}/no_details delay = 45s drop message = Header Sender have a invalid ${sender_verify_failure}: <${address:$h_sender:}> log_message = Header Sender have a invalid ${sender_verify_failure}: <${address:$h_sender:}> condition = ${if def:h_sender: {yes}{no}} !verify = sender=${address:$h_sender:}/no_details delay = 45s # 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/exim4/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 # Configure Exim so that it sends mail to the outside world only from # a restricted list of our local users? # # We need to have a convenient way of checking the list. If it is # only a handful of users, you could just list them inline. Otherwise, # you need to put them in a file or database. Let's suppose you've just # got a list in a file. Put this as your first router: #check_outgoing: # driver = redirect # domains = !+local_domains # senders = ! : !lsearch;/etc/exim4/permitted_senders # allow_fail # data = :fail: You, $local_part@$domain, are not allowed to send mail outside. # Is there any way to have messages sent to a specific local address delayed # by - say - 24 hours? # Adapted from http://wiki.exim.org/FAQ/Configuration_cookbook/Q9807 # # Configure Exim so that it deliberately delays for 12hrs (43200 secs) email # destined to the outside world, from a list of our local users # List can be in the format of the router above delay_outgoing: driver = redirect # domains = !+local_domains : !+relay_to_domains senders = ! : lsearch;/etc/exim4/delayed_senders condition = ${if < {$message_age}{43200}{yes}{no}} allow_defer data = :defer: message not old enough no_verify # 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 # #!smart_host_route: #! driver = manualroute #!domains = \N^yahoo\.\N : \N^lge\.\N : \N^hotmail\.\N : \N^live\.com\N : mindray.com : materkenya.com : internationalmedicalcorps.org #! domains = !+local_domains #! transport = ak_remote_smtp #!transport = remote_smtp #! route_data = gw.kictanet.or.ke #! same_domain_copy_routing #! no_verify #! no_more # REQUEST TRACKER #.include /etc/exim4/exim4u_rt_router.conf # Mailman3 .include /etc/exim4/mm3_router.conf # Special Purpose Router to throttle sending e-mails to Yahoo outbound_throttled: driver = dnslookup domains = \N^yahoo\.\N : rocketmail.com : ymail.com : y7mail.com : \ btinternet.com : btopenworld.com : att.net : sbcglobal.net : rogers.com retry_use_local_part transport = throttled_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 or X-Spam-Report if not 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 = AUTORESPONDER_BULK_REGEX 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 file_transport = dovecot_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 if spam or X-Spam-Report if not spam. 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 file_transport = dovecot_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 = MM_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 # .include /etc/exim4/exim-group-router.conf.inc .include /etc/exim4/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 file_transport = dovecot_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 # REQUEST TRACKER #.include /etc/exim4/exim4u_rt_transport.conf # Mailman3 .include /etc/exim4/mm3_transport.conf # This transport was forced upon me by Yahoo :-) # http://lists.exim.org/lurker/message/20080818.185617.b5534450.en.html throttled_smtp: driver = smtp connection_max_messages = 5 max_rcpt = 9 serialize_hosts = * retry_use_local_part hosts_avoid_pipelining = * tls_verify_cert_hostnames = !* # 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. # Refuse to send any message with over-long lines, which could have # been received other than via SMTP. The use of message_size_limit to # enforce this is a red herring. remote_smtp: driver = smtp # message_size_limit = ${if > {$max_received_linelength}{998}{1}{0}} serialize_hosts = * ak_remote_smtp: driver = smtp port = 587 serialize_hosts = * # 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 = ${if exists{/etc/pki/tls/dk/${lc:$sender_address_domain}-dkim.priv.key}{${lc:$sender_address_domain}}{}} dkim_selector = key1 dkim_private_key = ${if exists{/etc/pki/tls/dk/${lc:$sender_address_domain}-dkim.priv.key}\ {/etc/pki/tls/dk/${lc:$sender_address_domain}-dkim.priv.key}{0}} dkim_canon = relaxed dkim_strict = true # 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_mbox: 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 local_delivery: driver = appendfile directory = ${home}/Maildir/ create_directory maildir_format 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" dovecot_virtual_delivery: driver = pipe return_output command = /usr/lib/dovecot/dovecot-lda -d $local_part@$domain -f $sender_address message_prefix = message_suffix = delivery_date_add envelope_to_add return_path_add log_output user = Debian-exim temp_errors = 64 : 69 : 70: 71 : 72 : 73 : 74 : 75 : 78 virtual_vacation_delivery: driver = autoreply from = "${local_part}@${domain}" to = ${sender_address} subject = "Autoreply from ${local_part}@${domain}" 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}} once = /var/spool/virtual/.vacations/${lc:$local_part}_${lc:$domain}.db once_repeat = 7d mailman_verp_smtp: driver = smtp # put recipient address into return_path return_path = ${local_part:$return_path}+$original_local_part=$original_domain@${domain:$return_path} # must restrict to one recipient at a time max_rcpt = 1 # Errors-To: may carry old return_path headers_remove = Errors-To headers_add = Errors-To: ${local_part:$return_path}+$original_local_part=$original_domain@${domain:$return_path} mailman_transport: driver = pipe command = MM_WRAP \ '${if def:local_part_suffix \ {${sg{$local_part_suffix}{-(\\w+)(\\+.*)?}{\$1}}} \ {post}}' \ $local_part current_directory = MM_HOME home_directory = MM_HOME user = MM_USER group = MM_GROUP # This transport returns mail to unauthorized senders that send mail to # closed mailing lists. .include /etc/exim4/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 address_directory: driver = appendfile check_string = message_prefix = "" message_suffix = "" delivery_date_add envelope_to_add return_path_add maildir_format # 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 # For encrypted passwords, use the following two authenticators: plain_login_exim4u: driver = plaintext public_name = PLAIN server_condition = ${if crypteq{$auth3}{${lookup mysql{ \ SELECT crypt FROM users \ WHERE username = '${quote_mysql:$auth2}' \ AND enabled = 1 \ }}}{1}{0}} server_set_id = $auth2 fixed_login_exim4u: driver = plaintext public_name = LOGIN server_prompts = "Username:: : Password::" server_condition = ${if crypteq{$auth2}{${lookup mysql{ \ SELECT crypt FROM users \ WHERE username = '${quote_mysql:$auth1}' \ AND enabled = 1 \ }}}{1}{0}} server_set_id = $auth1 #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 # client_send = ^cam@simbanet.co.ke^qwerty123 #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