Nachfolgend eine kurze Zusammenfassung der wichtigsten Erkenntnisse aus dem Studium folgender URLs. Anschließend steht ein vollwertiges Mailsetup zur Verfügung, um E-Mails aus dem Internet empfangen und ins Internet senden zu können. Darüber hinaus kann auf die E-Mails mit IMAP oder einem Webclient zugegriffen werden.

http://www.debian.org/releases/stable/s390/ch08s05.html.de
http://koivi.com/exim4-config/ (Sehr alt)
http://www.freesoftwaremagazine.com/articles/exim_and_anti_spam_spamassassin (Viele kleine Fehler)
http://wiki.exim.org/MaildirSpamDelivery
http://workaround.org/pipermail/workaround-chitchat/2010-June/002055.html
http://wiki.dovecot.org/ManageSieve/Configuration
Und natürlich: http://www.exim.org/exim-html-current/doc/html/spec_html/index.html

Part 1: Exim4 einrichten

$ apt-get install exim4-daemon-heavy exim4-config
$ dpkg-reconfigure exim4-config

Folgende Optionen auswählen: Internet-Seite, Maildir-Format, Mehrere Konfigurationsdateien

$ apt-get install spamassasin clamav-daemon clamav-freshclam
$ nano /etc/default/spamassasin

Folgende Parameter ändern:

ENABLE=1
CRON=1

Spamassasin und Clamav starten:

$ /etc/init.d/spamassassin start
$ /etc/init.d/clamav-daemon start

Nun exim4 dazu bringen, eingehende E-Mails mit ClamAV und Spamassasin zu prüfen.

$ nano /etc/exim4/conf.d/acl/40_exim4-config_check_data

Dabei nur die vorgesehenen und auskommentierten Abschnitte zu Malware und Spam am Ende der Datei ändern:

  deny
    malware = *
    message = This message was detected as possible malware ($malware_name).

  warn
    spam = Debian-exim:true
    condition = ${if and{{<={$message_size}{500k}}{!={$h_X-DES-Spam-Checked:}{}}}}
    message = X-Spam-Score: $spam_score\n\
              X-Spam-Score-Int: $spam_score_int\n\
              X-Spam-Bar: $spam_bar\n\
              X-DES-Spam-Checked: True

Von ClamAV identifizierte Malware wird einfach abgelehnt. Das Ergebnis der Spam-Prüfung wird in den neuen Header Fields X-Spam-Score, X-Spam-Score-Int und X-Spam-Bar dokumentiert. Dabei werden nur E-Mails bis 500 kiB geprüft, weil Spam-Nachrichten in der Regel klein sind und größere Nachrichten meistens nur Malware enthalten, die zuvor schon herausgefiltert wurde. Außerdem kann Spamassasin bei großen Nachrichten den Server zu sehr auslasten. Das Feld X-DES-Spam-Checked soll verhindern, dass eine Mail zweimal geprüft wird, was vorkommen kann, wenn Exim4 zusammen mit Mailman benutzt wird. In diesem Fall würden alle Spam-Felder zweimal in die Mail aufgenommen werden, was zu Problemen im globalen Systemfilter führen würde, da die ausgelsenen Felder keinen reinen Integerwerte sondern einen Zeilenumbruch in der Mittel beinhalten würden.

Auf den $spam_report wird bewusst verzichtet, da er die E-Mail nur unnötig lang macht und sich die ACL-Regeln dadurch nur verkomplizieren. Stattdessen sollen alle möglichen Spam-Mails ab einem Score von 5.0 in einen Spam-Ordner der einzelnen Maildirs einsortiert werden. Zusätzlich sollen alle Nachrichten mit einem Score ab 10.0 im Betreff durch [ SPAM ] gekennzeichnet werden, so dass der Spamordner auch mit dem bloßen Auge schnell durchsucht werden kann. Für beide Features brauchen wir den Spam-Report nicht.

Die Kennzeichnung der besonders verdächtigen Spam-Mails kann durch den System-Filter erfolgen, der zunächst aktiviert werden muss:

$ nano /etc/exim4/conf.d/main/02_exim4-config_options

Dort ziemlich am Anfang folgende Zeilen einfügen:

system_filter = "/etc/exim4/system.filter"
system_filter_user = Debian-exim
system_filter_group = Debian-exim
system_filter_pipe_transport = address_pipe
system_filter_file_transport = address_file
system_filter_reply_transport = address_reply

Der System-Filter kann nun in der Datei /etc/exim4/system.filter konfiguriert werden. Besonders wichtig ist die Prüfung auf Existenz des X-Spam-Score-Int Header Fields ($h_X-Spam-Score-Int is not ""). Denn sonst entsteht beim Starten und Stoppen von exim4 ein Eintrag im paniclog, der zu einer Warnung auf der Konsole führt. Durch die Prüfung der Empfänger-Adresse wird sichergestellt, dass die Regel nur für eingehende Mails ausgeführt wird.

$ nano /etc/exim4/system.filter
if $h_X-Spam-Score-Int is not "" and $h_X-Spam-Score-Int is above 99
    and foranyaddress $recipients ($thisaddress contains "@meine-domain.de")
    then
    headers add "Old-Subject: $h_Subject:"
    headers remove "Subject"
    headers add "Subject: [ SPAM ] $h_Old-Subject:"
    headers remove "Old-Subject"
finish endif

Fehlt nurnoch das Einsortieren aller Spam-Mails in den Spam-Ordner der einzelnen User. Die meisten Internetseiten schlagen hier den Einsatz benutzerabhängiger Filter in der Datei ~/.forward vor, die natürlich auch unter /etc/skel angelegt werden sollte. Das ist natürlich eine gültige Lösung, ich bevorzuge jedoch eine systemweit einheitliche Lösung. Darum wird laut exim-Wiki ein neuer Router (für die Untersuchung der Nachricht) und ein neuer Transport (für die Speicherung im Spamordner) benötigt. Diese werden debiantypisch in zwei neuen Konfigurationsdateien angelegt. Der Router muss dabei der vorletzte vor 900_exim4-config_local_user sein, damit eine Spam-Nachricht nicht zuvor in das normale Maildir einsortiert wird.

$ nano /etc/exim4/conf.d/router/860_exim4-config_DES_spam
maildir_spam:
  debug_print = "R: DES - Spam (local_user for $local_part@$domain)"
  driver = accept
  domains = +local_domains
  check_local_user
  local_parts = ! root
  transport = maildir_spam_delivery
  condition = ${if >{$h_X-Spam-Score-Int:}{49}}

$ nano /etc/exim4/conf.d/transport/40_exim4-config_DES_spam
maildir_spam_delivery:
  debug_print = "T: DES - Spam (maildir_spam_delivery for $local_part@$domain)"
  driver = appendfile
  .ifdef MAILDIR_HOME_MAILDIR_LOCATION
  directory = MAILDIR_HOME_MAILDIR_LOCATION/.Spam
  .else
  directory = $home/Maildir/.Spam
  .endif
  .ifdef MAILDIR_HOME_CREATE_DIRECTORY
  create_directory
  .endif
  .ifdef MAILDIR_HOME_CREATE_FILE
  create_file = MAILDIR_HOME_CREATE_FILE
  .endif
  delivery_date_add
  envelope_to_add
  return_path_add
  maildir_format
  .ifdef MAILDIR_HOME_DIRECTORY_MODE
  directory_mode = MAILDIR_HOME_DIRECTORY_MODE
  .else
  directory_mode = 0700
  .endif
  .ifdef MAILDIR_HOME_MODE
  mode = MAILDIR_HOME_MODE
  .else
  mode = 0600
  .endif
  mode_fail_narrower = false
  # This transport always chdirs to $home before trying to deliver. If
  # $home is not accessible, this chdir fails and prevents delivery.
  # If you are in a setup where home directories might not be
  # accessible, uncomment the current_directory line below.
  # current_directory = /

Zuletzt müssen noch alle Domains gepflegt werden, für die Exim Mails empfangen kann:
$ nano /etc/exim4/update-exim4.conf.conf
dc_other_hostnames='pingu-mobil.de;linux-sis.org'

Das war die gesamte Konfiguration. Nun kann der Mailserver getestet werden. Dabei immer schön auf etwaige Fehlerausgaben achten und ggf. die Logs im Verzeichnis /var/log/exim4 überprüfen.

$ update-exim4.conf
$ exim4 -bV
$ /etc/init.d/exim4 restart
$ exim4 -bt
benutzer@meine-domain.de
$ exim4 -v benutzer@meine-domain.de
From: test@beispiel.de
To: benutzer@meine-domain.de
Subject: Test
Leerzeile
Dies ist ein Test.
.
^D

Anschließend kann man die empfangene Mail überprüfen und schauen, ob die X-Spam-Felder im Header enthalten sind:

$ more ~/Maildir/new/MAIL-ID

Damit ist die Einrichtung von exim4 abgeschlossen. Zum endgültigen Test sollte man noch den Empfang externer Nachrichten und auch den Versand nach extern testen. Mit dem Wormly SMTP-Server Test kann man noch prüfen, ob Mails an interne Empfänger angenommen und Mails an fremde Empfänger (Relaying) abgelehnt werden.

Part 2: Dovecot-Imapd einrichten

Jetzt da dank exim4 E-Mails empfangen und gesendet werden können, fehlt noch eine Möglichkeit, auf diese zuzugreifen, wenn man nicht gerade auf einer Konsole des Servers angemeldet ist. Diese Aufgabe kann Dovecot übernehmen.

$ apt-get install dovecot-imapd

Sollte dabei im Protokoll folgender Eintrag entstehen, kann dies damit zusammenhängen, dass der verantwortungsvolle Admin den Root-Acount des Systems gesperrt hat. Der Eintrag kann aber ignoriert werden, da der Systemuser dovecot dennoch richtig angelegt wurde:

Your account has expired; please contact your system administrator
chfn: PAM authentication failed
adduser: `/usr/bin/chfn -f Dovecot mail server dovecot' returned error code 1. Exiting.

Jetzt kann die zentrale Konfigurationsdatei angepasst werden:

$ nano /etc/dovecot/dovecot.conf
...
# Protocols we want to be serving: imap imaps pop3 pop3s managesieve
# If you only want to use dovecot-auth, you can set this to "none".
#protocols = imap imaps
protocols = imap imaps managesieve

...
listen = *, [::]

# Disable LOGIN command and all other plaintext authentications unless
# SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP
# matches the local IP (ie. you're connecting from the same computer), the
# connection is considered secure and plaintext authentication is allowed.
disable_plaintext_auth = yes

...
mail_location = maildir:~/Maildir

...
# Show more verbose process titles (in ps). Currently shows user name and
# IP address. Useful for seeing who are actually using the IMAP processes
# (eg. shared mailboxes or if same uid is used for multiple accounts).
verbose_proctitle = yes

...
protocol lda {
  # Address to use when sending rejection mails (e.g. postmaster@example.com).
  postmaster_address = root@developer-showcase.de

...
  # Support for dynamically loadable plugins. mail_plugins is a space separated
  # list of plugins to load.
  mail_plugins = sieve


...
  # Subject: header to use for rejection mails. You can use the same variables
  # as for rejection_reason below.
  rejection_subject = Rejected: %s

  # Human readable error message for rejection mails. You can use variables:
  #  %n = CRLF, %r = reason, %s = original subject, %t = recipient
  rejection_reason = Your message to <%t> was automatically rejected:%n%r
...
}

...
auth default {
  # Space separated list of wanted authentication mechanisms:
  #   plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp skey
  #   gss-spnego
  # NOTE: See also disable_plaintext_auth setting.
  mechanisms = plain login

...
  # Sieve plugin (http://wiki.dovecot.org/LDA/Sieve) and ManageSieve service
  #
  # Location of the active script. When ManageSieve is used this is actually
  # a symlink pointing to the active script in the sieve storage directory.
  sieve=~/.dovecot.sieve
  #
  # The path to the directory where the personal Sieve scripts are stored. For
  # ManageSieve this is where the uploaded scripts are stored.
  sieve_dir=~/sieve

Jetzt den IMAP-Server durchstarten und testen, ob ein Login z.B. mit Thunderbird funktioniert. Zuvor prüfen, ob beim Durchstarten ein Fehler aufgetreten ist.

$ /etc/init.d/dovecot restart
$ tail /var/log/mail.err

Auf den IMAP-Server sollte aus Sicherheitsgründen immer verschlüsselt via SSL zugegriffen werden, denn die obige Konfiguration unterstützt keine sichere Passwortübertragung bei einer unverschlüsselten Verbindung. Demnach funktioniert auch die Thunderbird-Option "Use secure authentication" nicht.

Part 3: Mailzustellung per Dovecot LDA, wegen Sieve

Das bisheriger Setup sorgt dafür, dass alle Nachrichten von Exim direkt in das jeweilige Maildir der Benutzer gestellt werden. Für Spamnachrichten ist dies in Ordnung, alle anderen Mails sollen jedoch nicht von Exim direkt zugestellt werden. Stattdessen soll der eben eingerichtete Dovecot LDA verwendet werden, damit benutzerspezifische Sieveregeln ausgewertet werden können.

Zunächst muss ein neuer Transport definiert werden:

$ nano /etc/exim4/conf.d/transport/30_exim4-config_DES_dovecot_lda
dovecot_lda_pipe:
  debug_print = "T: dovecot_lda_pipe for $local_part@$domain"
  driver = pipe
  command = /usr/lib/dovecot/deliver
  message_prefix =
  message_suffix =
  log_output
  delivery_date_add
  envelope_to_add
  return_path_add
  #group = mail
  #mode = 0660
  temp_errors = 64 : 69 : 70: 71 : 72 : 73 : 74 : 75 : 78

Dann muss das Debianmakro LOCAL_DELIVERY angepasst werden, damit die der neue Transport auch verwendet wird. Der Inhalt wird in der Datei /etc/exim4/update-exim4.conf.conf angepasst, obwohl das Makro selbst in /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs definiert ist.

$nano /etc/exim4/update-exim4.conf.conf
...
dc_localdelivery='dovecot_lda_pipe'

Durch folgende Befehle wird die neue Konfiguration aktiv:

$ update-exim4.conf
$ exim4 -bV
$ /etc/init.d/exim4 restart

Part 4: Roundcube einrichten

Roundcube ist ein Webclient, der den Zugriff auf einen lokalen IMAP-Server ermöglicht. Somit steht den Benutzern eine komfortable Weboberfläche für den Zugriff auf ihre Mails zur Verfügung, die sich deutlich vom angestaubten Squirrelmail abhebt.

$ apt-get install apache2 roundcube roundcube-mysql roundcube-plugins mysql-server mysql-client

Als Datenbank-Backend soll aus Performancegründen MySQL verwendet werden. Bei der Installation wird man dabei zunächst aufgefordert ein Admin-Passwort für MySQL zu vergeben. Dieses sollte man sich gut merken, den das Konfigurationsskript von Roundcube benötigt es, um seine Tabellen anlegen zu können.

Im einfachsten Fall soll der Apache-Server keine virtuellen Hosts anbieten. In diesem Fall genügt es, die Alias-Definitionen der Datei /etc/apache2/conf.d/roundcube zu aktivieren, wobei die Datei ein Symlink auf /etc/roundcube/apache.conf ist. Anstatt dem Prefix /roundcube bevorzuge ich jedoch einen sprechenderen Namen wie /webmail.

$ nano /etc/apache2/conf.d/roundcube
# Those aliases do not work properly with several hosts on your apache server
# Uncomment them to use it or adapt them to your configuration
Alias /webmail/program/js/tiny_mce/ /usr/share/tinymce/www/
Alias /webmail /var/lib/roundcube
...

Anschließend muss die Roundcube-Konfiguration angepasst werden:

$ nano /etc/roundcube/main.inc.php
...
// enforce connections over https
// with this option enabled, all non-secure connections will be redirected.
// set the port for the ssl connection as value of this option if it differs from the default 443
$rcmail_config['force_https'] = TRUE;

// the mail host chosen to perform the log-in
// leave blank to show a textbox at login, give a list of hosts
// to display a pulldown menu or set one host as string.
// To use SSL/TLS connection, enter hostname with prefix ssl:// or tls://
$rcmail_config['default_host'] = 'localhost';

// IMAP auth type. Can be "auth" (CRAM-MD5), "plain" (PLAIN) or "check" to auto detect.
// Optional, defaults to "check"
$rcmail_config['imap_auth_type'] = plain;

...
// This domain will be used to form e-mail addresses of new users
// Specify an array with 'host' => 'domain' values to support multiple hosts
$rcmail_config['mail_domain'] = 'developer-showcase.de';

...
// SMTP username (if required) if you use %u as the username RoundCube
// will use the current username for login
$rcmail_config['smtp_user'] = '%u';

// SMTP password (if required) if you use %p as the password RoundCube
// will use the current user's password for login
$rcmail_config['smtp_pass'] = '%p';

...
// How many seconds must pass between emails sent by a user
$rcmail_config['sendmail_delay'] = 10;

...
/ check client IP in session athorization
$rcmail_config['ip_check'] = true;

...
// store spam messages in this mailbox
$rcmail_config['junk_mbox'] = 'Spam';

...
// display these folders separately in the mailbox list.
// these folders will also be displayed with localized names
$rcmail_config['default_imap_folders'] = array('INBOX', 'Drafts', 'Sent', 'Spam', 'Trash');

// automatically create the above listed default folders on login
$rcmail_config['create_default_folders'] = TRUE;

...
// Enable DNS checking for e-mail address validation
$rcmail_config['email_dns_check'] = true;

...
// List of active plugins (in plugins/ directory)
$rcmail_config['plugins'] = array("managesieve");

...
// display remote inline images
// 0 - Never, always ask
// 1 - Ask if sender is not in address book
// 2 - Always show inline images
$rcmail_config['show_images'] = 1;

// compose html formatted messages by default
$rcmail_config['htmleditor'] = TRUE;

...
// default setting if preview pane is enabled
$rcmail_config['preview_pane'] = TRUE;

...
// If true all folders will be checked for recent messages
$rcmail_config['check_all_folders'] = TRUE;

Anschließend muss noch die Konfiguration des managesieve-Plugins von Roundcube angepasst werden. Dabei ist die Standardkonfiguration, die von Debian installiert wird, leer. Eine gute Vorlage wird aber mitgeliefert.

$ cd /etc/roundcube/plugins/managesieve
$ rm config.inc.php

$ cp /usr/share/roundcube/plugins/managesieve/config.inc.php.dist .
$ mv config.inc.php.dist config.inc.php

Achtung: Neuere Versionen von Roundcube besitzen die sehr fragwürdige Voreinstellung, den Google Spellcheck zu benutzen. um E-Mails vor dem Versand auf Rechtschreibfehler zu prüfen. Um dies zu umgehen, kann man sich einen eigenen Spellserver einrichten, der zu dem von Google kompatibel ist (NoxSpell).

$ cd /opt
$ wget http://orangoo.com/labs/uploads/NoxSpellServer.zip
$ unzip NoxSpellServer.zip
$ mv NoxSpellServer noxspell
$ python /opt/noxspell/nox_server.py 14003 &

Natürlich soll der Server beim Systemstart automatisch starten:

$ nano /etc/rc.local
python /opt/noxspell/nox_server.py 14003 &

In der Roundcubekonfiguration ändert man folgende Option ab:

$ nano /etc/roundcube/main.inc.php
...
// For a locally installed Nox Spell Server, please specify the URI to call it.
// Get Nox Spell Server from http://orangoo.com/labs/?page_id=72
// Leave empty to use the Google spell checking service, what means
// that the message content will be sent to Google in order to check spelling
$rcmail_config['spellcheck_uri'] = 'http://localhost:14003/?lang=';

Damit ist auch dieses Scheckgespenst gebändigt. Bleibt nurnoch der Neustart des Webservers und ein einfacher Funktionstest übrig.

$ make-ssl-cert generate-default-snakeoil
$ a2enmod ssl
$ a2ensite default-ssl
$ /etc/init.d/apache2 restart

Das war's! Damit ist der Mailserver komplet eingerichtet.

Errata: Anpassungen an Dovecot 2.x

Mit Dovecot 2 ändern sich ein Paar Konfigurationsoptionen und Debian organisiert die Konfiguration nun nicht mehr in einer monolithischen Datei. Stattdessen setzt sich die Konfiguration aus mehreren kleinen Dateien im Ordner /etc/dovecot/conf.d/ zusammen. Die alte Konfigurationsdatei von Dovecot 1.x kann mit Version 2.x nicht mehr genutzt werden, weil einige Optionen umbenannt wurden. Beim Start von Dovecot wird man auf diese Änderungen hingewiesen; die größte Änderung ist, dass die Protokolle managesieve und sieve zusammengefasst wurden und auf Port 4190 anstatt 2000 reagieren.

So sieht eine migrierte Konfigurationsdaten (selbe Einstellungen wie oben in diesem Artikel) aus, ohne die gesplitteten Konfigurationsdateien zu berücksichtigen. Wegen der Kompatibilität zu Roundcube wurden für Sieve sowohl der alte als auch der neue Port freigeschaltet.

Nähere Informationen stehen im Dovecot 2-Wiki:

http://wiki2.dovecot.org/
http://wiki2.dovecot.org/Pigeonhole/Sieve/Configuration
http://wiki2.dovecot.org/Pigeonhole/ManageSieve/Configuration

/etc/dovecot/dovecot.conf (Migiriert zu Dovecot 2.x)
# ---------------------------------------------------
# 2.0.12: /etc/dovecot/dovecot.conf
# OS: Linux 2.6.30.2-domU-v4 i686 Debian wheezy/sid
# ---------------------------------------------------
auth_mechanisms = plain login
listen = *, [::]
log_timestamp = "%Y-%m-%d %H:%M:%S "

mail_location = maildir:~/Maildir
mail_privileged_group = mail

protocols = imap sieve
verbose_proctitle = yes

ssl_cert = </etc/ssl/certs/dovecot.pem
ssl_key = </etc/ssl/private/dovecot.pem

passdb {
  driver = pam
}
service auth {
  user = root
}
userdb {
  driver = passwd
}

# -----------------------------------
# Sieve and managesieve configuration
# -----------------------------------
protocol sieve {
  managesieve_logout_format = bytes ( in=%i : out=%o )
}

service managesieve-login {
  # Specify an alternative address:port the daemon must listen on
  inet_listener sieve {
    port = 4190
  }

  inet_listener sieve_deprecated {
    port = 2000
  }
}

plugin {
  sieve = ~/.dovecot.sieve
  sieve_dir = ~/sieve
}

protocol lda {
  mail_plugins = $mail_plugins sieve
}


attachments

imageappend Append an Image
>