From 4fcc01df6f8ce687eaf5609b052bb5f38575ca99 Mon Sep 17 00:00:00 2001 From: Nirvana <168984811+nirvanameow@users.noreply.github.com> Date: Fri, 16 May 2025 21:50:53 +0100 Subject: [PATCH] Update exim4.conf.template add primary hostname placeholder Adding a primary_hostname placeholder in exim4.conf.template, set to mail. via vst-install-debian.sh and v-rebuild-exim4-config. Updating acl_check_rcpt to allow unauthenticated local domain deliveries on port 25, while blocking non-local sends to prevent relaying. --- install/debian/12/exim/exim4.conf.template | 383 ++++++++++++++------- 1 file changed, 251 insertions(+), 132 deletions(-) diff --git a/install/debian/12/exim/exim4.conf.template b/install/debian/12/exim/exim4.conf.template index 15264797..2e00ce04 100644 --- a/install/debian/12/exim/exim4.conf.template +++ b/install/debian/12/exim/exim4.conf.template @@ -4,262 +4,363 @@ # # ###################################################################### +# Placeholder for primary_hostname (to be set dynamically during installation) +# primary_hostname = mail.domain.com + #SPAMASSASSIN = yes #SPAM_SCORE = 50 -#CLAMD = yes +#CLAMD = yes -disable_ipv6=true -add_environment=<; PATH=/bin:/usr/bin -keep_environment= +# Disable IPv6 for Exim to avoid connectivity issues on systems without IPv6 +disable_ipv6 = true + +# Define environment variables for Exim subprocesses +add_environment = <; PATH=/bin:/usr/bin +keep_environment = + +# Disable SMTPUTF8 advertisement (not needed for most setups) smtputf8_advertise_hosts = +# Load SRS secret for Sender Rewriting Scheme (used for email forwarding) SRS_SECRET = ${readfile{/etc/exim4/srs.conf}} -#local_interfaces = 0.0.0.0 +# Uncomment to bind Exim to specific interfaces (e.g., 0.0.0.0 for all interfaces) +#local_interfaces = 0.0.0.0 + +# Uncomment to set smtp_active_hostname dynamically based on interface address #smtp_active_hostname = ${lookup{$interface_address}lsearch{/etc/exim4/virtual/helo_data}{$value}} + +# Uncomment to customize the SMTP banner with the hostname and timestamp #smtp_banner = "$smtp_active_hostname ESMTP $tod_full" +# Define domains handled by this server (local_domains are those in /etc/exim4/domains/) domainlist local_domains = dsearch;/etc/exim4/domains/ + +# Define domains to relay to (also in /etc/exim4/domains/) domainlist relay_to_domains = dsearch;/etc/exim4/domains/ + +# Define trusted relay hosts (e.g., localhost) hostlist relay_from_hosts = 127.0.0.1 + +# Define whitelisted IPs (loaded from /etc/exim4/white-blocks.conf) hostlist whitelist = net-iplsearch;/etc/exim4/white-blocks.conf + +# Define blacklisted IPs (loaded from /etc/exim4/spam-blocks.conf) hostlist spammers = net-iplsearch;/etc/exim4/spam-blocks.conf + +# Disable local sender verification (useful for virtual domains) no_local_from_check + +# Allow untrusted senders to set the sender address untrusted_set_sender = * + +# Define ACLs for various SMTP stages acl_smtp_connect = acl_check_spammers acl_smtp_mail = acl_check_mail acl_smtp_rcpt = acl_check_rcpt acl_smtp_data = acl_check_data acl_smtp_mime = acl_check_mime +# Define recipient and email sending limits per email/hosting account LIMIT_PER_EMAIL_ACCOUNT_MAX_RECIPIENTS = 15 LIMIT_PER_HOSTING_ACCOUNT_MAX_RECIPIENTS = 5 LIMIT_PER_EMAIL_ACCOUNT_MAX_SENT_EMAILS_PER_HOUR = 40 LIMIT_PER_HOSTING_ACCOUNT_MAX_SENT_EMAILS_PER_HOUR = 40 +# Set maximum recipients per email and reject if exceeded recipients_max = 150 recipients_max_reject = true +# Uncomment to enable detailed logging for SMTP connections # log_selector = +smtp_connection + +# Limit concurrent SMTP connections smtp_accept_max = 50 smtp_accept_max_per_host = 4 +# Configure SpamAssassin if enabled .ifdef SPAMASSASSIN spamd_address = 127.0.0.1 783 .endif +# Configure ClamAV if enabled .ifdef CLAMD av_scanner = clamd: /var/run/clamav/clamd.ctl .endif +# Advertise TLS for all hosts tls_advertise_hosts = * + +# Specify paths to TLS certificate and private key tls_certificate = /usr/local/vesta/ssl/certificate.crt tls_privatekey = /usr/local/vesta/ssl/certificate.key +# Define SMTP ports (25 for standard SMTP, 465 for SMTPS, 587 for submission, 2525 as alternative) daemon_smtp_ports = 25 : 465 : 587 : 2525 + +# Define ports that use TLS-on-connect (SMTPS) tls_on_connect_ports = 465 + +# Prevent Exim from running as root never_users = root + +# Perform host lookup for all incoming connections host_lookup = * + +# Disable RFC 1413 ident queries (not commonly used) rfc1413_hosts = * rfc1413_query_timeout = 0s + +# Ignore bounce errors after 2 days ignore_bounce_errors_after = 2d + +# Remove frozen messages after 7 days timeout_frozen_after = 7d +# Configure DKIM settings for outgoing emails DKIM_DOMAIN = ${lc:${domain:$h_from:}} DKIM_FILE = /etc/exim4/domains/${lookup{${lc:${domain:$h_from:}}}dsearch{/etc/exim4/domains/}}/dkim.pem DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}} - - ###################################################################### # ACL CONFIGURATION # # Specifies access control lists for incoming SMTP mail # ###################################################################### +# Define ACL for non-SMTP (local) submissions acl_not_smtp = acl_not_smtp begin acl +# ACL for non-SMTP (local) submissions acl_not_smtp: + # Deny if the number of recipients exceeds the per-hosting-account limit deny message = Too many recipients, limit is $acl_c_max_recipients recipients - set acl_c_max_recipients=${lookup{$authenticated_id}lsearch{/etc/exim4/limit_per_hosting_account_max_recipients}{$value}{LIMIT_PER_HOSTING_ACCOUNT_MAX_RECIPIENTS}} - condition = ${if >{$rcpt_count}{$acl_c_max_recipients}} + set acl_c_max_recipients=${lookup{$authenticated_id}lsearch{/etc/exim4/limit_per_hosting_account_max_recipients}{$value}{LIMIT_PER_HOSTING_ACCOUNT_MAX_RECIPIENTS}} + condition = ${if >{$rcpt_count}{$acl_c_max_recipients}} + # Deny if the hosting account exceeds the hourly email sending limit deny message = Hosting account is sending too much emails [limitlog]: deny / account / $authenticated_id / $sender_rate / $sender_rate_period [limit=$acl_c_limit_per_hour] - set acl_c_limit_per_hour=${lookup{$authenticated_id}lsearch{/etc/exim4/limit_per_hosting_account_max_sent_emails_per_hour}{$value}{LIMIT_PER_HOSTING_ACCOUNT_MAX_SENT_EMAILS_PER_HOUR}} - ratelimit = $acl_c_limit_per_hour / 1h / $authenticated_id + set acl_c_limit_per_hour=${lookup{$authenticated_id}lsearch{/etc/exim4/limit_per_hosting_account_max_sent_emails_per_hour}{$value}{LIMIT_PER_HOSTING_ACCOUNT_MAX_SENT_EMAILS_PER_HOUR}} + ratelimit = $acl_c_limit_per_hour / 1h / $authenticated_id + # Log the sender rate for the hosting account warn ratelimit = 0 / 1h / strict / $authenticated_id - set acl_c_limit_per_hour=${lookup{$authenticated_id}lsearch{/etc/exim4/limit_per_hosting_account_max_sent_emails_per_hour}{$value}{LIMIT_PER_HOSTING_ACCOUNT_MAX_SENT_EMAILS_PER_HOUR}} - log_message = Sender rate [limitlog]: log / account / $authenticated_id / $sender_rate / $sender_rate_period [limit=$acl_c_limit_per_hour] + set acl_c_limit_per_hour=${lookup{$authenticated_id}lsearch{/etc/exim4/limit_per_hosting_account_max_sent_emails_per_hour}{$value}{LIMIT_PER_HOSTING_ACCOUNT_MAX_SENT_EMAILS_PER_HOUR}} + log_message = Sender rate [limitlog]: log / account / $authenticated_id / $sender_rate / $sender_rate_period [limit=$acl_c_limit_per_hour] - warn set acl_m3 = yes + # Set a flag for later use in the ACL + warn set acl_m3 = yes + # Accept the message accept +# ACL to check for spammers on SMTP connection acl_check_spammers: - accept hosts = +whitelist + # Accept connections from whitelisted IPs + accept hosts = +whitelist - drop message = Your host in blacklist on this server. - log_message = Host in blacklist - hosts = +spammers + # Drop connections from blacklisted IPs + drop message = Your host in blacklist on this server. + log_message = Host in blacklist + hosts = +spammers + # Accept all other connections accept - +# ACL to validate the MAIL FROM command acl_check_mail: - deny condition = ${if eq{$sender_helo_name}{}} - message = HELO required before MAIL + # Deny if the HELO name is empty + deny condition = ${if eq{$sender_helo_name}{}} + message = HELO required before MAIL - drop !authenticated = * - 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 + # Drop unauthenticated connections where HELO contains an IP address and doesn't match reverse DNS + drop !authenticated = * + 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 - drop !authenticated = * - condition = ${if isip{$sender_helo_name}} - message = Access denied - Invalid HELO name (See RFC2821 4.1.3) + # Drop unauthenticated connections where HELO is an IP address + drop !authenticated = * + condition = ${if isip{$sender_helo_name}} + message = Access denied - Invalid HELO name (See RFC2821 4.1.3) - drop !authenticated = * - condition = ${if eq{[$interface_address]}{$sender_helo_name}} - message = $interface_address is _my_ address + # Drop unauthenticated connections where HELO matches the server's own IP + drop !authenticated = * + condition = ${if eq{[$interface_address]}{$sender_helo_name}} + message = $interface_address is _my_ address + # Accept the MAIL FROM command accept - +# ACL to validate the RCPT TO command acl_check_rcpt: - accept hosts = : + # Accept local connections (no authentication needed) + accept hosts = : + # Allow deliveries to local domains on port 25 without authentication + accept domains = +local_domains + verify = recipient + + # Block unauthenticated sends on port 25 for NON-local domains (prevent relay) + deny message = SMTP auth required for port 25 + condition = ${if eq{$interface_port}{25}} + !authenticated = * + hosts = !+relay_from_hosts + domains = !+local_domains + + # Deny if the number of recipients exceeds the per-email-account limit deny message = Too many recipients, limit is $acl_c_max_recipients recipients - set acl_c_max_recipients=${lookup{$authenticated_id}lsearch{/etc/exim4/limit_per_email_account_max_recipients}{$value}{LIMIT_PER_EMAIL_ACCOUNT_MAX_RECIPIENTS}} - condition = ${if >{$rcpt_count}{$acl_c_max_recipients}} + set acl_c_max_recipients=${lookup{$authenticated_id}lsearch{/etc/exim4/limit_per_email_account_max_recipients}{$value}{LIMIT_PER_EMAIL_ACCOUNT_MAX_RECIPIENTS}} + condition = ${if >{$rcpt_count}{$acl_c_max_recipients}} + # Deny if the email account exceeds the hourly email sending limit deny message = Email account is sending too much emails [limitlog]: deny / email / $authenticated_id / $sender_rate / $sender_rate_period [limit=$acl_c_limit_per_hour] - set acl_c_limit_per_hour=${lookup{$authenticated_id}lsearch{/etc/exim4/limit_per_email_account_max_sent_emails_per_hour}{$value}{LIMIT_PER_EMAIL_ACCOUNT_MAX_SENT_EMAILS_PER_HOUR}} - ratelimit = $acl_c_limit_per_hour / 1h / $authenticated_id + set acl_c_limit_per_hour=${lookup{$authenticated_id}lsearch{/etc/exim4/limit_per_email_account_max_sent_emails_per_hour}{$value}{LIMIT_PER_EMAIL_ACCOUNT_MAX_SENT_EMAILS_PER_HOUR}} + ratelimit = $acl_c_limit_per_hour / 1h / $authenticated_id + # Log the sender rate for the email account warn ratelimit = 0 / 1h / strict / $authenticated_id - set acl_c_limit_per_hour=${lookup{$authenticated_id}lsearch{/etc/exim4/limit_per_email_account_max_sent_emails_per_hour}{$value}{LIMIT_PER_EMAIL_ACCOUNT_MAX_SENT_EMAILS_PER_HOUR}} - log_message = Sender rate [limitlog]: log / email / $authenticated_id / $sender_rate / $sender_rate_period [limit=$acl_c_limit_per_hour] + set acl_c_limit_per_hour=${lookup{$authenticated_id}lsearch{/etc/exim4/limit_per_email_account_max_sent_emails_per_hour}{$value}{LIMIT_PER_EMAIL_ACCOUNT_MAX_SENT_EMAILS_PER_HOUR}} + log_message = Sender rate [limitlog]: log / email / $authenticated_id / $sender_rate / $sender_rate_period [limit=$acl_c_limit_per_hour] - warn set acl_m3 = no - - warn !authenticated = * - hosts = !+relay_from_hosts - condition = ${if eq{${lookup{$domain}dsearch{/etc/exim4/domains/}}}{}{false}{true}} - condition = ${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}{true}{false}} - set acl_m3 = yes + # Reset the flag used earlier + warn set acl_m3 = no - deny message = Restricted characters in address - domains = +local_domains - local_parts = ^[.] : ^.*[@%!/|] + # Set flag for alias deliveries to local domains (unauthenticated) + warn !authenticated = * + hosts = !+relay_from_hosts + condition = ${if eq{${lookup{$domain}dsearch{/etc/exim4/domains/}}}{}{false}{true}} + condition = ${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}{true}{false}} + set acl_m3 = yes - deny message = Restricted characters in address - domains = !+local_domains - local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ + # Deny addresses with restricted characters in local domains + deny message = Restricted characters in address + domains = +local_domains + local_parts = ^[.] : ^.*[@%!/|] - require verify = sender + # Deny addresses with restricted characters in non-local domains + deny message = Restricted characters in address + domains = !+local_domains + local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ - accept hosts = +relay_from_hosts - control = submission + # Require sender verification + require verify = sender - accept authenticated = * - control = submission/domain= + # Accept connections from relay hosts with submission control + accept hosts = +relay_from_hosts + control = submission - deny message = Rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text - hosts = !+whitelist - dnslists = ${readfile {/etc/exim4/dnsbl.conf}{:}} + # Accept authenticated connections with submission control + accept authenticated = * + control = submission/domain= - require message = relay not permitted - domains = +local_domains : +relay_to_domains + # Deny connections from blacklisted hosts (using DNSBL) + deny message = Rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text + hosts = !+whitelist + dnslists = ${readfile {/etc/exim4/dnsbl.conf}{:}} - deny message = smtp auth requried - sender_domains = +local_domains - !authenticated = * + # Require the recipient domain to be either a local or relay domain + require message = relay not permitted + domains = +local_domains : +relay_to_domains - require verify = recipient + # Deny unauthenticated sends from local domains (require SMTP auth) + deny message = smtp auth required + sender_domains = +local_domains + !authenticated = * -.ifdef CLAMD - warn set acl_m0 = no + # Require recipient verification + require verify = recipient - warn condition = ${if exists {/etc/exim4/domains/$domain/antivirus}{yes}{no}} - set acl_m0 = yes -.endif + # Enable antivirus scanning if the domain has antivirus enabled + .ifdef CLAMD + warn set acl_m0 = no + warn condition = ${if exists {/etc/exim4/domains/$domain/antivirus}{yes}{no}} + set acl_m0 = yes + .endif -.ifdef SPAMASSASSIN - warn set acl_m1 = no - - warn condition = ${if exists {/etc/exim4/domains/$domain/antispam}{yes}{no}} - set acl_m1 = yes -.endif + # Enable antispam scanning if the domain has antispam enabled + .ifdef SPAMASSASSIN + warn set acl_m1 = no + warn condition = ${if exists {/etc/exim4/domains/$domain/antispam}{yes}{no}} + set acl_m1 = yes + .endif + # Accept the recipient accept - +# ACL to validate message data (after RCPT TO, during DATA phase) acl_check_data: - + # Deny messages from senders listed in deny_senders deny senders = /etc/exim4/deny_senders -.ifdef CLAMD - deny message = Message contains a virus ($malware_name) and has been rejected - malware = */defer_ok - condition = ${if eq{$acl_m0}{yes}{yes}{no}} -.endif + # Scan for malware if ClamAV is enabled and the domain has antivirus enabled + .ifdef CLAMD + deny message = Message contains a virus ($malware_name) and has been rejected + malware = */defer_ok + condition = ${if eq{$acl_m0}{yes}{yes}{no}} + .endif -.ifdef SPAMASSASSIN - warn !authenticated = * - hosts = !+relay_from_hosts - condition = ${if < {$message_size}{600K}} - condition = ${if eq{$acl_m1}{yes}{yes}{no}} - spam = nobody:true/defer_ok - add_header = X-Spam-Score: $spam_score_int - add_header = X-Spam-Bar: $spam_bar - add_header = X-Spam-Report: $spam_report - set acl_m2 = $spam_score_int + # Perform SpamAssassin scanning if enabled, for unauthenticated messages under 600K + .ifdef SPAMASSASSIN + warn !authenticated = * + hosts = !+relay_from_hosts + condition = ${if < {$message_size}{600K}} + condition = ${if eq{$acl_m1}{yes}{yes}{no}} + spam = nobody:true/defer_ok + add_header = X-Spam-Score: $spam_score_int + add_header = X-Spam-Bar: $spam_bar + add_header = X-Spam-Report: $spam_report + set acl_m2 = $spam_score_int - warn condition = ${if !eq{$acl_m2}{} {yes}{no}} - condition = ${if >{$acl_m2}{SPAM_SCORE} {yes}{no}} - add_header = X-Spam-Status: Yes - message = SpamAssassin detected spam (from $sender_address to $recipients). -.endif + # Mark messages as spam if the score exceeds the threshold + warn condition = ${if !eq{$acl_m2}{} {yes}{no}} + condition = ${if >{$acl_m2}{SPAM_SCORE} {yes}{no}} + add_header = X-Spam-Status: Yes + message = SpamAssassin detected spam (from $sender_address to $recipients). + .endif + # Accept the message accept - +# ACL to validate MIME parts of the message acl_check_mime: - deny message = Blacklisted file extension detected - condition = ${if match {${lc:$mime_filename}}{\N(\.ade|\.adp|\.bat|\.chm|\.cmd|\.com|\.cpl|\.exe|\.hta|\.ins|\.isp|\.jse|\.lib|\.lnk|\.mde|\.msc|\.msp|\.mst|\.pif|\.scr|\.sct|\.shb|\.sys|\.vb|\.vbe|\.vbs|\.vxd|\.wsc|\.wsf|\.wsh|\.jar)$\N}{1}{0}} + # Deny messages with blacklisted file extensions + deny message = Blacklisted file extension detected + condition = ${if match {${lc:$mime_filename}}{\N(\.ade|\.adp|\.bat|\.chm|\.cmd|\.com|\.cpl|\.exe|\.hta|\.ins|\.isp|\.jse|\.lib|\.lnk|\.mde|\.msc|\.msp|\.mst|\.pif|\.scr|\.sct|\.shb|\.sys|\.vb|\.vbe|\.vbs|\.vxd|\.wsc|\.wsf|\.wsh|\.jar)$\N}{1}{0}} + # Accept the MIME part accept - - ###################################################################### # AUTHENTICATION CONFIGURATION # ###################################################################### + begin authenticators +# Dovecot PLAIN authentication dovecot_plain: driver = dovecot public_name = PLAIN server_socket = /var/run/dovecot/auth-client server_set_id = $auth1 +# Dovecot LOGIN authentication dovecot_login: driver = dovecot public_name = LOGIN server_socket = /var/run/dovecot/auth-client server_set_id = $auth1 - - ###################################################################### # ROUTERS CONFIGURATION # # Specifies how addresses are handled # ###################################################################### + begin routers +# Uncomment to use a smarthost for outbound mail #smarthost: # driver = manualroute # domains = ! +local_domains @@ -268,20 +369,23 @@ begin routers # no_more # no_verify +# Route non-local domains via DNS lookup dnslookup: driver = dnslookup - # if outbound, and forwarding has been done, use an alternate transport + # Use a different transport for forwarded messages domains = ! +local_domains transport = ${if eq {$local_part@$domain} \ {$original_local_part@$original_domain} \ {remote_smtp} {remote_forwarded_smtp}} no_more +# Deliver spam messages to the user's Spam folder localuser_spam: driver = accept transport = local_spam_delivery condition = ${if eq {${if match{$h_X-Spam-Status:}{\N^Yes\N}{yes}{no}}} {${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}{yes}{no_such_user}}}} +# Handle user .forward files for mail forwarding userforward: driver = redirect check_local_user @@ -296,6 +400,7 @@ userforward: pipe_transport = address_pipe reply_transport = address_reply +# Handle procmail for users with a .procmailrc file procmail: driver = accept check_local_user @@ -303,6 +408,7 @@ procmail: transport = procmail no_verify +# Send autoreplies if an autoreply message exists autoreplay: driver = accept require_files = /etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/autoreply.${local_part}.msg @@ -311,23 +417,26 @@ autoreplay: transport = userautoreply unseen +# Handle inbound SRS (Sender Rewriting Scheme) for forwarded messages inbound_srs: - driver = redirect - senders = : - domains = +local_domains - # detect inbound bounces which are converted to SRS, and decode them - condition = ${if inbound_srs {$local_part} {SRS_SECRET}} - data = $srs_recipient + driver = redirect + senders = : + domains = +local_domains + # Decode SRS addresses for inbound bounces + condition = ${if inbound_srs {$local_part} {SRS_SECRET}} + data = $srs_recipient +# Fail invalid SRS addresses inbound_srs_failure: - driver = redirect - senders = : - domains = +local_domains - # detect inbound bounces which look converted to SRS but are invalid - condition = ${if inbound_srs {$local_part} {}} - allow_fail - data = :fail: Invalid SRS recipient address + driver = redirect + senders = : + domains = +local_domains + # Fail if the address looks like SRS but is invalid + condition = ${if inbound_srs {$local_part} {}} + allow_fail + data = :fail: Invalid SRS recipient address +# Handle aliases defined in domain alias files aliases: driver = redirect headers_add = X-redirected: yes @@ -337,16 +446,19 @@ aliases: pipe_transport = address_pipe unseen +# Handle forward-only accounts localuser_fwd_only: driver = accept transport = devnull condition = ${if exists{/etc/exim4/domains/$domain/fwd_only}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/fwd_only}{true}{false}}}} +# Deliver to local users localuser: driver = accept transport = local_delivery condition = ${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}{true}{false}} +# Handle catch-all aliases catchall: driver = redirect headers_add = X-redirected: yes @@ -355,20 +467,22 @@ catchall: file_transport = local_delivery redirect_router = dnslookup +# Terminate alias processing terminate_alias: driver = accept transport = devnull condition = ${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}{true}{false}} - - ###################################################################### # TRANSPORTS CONFIGURATION # ###################################################################### + begin transports +# Transport for outbound SMTP delivery remote_smtp: driver = smtp + # Uncomment to set interface and HELO dynamically #interface = ${if eq{$acl_m3}{yes}{FIRSTIP}{${lookup{$sender_address_domain}lsearch{/etc/exim4/virtual/interfaces} {$value}{SECONDIP}}}} #helo_data = "${if eq{$acl_m3}{yes}{FIRSTHOST}{${lookup{$sending_ip_address}lsearch{/etc/exim4/virtual/helo_data}{$value}{SECONDHOST}}}}" dkim_domain = DKIM_DOMAIN @@ -376,10 +490,11 @@ remote_smtp: dkim_private_key = DKIM_PRIVATE_KEY dkim_canon = relaxed dkim_strict = 0 - hosts_try_fastopen = + hosts_try_fastopen = hosts_try_chunking = !93.188.3.0/24 message_linelength_limit = 1G +# Transport for forwarded SMTP messages (with SRS rewriting) remote_forwarded_smtp: driver = smtp dkim_domain = DKIM_DOMAIN @@ -387,13 +502,13 @@ remote_forwarded_smtp: dkim_private_key = DKIM_PRIVATE_KEY dkim_canon = relaxed dkim_strict = 0 - hosts_try_fastopen = + hosts_try_fastopen = hosts_try_chunking = !93.188.3.0/24 message_linelength_limit = 1G - # modify the envelope from, for mails that we forward max_rcpt = 1 return_path = ${srs_encode {SRS_SECRET} {$return_path} {$original_domain}} +# Transport for procmail delivery procmail: driver = pipe command = "/usr/bin/procmail -d $local_part" @@ -404,6 +519,7 @@ procmail: initgroups return_output +# Transport for local mail delivery to user mailboxes local_delivery: driver = appendfile maildir_format @@ -421,6 +537,7 @@ local_delivery: quota = ${extract{6}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}M quota_warn_threshold = 75% +# Transport for delivering spam messages to the Spam folder local_spam_delivery: driver = appendfile maildir_format @@ -439,19 +556,23 @@ local_spam_delivery: quota_directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}/${lookup{$local_part}dsearch{${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}}}" quota_warn_threshold = 75% +# Transport for piped deliveries (e.g., via aliases) address_pipe: driver = pipe return_output +# Transport for file deliveries (e.g., via .forward files) address_file: driver = appendfile delivery_date_add envelope_to_add return_path_add +# Transport for autoreplies (e.g., via .forward files) address_reply: driver = autoreply +# Transport for user-defined autoreplies userautoreply: driver = autoreply file = /etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/autoreply.${extract{1}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/accounts}}}}.msg @@ -460,28 +581,26 @@ userautoreply: subject = "${if def:h_Subject: {Autoreply: \"${rfc2047:$h_Subject:}\"} {Autoreply Message}}" to = "${sender_address}" +# Transport to discard messages (used for devnull routing) devnull: driver = appendfile file = /dev/null - - ###################################################################### # RETRY CONFIGURATION # ###################################################################### + begin retry +# Retry rules for message delivery # Address or Domain Error Retries # ----------------- ----- ------- * * F,2h,15m; G,16h,1h,1.5; F,4d,6h - - ###################################################################### # REWRITE CONFIGURATION # ###################################################################### + begin rewrite - - ######################################################################