Hello,
I want to setup Sieve with my Exim server but can't quite figure out how
it should be integrated into my configuration.
My server provides web and mail services for multiple users. The domains
and mailbox accounts are stored in a MySQL database and Exim is set up
to look up everything from there. No local system accounts involved.
Each mailbox has a Maildir directory in /var/mail/virtual and all these
directories belong to the system user mail and group mail.
All Sieve tutorials I've found expect that I have traditional local
system users for my mailboxes and only a single domain. I know nothing
about Sieve because I haven't seen it anywhere else yet. But it seems
that Sieve uses script file(s) that should be stored in the mailbox
user's home directory. Which assumes that the user's mail is also stored
in their home directory. Like in the 70s. Unfortunately I don't have that.
I've attached my Exim configuration for reference. Can anybody please
explain how Sieve would be integrated there?
I'm especially interested in using the Sieve features of message
forwarding*, auto responders and moving messages into folders (mostly
the Junk folder) directly on the server.
*) My config has mailboxes that store mail locally as well as forwards
that only forward mail to one or more addresses. I'd also like to
temporarily forward mail that is addressed to a mailbox to another address.
The Exim version is 4.86 on Ubuntu 16.04 server. Here's the full output
from 'exim --version':
> Exim version 4.86_2 #1 built 05-Jan-2017 13:29:10
> Copyright (c) University of Cambridge, 1995 - 2015
> (c) The Exim Maintainers and contributors in ACKNOWLEDGMENTS file, 2007 - 2015
> Berkeley DB: Berkeley DB 5.3.28: (September 9, 2013)
> Support for: crypteq iconv() IPv6 PAM Perl Expand_dlfunc GnuTLS move_frozen_messages Content_Scanning DKIM Old_Demime DNSSEC PRDR OCSP
> Lookups (built-in): lsearch wildlsearch nwildlsearch iplsearch cdb dbm dbmjz dbmnz dnsdb dsearch ldap ldapdn ldapm mysql nis nis0 passwd pgsql sqlite
> Authenticators: cram_md5 cyrus_sasl dovecot plaintext spa tls
> Routers: accept dnslookup ipliteral iplookup manualroute queryprogram redirect
> Transports: appendfile/maildir/mailstore/mbx autoreply lmtp pipe smtp
> Fixed never_users: 0
> Size of off_t: 8
> Configuration file is /etc/exim4/exim4.conf
Yves
MYSQL_SERVER = 127.0.0.1
MYSQL_USER = <<DB_USER_MAIL>>
MYSQL_PASS = <<DB_PASS_MAIL>>
MYSQL_DB = <<DB_NAME>>
MAIN_HOST = <<HOST>>
MAIN_IP4 = <<IP4_1>>
MAIN_IP6 = <<IP6_1>>
# Recipient address of the mail
VAR_RCPT_ADDR = m0
# New subject header
VAR_SUBJECT = m1
# Spam-Score header
VAR_SPAM_SCORE = m2
# Spam-Report header
VAR_SPAM_REPORT = m3
MYSQL_Q_LDOMAIN = SELECT DISTINCT domain FROM mailusers WHERE domain='${quote_mysql:$domain}' LIMIT 1
MYSQL_Q_MAILDIR = SELECT maildir FROM mailusers WHERE local='${quote_mysql:$local_part}' AND domain='${quote_mysql:$domain}' AND maildir!='' LIMIT 1
MYSQL_Q_AUTH_CR1 = SELECT cryptpass FROM mailusers WHERE CONCAT(local, '@', domain)='${quote_mysql:$1}' LIMIT 1
MYSQL_Q_AUTH_CR2 = SELECT cryptpass FROM mailusers WHERE CONCAT(local, '@', domain)='${quote_mysql:$2}' LIMIT 1
MYSQL_Q_FORWARD = SELECT forward FROM mailusers WHERE (local='${quote_mysql:$local_part}' OR local='*') AND domain='${quote_mysql:$domain}' AND forward!='' LIMIT 1
MYSQL_Q_SENDERS = SELECT senders FROM mailusers WHERE (local='${quote_mysql:$local_part}' OR local='*') AND domain='${quote_mysql:$domain}' AND forward!='' LIMIT 1
MYSQL_Q_QUOTA = SELECT quota FROM mailusers WHERE local='${quote_mysql:$local_part}' AND domain='${quote_mysql:$domain}' AND forward='' LIMIT 1
MYSQL_Q_SPAMFILTER_MAIL = SELECT spamfilter FROM mailusers WHERE CONCAT(local, "@", domain)='${quote_mysql:$acl_VAR_RCPT_ADDR}' LIMIT 1
#MYSQL_Q_SPAMFILTER_RCPT = SELECT spamfilter FROM mailusers WHERE local='${quote_mysql:$local_part}' AND domain='${quote_mysql:$domain}' LIMIT 1
MYSQL_Q_VIRUSFILTER_MAIL = SELECT virusfilter FROM mailusers WHERE CONCAT(local, "@", domain)='${quote_mysql:$recipients}' LIMIT 1
#MYSQL_Q_VIRUSFILTER_RCPT = SELECT virusfilter FROM mailusers WHERE local='${quote_mysql:$local_part}' AND domain='${quote_mysql:$domain}' LIMIT 1
hide mysql_servers = "MYSQL_SERVER/MYSQL_DB/MYSQL_USER/MYSQL_PASS"
primary_hostname = MAIN_HOST
domainlist local_domains = localhost : @ : mysql;MYSQL_Q_LDOMAIN
domainlist relay_to_domains =
hostlist relay_from_hosts = 127.0.0.1
acl_smtp_mail = acl_check_mail
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_data
acl_smtp_mime = acl_check_mime
never_users = root
host_lookup = *
rfc1413_query_timeout = 0s
# message_size_limit = 50M
ignore_bounce_errors_after = 2d
timeout_frozen_after = 7d
tls_advertise_hosts = *
tls_certificate = /etc/letsencrypt/live/MAIN_HOST/fullchain.pem
tls_privatekey = /etc/letsencrypt/live/MAIN_HOST/privkey.pem
#tls_certificate = /etc/ssl/private/MAIN_HOST
#tls_privatekey = /etc/ssl/private/MAIN_HOST
tls_on_connect_ports = 465
tls_require_ciphers = NORMAL:!VERS-SSL3.0
local_interfaces = <; MAIN_IP4 ; MAIN_IP6 ; 127.0.0.1 ; ::1
daemon_smtp_ports = 25 : 465 : 587
untrusted_set_sender = "^\\$"
# smtp_enforce_sync = true
log_selector = +delivery_size +sender_on_delivery +received_recipients
log_file_path = /var/log/exim4/%s-%D.log : syslog
syslog_timestamp = false
syslog_duplication = false
#spamd_address = /var/run/spamd_socket
spamd_address = 127.0.0.1 783
av_scanner = clamd:/var/run/clamav/clamd.ctl
errors_reply_to = <<MAIL_ADDR_ADMIN>>
bounce_message_file = /etc/exim4/bounce_message.txt
warn_message_file = /etc/exim4/warn_message.txt
add_environment = <; PATH=/bin:/usr/bin
keep_environment =
begin acl
acl_check_mail:
# Rate limiting on all messages per host
defer ratelimit = 50 / 5m / strict
message = Sending rate exceeded. Try again later.
log_message = Sending rate exceeded: $sender_rate/$sender_rate_period (max $sender_rate_limit)
# Keep authenticated users under control
deny authenticated = *
ratelimit = 10 / 5m / strict / $authenticated_id
# System-wide rate limit
defer message = Sorry, too busy. Try again later.
ratelimit = 100 / 10s / $primary_hostname
accept
acl_check_rcpt:
#warn control = dkim_disable_verify
accept hosts = :
deny domains = +local_domains
message = restricted characters in address
local_parts = ^[.] : ^.*[@%!/|]
deny domains = !+local_domains
message = restricted characters in address
local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
require verify = sender
accept hosts = +relay_from_hosts
accept authenticated = *
defer message = only one recipient at a time
condition = ${if def:acl_VAR_RCPT_ADDR {1}{0}}
accept domains = +local_domains
control = submission/sender_retain
endpass
message = unknown user
verify = recipient
set acl_VAR_RCPT_ADDR = $local_part@$domain
accept domains = +relay_to_domains
endpass
message = unrouteable address
verify = recipient
set acl_VAR_RCPT_ADDR = $domain
deny message = relay not permitted
acl_check_data:
# put headers in all messages (no matter if spam or not)
warn !authenticated = *
condition = ${if <{$message_size}{5242880}{1}{0}}
spam = nobody:true
set acl_VAR_SPAM_SCORE = $spam_score ($spam_bar)
set acl_VAR_SPAM_REPORT = $spam_report
warn !authenticated = *
condition = ${if <{$message_size}{5242880}{1}{0}}
spam = nobody:true
condition = ${if >={$spam_score_int}{50}{1}{0}}
set acl_VAR_SUBJECT = $header_Subject: *** Spam $spam_score
# drop spam from mailing lists
# discard !authenticated = *
# condition = ${if <{$message_size}{5242880}{1}{0}}
# spam = nobody:true
# condition = ${if >{${strlen:$header_List-Id }}{0}}
# condition = ${if >={${lookup mysql{MYSQL_Q_SPAMFILTER_MAIL}{$value}}}{30} {1} {0}}
# condition = ${if >={$spam_score_int}{${lookup mysql{MYSQL_Q_SPAMFILTER_MAIL}{$value}}} {1} {0}}
# add_header = X-Spam-Score: $spam_score ($spam_bar)
# add_header = X-Spam-Report: $spam_report
# message = This message scored $spam_score spam points.
# reject spam at high scores (see database value, minimum score for reject is 10 = 1.0)
deny !authenticated = *
condition = ${if <{$message_size}{5242880}{1}{0}}
spam = nobody:true
condition = ${if >={${lookup mysql{MYSQL_Q_SPAMFILTER_MAIL}{$value}}}{10} {1} {0}}
condition = ${if >={$spam_score_int}{${lookup mysql{MYSQL_Q_SPAMFILTER_MAIL}{$value}}} {1} {0}}
add_header = X-Spam-Score: $spam_score ($spam_bar)
add_header = X-Spam-Report: $spam_report
message = This message scored $spam_score spam points.
deny condition = ${lookup mysql{MYSQL_Q_VIRUSFILTER_MAIL}{$value}}
malware = *
message = This message was detected as possible malware ($malware_name).
accept
acl_check_mime:
deny condition = ${lookup mysql{MYSQL_Q_VIRUSFILTER_MAIL}{$value}}
condition = ${if match{${lc:$mime_filename}}{\.lnk\$|\.pif\$|\.scr\$}{true}}
message = This message contains unwanted attachments.
accept
begin routers
dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more
virtual_forward:
driver = redirect
forbid_file
forbid_pipe
data = ${lookup mysql{MYSQL_Q_FORWARD}{$value}}
# ^-- insert :unknown: here (?)
virtual_user:
driver = redirect
allow_fail
allow_defer
data = ${lookup mysql{MYSQL_Q_MAILDIR}{$value}fail}
address_data = ${lookup mysql{MYSQL_Q_QUOTA}{$value}fail}
file_transport = address_directory
cannot_route_message = Unknown user
begin transports
remote_smtp:
driver = smtp
address_pipe:
driver = pipe
return_output
address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add
address_directory:
driver = appendfile
maildir_format
maildir_tag = ,S=$message_size
maildir_use_size_file
user = mail
quota = $address_data
delivery_date_add
envelope_to_add
return_path_add
quota_warn_threshold = 80%
quota_warn_message = "\
To: $local_part@$domain\n\
Subject: Ihr Postfach ist fast voll!\n\
\n\
(...)\n"
headers_remove = X-Virus*:X-Virus-Scanned:X-Spam-DCC:X-SpamChecker-Version:\
X-Spam-Status:X-Spam-RBL:X-Spam-Eval\
${if !eq {$acl_VAR_SUBJECT}{} {::Subject}{}}\
${if !eq {$acl_VAR_SPAM_SCORE}{} {::X-Spam-Score}{}}\
${if !eq {$acl_VAR_SPAM_REPORT}{} {::X-Spam-Report}{}}
headers_add = ${if !eq {$acl_VAR_SUBJECT}{} {Subject: $acl_VAR_SUBJECT\n}{}}\
${if !eq {$acl_VAR_SPAM_SCORE}{} {X-Spam-Score: $acl_VAR_SPAM_SCORE\nX-Spam-mysite-Info: Diese Nachricht wurde vom mysite-Mailserver geprueft.\n}{}}\
${if !eq {$acl_VAR_SPAM_REPORT}{} {X-Spam-Report: $acl_VAR_SPAM_REPORT\n}{}}
address_reply:
driver = autoreply
begin retry
# Domain Error Retries
* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
begin rewrite
begin authenticators
fixed_plain:
driver = plaintext
public_name = PLAIN
server_prompts = :
server_condition = ${if \
crypteq {$3}{${lookup mysql{MYSQL_Q_AUTH_CR2}{$value}fail}} \
{yes}{no}}
server_set_id = $2
login:
driver = plaintext
public_name = LOGIN
server_prompts = Username:: : Password::
server_condition = ${if \
crypteq {$2}{${lookup mysql{MYSQL_Q_AUTH_CR1}{$value}fail}} \
{yes}{no}}
server_set_id = $1