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
-- 
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Reply via email to