Der perfekte Mail-Server

Vorwort

Jeder G33k träumt irgendwann davon, seinen eigenen Mail-Server laufen zu haben. So ging es mir auch und ich wollte einfach nicht locker lassen. Unzählige Stunden habe ich damit verbracht, Informationen zusammenzukratzen, HowTos gewälzt, Dokumentationen und Bücher gelesen. Wer mal ein wenig seine Suchmaschine zu dem Thema befragt, wird sich fragen: „Warum schreibt der Typ mit dem alternativen Betriebssystem auch so viel Stuss dazu?!“ Ganz einfach: ich bin (wie so oft) unzufrieden mit dem, was bereits an Anleitungen existiert. In diesem Umfang gibt es im gesamten Internet kein einziges zeitgemäßes HowTo, welches wirklich ohne Zicken out-of-the-Box funktioniert. „Aha, und darum nennt er es gleich perfekt?“ - nun, ja! Ich garantiere euch, dass diese Anleitung auf einem frischen Debian 5 „Lenny“ zu einhundert Prozent funktionieren wird! Das komplette HowTo wurde - während ich es geschrieben habe - auf eben jenem erwähnten System getestet und entwickelt. Somit ist es auch „Debian-typisch“ und rein darauf ausgelegt, unter Ubuntu könnte sich einiges anders verhalten. Ich habe auch viele „Bugs“ dokumentiert, die keine sind sondern lediglich etwas versteckte oder gar nicht dokumentierte Features. Diese Anleitung umfasst die Einrichtung folgender Software-Komponenten (Versionsnummern sind zu beachten!):

Voraussetzungen

Damit dieses Setup von Erfolg gekrönt wird müssen folgende Bedingungen erfüllt sein:

  • Der Server ist mit mindestens einer statischen IP mit dem Internet verbunden.
    • dazu zählen keinesfalls dynamische IPs wie von privaten ISPs vergeben!
  • Eine funktionierende DNS-Konfiguration muss vorhanden sein.
    • dazu gehört ein MX-Record und der PTR.
    • DynDNS fällt da nicht hinein!

Software

Nun, was bleibt mir noch zu sagen: wer aufmerksam ließt und wenigstens über Linux-Basiswissen verfügt, sollte… abhauen! Das hier ist nur was für Profis :-D Auf geht´s ab geht´s, ran an die Shell!

Für den Großteil der Shell-Befehle sind root-Rechte erforderlich! Ich empfehle, ohne sudo in einer Root-Shell zu agieren!

Vorbereitung

Für diese Anleitung werden noch ein paar spezielle Software Repositories benötigt. Dotdeb.org stellt u.A. aktuelle Stable Releases von MySQL 5.1 und PHP 5.3 vor, welche zum Einsatz kommen. Für die neuesten LAMP Komponenten bindet man folgendes Repo ein:

/etc/apt/sources.list
deb http://packages.dotdeb.org oldstable all
deb-src http://packages.dotdeb.org oldstable all

Wer so wie ich mit PHP 5.3 arbeiten will, fügt noch diese Repos hinzu, andernfalls wird PHP 5.2 aus den Debian Quellen installiert:

/etc/apt/sources.list
deb http://php53.dotdeb.org oldstable all
deb-src http://php53.dotdeb.org oldstable all

Damit apt den Repositories vertraut importieren wir noch den Public Key:

gpg --keyserver keys.gnupg.net --recv-key 89DF5277
gpg -a --export 89DF5277 | apt-key add -

Ich verwende Features, über die der IMAP-Server dovecot-imapd erst ab der Version 1.2 verfügt, somit benötigen wir noch das Debian Backports Repository:

/etc/apt/sources.list
deb http://backports.debian.org/debian-backports lenny-backports main

Schließlich noch ein

apt-get update

und es kann weiter gehen :-)

Installation

Neben MTA, IMAP und anderen Mail-Diensten wird noch ein einsatzfähiges LAMP-System benötigt.

MySQL

Sollte jemand Debian minimal nutzen, wäre es sinnvoller, Postfix vor MySQL zu installieren, dann erspart man sich das Nachladen von exim4!

Herzstück unseres neuen Mail-Servers - welcher selbst aus mehreren Server-Diensten bestehen wird - ist der freie Datenbankserver MySQL von Sun (bzw. Oracle), wir installieren Server- und Client-Komponente:

aptitude install mysql-server-5.1 mysql-client-5.1

Während der Installation wird man vom Paketmanager aufgefordert, ein neues Passwort für den MySQL-Superuser root einzugeben, ein entsprechend langer und zufälliger String ist empfehlenswert. Wir werden das Passwort später noch brauchen.

Apache & PHP

Unser LAMP ist fast komplett. Als Webserver setze ich Apache 2.2.x ein, Webmail sowie Admin-Frontend benötigen PHP. Die aktuelle Version 5.3 holt man sich aus dem Dotdeb-Repo:

aptitude install libapache2-mod-php5

Das Modul libapache2-mod-php5 installiert (durch die Abhängigkeiten) alle notwendigen Pakete nach. Letztendlich noch

invoke-rc.d apache2 restart

ausführen damit PHP-Dateien geparst werden. Somit wäre der Linux Apache MySQL PHP-Server fertig.

Postfix Admin

Zur komfortablen Verwaltung von Domains, Aliasen und Mailboxen eignet sich die Web-Applikation Postfix Admin, für die ebenfalls ein .deb-Paket vorliegt. Vor der Installation müssen noch ein paar notwendige Pakate geholt werden:

aptitude install php5-mysql php5-imap dbconfig-common wwwconfig-common

Danach geht es gleich weiter mit Postfix Admin:

wget "http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-2.3.1/postfixadmin_2.3.1_all.deb?use_mirror=switch&ts=1280252995"
dpkg -i postfixadmin_2.3.1_all.deb

Im erscheinenden Menü wählt man die folgenden Optionen (nicht alle müssen aufscheinen):

  • Web server to reconfigure automatically: - apache2
  • Konfigurieren der Datenbank für postfixadmin mit dbconfig-common? - Ja
  • Datenbanktyp, der durch das Paket postfixadmin benutzt werden soll: - mysql
  • Passwort des Datenbank-Administrators: - das von dir vergebene Passwort :-)
  • MySQL-Anwendungspasswort für postfixadmin: - neues Passwort für den Nutzer postfixadmin, wird später noch benötigt
  • Wie wollen Sie mit config.inc.php verfahren? - Version des Paket-Betreuers installieren

Sollte hier ein Fehler passiert sein hilft einem der Befehl dpkg-reconfigure postfixadmin weiter. Da PHP-Extensions installiert wurden, den Indianer neu starten:

invoke-rc.d apache2 restart

phpMyAdmin (optional)

Zur bequemen Administration der MySQL-Datenbanken eignet sich nach wie vor das Frontend phpMyAdmin sehr gut:

aptitude install phpmyadmin

Es wird u.A. noch php5-gd und php5-mcrypt nachinstalliert. Auch hier wird man noch durch einen „Wizard“ geführt:

  • Webserver, die automatisch konfiguriert werden sollen: - apache2

Nicht zu vergessen die PHP-Module laden zu lassen:

invoke-rc.d apache2 restart

Postfix

Nun zu einer der wichtigsten Komponenten: Postfix, der MTA und (E)SMTP-Server unserer Mail-Distribution. Natürlich wieder mit der Hilfe des apt:

aptitude install postfix postfix-mysql

Es wird die Entfernung von Paketen vorgeschlagen:

Entferne die folgenden Pakete:
exim4
exim4-base
exim4-config

Dem kann man getrost zustimmen, da Postfix den exim-Dämon ersetzt. Schließlich greift einem der „Wizard“ wieder unter die Arme:

  • Allgemeine Art der Konfiguration: - Internet-Site
  • System-E-Mail-Name: - hier kann vorerst der Hostname des Systems benutzt werden, diese Einstellung wird in späterer Folge von uns überschrieben!

Soweit so gut, die ausführliche Konfiguration folgt noch.

Dovecot

Als IMAP-Server setze ich den wirklich hervorragenden und flexiblen Dienst Dovecot ein. Allerdings benötigen wir eine neuere Version als die in den Debian Stable Repos. Nun kommen die Backports ins Spiel:

aptitude -t lenny-backports install dovecot-imapd

Sollte jemand tatsächlich noch POP3 benötigen, wird noch ein Paket installiert:

aptitude -t lenny-backports install dovecot-pop3d

Ob es die korrekte Version ist, findet man leicht heraus, dovecot –version sollte 1.2.11 bzw. zumindest 1.2.xx ausgeben. Auch hier bedarf es noch einer Konfiguration, die natürlich noch folgt.

RoundCube Webmail (optional)

Webmail ist immer von Vorteil, sollte man seinen Rechner mit konfiguriertem Mail-Client nicht dabei haben. Auch möchte nicht jeder Nutzer Clients wie Outlook oder Thunderbird nutzen. Die verwendete Web-Applikation RoundCube wäre auch in den Backports in der letzten stabilen Version vorhanden, allerdings verwende ich die aktuellste 0.5-Beta und deren Plugins (neu, neuer, beta :-)). Somit bedienen wir uns der SourceForge Version:

cd /var/www/
wget "http://downloads.sourceforge.net/project/roundcubemail/roundcubemail-beta/0.5-beta/roundcubemail-0.5-beta.tar.gz?r=http%3A%2F%2Froundcube.net%2Fdownload&ts=1292513033&use_mirror=switch"
tar xf roundcubemail-0.5-beta.tar.gz
mv roundcubemail-0.5-beta webmail
rm roundcubemail-0.5-beta.tar.gz

Das war es soweit fürs Erste, die Einrichtung kommt etwas weiter unten.

Konfiguration

Nun zum lustigen Teil: die Konfiguration :-P

Postfix

Auf geht´s, ab geht´s jetzt wird´s erst spannend :-)

RFC-Konforme Einstellungen

Damit andere Mail-Server im Internet unsere Nachrichten annehmen, benötigt man neben einer statischen IP noch die korrekte „Umgangsform“ mit seinen Kollegen. Dazu sollte man dringend diese wichtigen Parameter korrigieren:

/etc/postfix/main.cf
# dieser Wert wird zusammen mit HELO/EHLO bei fremden Servern benutzt (MX Record)
myhostname = mail.example.com
# der Domain-Name des Systems (ohne Subdomain)
mydomain = example.com
# dieser Wert wird benutzt, um lokale E-Mails mit korrektem Domain-Part zu versehen (e.g. www-data@example.com)
myorigin = $mydomain

!!! ACHTUNG !!! LESEN !!! ACHTUNG !!! LESEN !!!
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

Achtung: Hier darf keine der virtuellen Domains aufscheinen, da Postfix dann nicht weiß, ob sie für das lokale oder virtuelle Konto gelten! Also auch nicht myorigin, mydomain oder myhostname!

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
!!! ACHTUNG !!! LESEN !!! ACHTUNG !!! LESEN !!!

mydestination = debian.local, localhost.localdomain, localhost

Virtuelle Domain: als virtuelle Domain wird schlicht ein Domain-Name bezeichnet, der aus einer Datenbank oder einem Verzeichnis bezogen wird. Sie existiert also streng genommen in der lokalen Konfiguration nicht und wird zur Unterscheidung virtuell genannt. Dieses Detail ist von enormer Wichtigkeit, da Postfix je nach Domain-Typ einen anderen zuständigen Prozess verwendet. Für Domains, die man in mydestination einträgt, ist der local-Dämon zuständig, für datenbankbezogene virtual.

Trägt man also example.net in mydestination ein, versucht Postfix, Mails in das Postfach des lokalen (existierenden) Benutzers einzuordnen. Sendet man nun eine Nachricht an abuse@example.net und der Benutzer abuse existier in der Datenbank, jedoch nicht im Linux-System ist Postfix verwirrt und weiß nicht wo hin damit. Darum ist in diesem Set-Up mydestination tabu - außer für localhost =)

Virtuelle Nutzer

Zu allererst machen wir uns über die main.cf her:

/etc/postfix/main.cf

Diese Direktiven fügt man an die bestehende Konfiguration an:

# Virtual mailbox settings
virtual_mailbox_domains = proxy:mysql:$config_directory/mysql_virtual_domains_maps.cf
virtual_mailbox_base = /var/vmail
virtual_mailbox_maps = 
    proxy:mysql:$config_directory/mysql_virtual_mailbox_maps.cf,
    proxy:mysql:$config_directory/mysql_virtual_alias_domain_mailbox_maps.cf,
    proxy:mysql:$config_directory/mysql_virtual_alias_domain_catchall_maps.cf
virtual_alias_maps = 
    proxy:mysql:$config_directory/mysql_virtual_alias_maps.cf,
    proxy:mysql:$config_directory/mysql_virtual_alias_domain_maps.cf
virtual_mailbox_limit = proxy:mysql:$config_directory/mysql_virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = Sorry, the user's maildir has overdrawn his diskspace quota, please try again later.
virtual_overquota_bounce = yes
virtual_minimum_uid = 150
virtual_uid_maps = static:150
virtual_gid_maps = static:8
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
 
# SASL Authentication
smtpd_sasl_auth_enable = yes
smtpd_sasl_exceptions_networks = $mynetworks
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
 
# No open relay!
smtpd_recipient_restrictions =
    permit_mynetworks
    permit_sasl_authenticated
    reject_unauth_destination
    permit

Die korrekte Anwendung der Syntax (insbesondere führende Leerzeichen) ist enorm wichtig für einen problemlosen Start!

Da wir mit virtuellen Nutzern arbeiten, benötigen die Mailboxen ein eigenes Verzeichnis und einen UNIX-Nutzer, den wir noch erstellen müssen (Parameter sind natürlich dem eigenen System anzupassen):

useradd -r -u 150 -g mail -d /var/vmail -s /sbin/nologin -c "Virtual mailbox" vmail
mkdir /var/vmail
chmod 770 /var/vmail/
chown vmail:mail /var/vmail/

UID, GID, Name und Home-Verzeichnis können natürlich geändert werden, allerdings müssen diese Änderungen auch in den Konfigurationsdateien berücksichtigt werden!

Dem Thema Anti-Spam habe ich einen eigenen Artikel gegönnt.

Postfix MySQL Konfiguration

Die angegebenen Dateien sind mit dem entsprechenden Inhalt unter /etc/postfix/ anzulegen. MYSQLPW ist mit dem Passwort für den Datenbank-Nutzer postfixadmin zu ersetzen.

Alias-Informationen
mysql_virtual_alias_maps.cf
user = postfixadmin
password = MYSQLPW
hosts = localhost
dbname = postfixadmin
table = alias
query = SELECT goto FROM alias WHERE address = '%s' AND active = '1'
Zu behandelnde Domains
mysql_virtual_domains_maps.cf
user = postfixadmin
password = MYSQLPW
hosts = localhost
dbname = postfixadmin
table = domain
query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '0' AND active = '1'
Alias Domains
mysql_virtual_alias_domain_maps.cf
user = postfixadmin
password = MYSQLPW
hosts = localhost
dbname = postfixadmin
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'	
Quota-Einträge
mysql_virtual_mailbox_limit_maps.cf
user = postfixadmin
password = MYSQLPW
hosts = localhost
dbname = postfixadmin
table = mailbox
query = SELECT quota FROM mailbox WHERE username = '%s' AND active = '1'
Mailboxen
mysql_virtual_mailbox_maps.cf
user = postfixadmin
password = MYSQLPW
hosts = localhost
dbname = postfixadmin
table = mailbox
query = SELECT maildir FROM mailbox WHERE username = '%s' AND active = '1'
Alias Domain Mailboxen
mysql_virtual_alias_domain_mailbox_maps.cf
user = postfixadmin
password = MYSQLPW
hosts = localhost
dbname = postfixadmin
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'
Catchall Einträge
mysql_virtual_alias_domain_catchall_maps.cf
user = postfixadmin
password = MYSQLPW
hosts = localhost
dbname = postfixadmin
query  = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'

Für den bequemen Administrator habe ich noch ein Hilfsmittel an der Angel:

sed -i 's/MYSQLPW/dasEchtePasswort/g' mysql_virtual_*

Damit kann man ohne großen Aufwand das richtige Passwort setzen lassen.

Da in diesen Dateien die Passwörter im Klartext stehen (müssen), empfiehlt es sich die Rechte entsprechend anzupassen:

chgrp postfix /etc/postfix/mysql*.cf
chmod o-rwx /etc/postfix/mysql*.cf

Ändert nicht versehentlich die Rechte der main.cf, da sendmail (und damit auch PHPs Funktion mail()) Werte aus der Datei mit dem aufgerufenen Benutzer lesen können muss, ohne wird es Fehler im Log hageln! 0644-Rechte sind empfehlenswert.

Dovecots' deliver

Für Sieve und aus Performance-Gründen werde ich als LDA Dovecots' eigenes Programm deliver einsetzen. Postfix muss man nur noch mitteilen, dass man ihn nutzen möchte. Dazu hängt man in der master.cf folgenden Eintrag am Ende an:

/etc/postfix/master.cf
dovecot   unix 	- 	n 	n 	- 	- 	pipe flags=DRhu 
  user=vmail:mail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}

Beachtet bitte die führenden Leerzeichen am Anfang der zweiten Zeile, diese sind entscheidend wichtig! Andernfalls interpretiert Postfix die letzte Zeile als eigenen Dienst und dieser Fehler ist sogar mit Logging nur schwer zu finden!

Letztendlich noch die Änderungen aktivieren:

invoke-rc.d postfix restart

Submission & SMTPS (optional)

Für gewisse Szenarien reicht das Lauschen auf Port 25 alleine nicht aus. Will man sich etwa per Google-Mail oder Outlook verbinden und es klappt einfach nicht, kann Postfix zur Kontaktaufnahme auch Submission bzw. das veraltete SMTPS anbieten. Dazu kommentiert man diese Zeilen in der /etc/postfix/master.cf ein:

submission inet n       -       -       -       -       smtpd
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
smtps     inet  n       -       -       -       -       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

Nach Übernahme der Änderungen mit

invoke-rc.d postfix restart

sollte Postfix nun auch auf den Ports 587 bzw. 465 lauschen und Verbindungen annehmen:

root#/etc/postfix netstat -tlpn|grep master
tcp        0      0 0.0.0.0:587             0.0.0.0:*               LISTEN      30722/master
tcp        0      0 0.0.0.0:465             0.0.0.0:*               LISTEN      30722/master
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      30722/master
tcp6       0      0 :::587                  :::*                    LISTEN      30722/master
tcp6       0      0 :::465                  :::*                    LISTEN      30722/master
tcp6       0      0 :::25                   :::*                    LISTEN      30722/master

Dovecot

Dovecots' Konfigurationsdatei ist standardmäßig überaus reichhaltig dokumentiert und mit Kommentaren versehen. Allerdings kann das beim Einrichten auch hinderlich sein. Deshalb empfehle ich, die Datei dovecot.conf unter /etc/dovecot/ neu anzulegen mit folgendem Inhalt:

dovecot.conf
base_dir = /var/run/dovecot
# Ich habe nur IMAP(S) in Verwendung, für POP3 einfach noch pop3 bzw. pop3s hinzufügen
protocols = imap imaps managesieve
# IMAP Konfiguration
protocol imap {
   listen = *:143
   # Quota Einstellungen
   mail_plugins = quota imap_quota
}
 
# einkommentieren, falls POP3 benötigt
#protocol pop3 {
#   listen = *:110
#   # ssl_listen = *:995
#   mail_plugins = quota
#}
 
# managesieve Dienst zum Verwalten der Sieve-Skripte
protocol managesieve {
   listen = *:2000
   login_executable = /usr/lib/dovecot/managesieve-login
   mail_executable = /usr/lib/dovecot/managesieve
   managesieve_max_line_length = 65536
   managesieve_logout_format = bytes=%i/%o
   managesieve_implementation_string = dovecot
}
listen = *
# erzwinge AUTH mit STARTTLS
disable_plaintext_auth = yes
 
# logging Optionen
log_path = /var/log/dovecot.log
info_log_path = /var/log/dovecot.log
log_timestamp = "%Y-%m-%d %H:%M:%S "
syslog_facility = mail
 
# mailbox Einstellungen
mail_location = maildir:/var/vmail/%d/%u
mail_privileged_group = mail
mail_debug = no
 
# gültig ist nur unser vmail-Besitzer
first_valid_uid = 150
last_valid_uid = 150
 
maildir_copy_with_hardlinks = yes
 
# IMAP Optionen
protocol imap {
  login_executable = /usr/lib/dovecot/imap-login
  mail_executable = /usr/lib/dovecot/imap
  imap_max_line_length = 65536
  mail_plugin_dir = /usr/lib/dovecot/modules/imap
}
 
#protocol pop3 {
#  pop3_uidl_format = %08Xu%08Xv
#}
 
# managesieve aktivieren
protocol managesieve {
}
 
# deliver aktivieren
protocol lda {
  postmaster_address = postmaster@example.com
  mail_plugins = quota sieve
  mail_plugin_dir = /usr/lib/dovecot/modules/lda
  deliver_log_format = msgid=%m: %$
  sendmail_path = /usr/lib/sendmail
  auth_socket_path = /var/run/dovecot/auth-master
}
 
auth_verbose = no
auth_debug = no
 
# Authentifizierungs-Info aus Datenbank
auth default {
  mechanisms = plain login
 
  passdb sql {
    args = /etc/dovecot/dovecot-sql.conf
  }
 
  # steigert Performance mit Datenbank
  userdb prefetch {
  }
 
  userdb sql {
    args = /etc/dovecot/dovecot-sql.conf
  }
 
  user = nobody
 
  socket listen {
    master {
      path = /var/run/dovecot/auth-master
      mode = 0660
 
      user = postfix
      group = mail
    }
    client {
      path = /var/spool/postfix/private/auth
      mode = 0660
      user = postfix
      group = postfix
    }
  }
}
 
# Quota-Info wird in Datenbank gespeichert
dict {
  quotadict = mysql:/etc/dovecot/dovecot-dict-sql.conf
  mail_debug = yes
}
 
# Quota & Sieve Konfiguration
plugin {
  quota = dict:user::proxy::quotadict
  quota_rule = *:storage=500MB
  sieve=~/dovecot.sieve
  sieve_dir=~/sieve
}

Solltet ihr .dovecot.sieve bzw. .sieve (also mit führendem Punkt) schreiben, werden diese Dateien zwar im Dateisystem versteckt (in diesem Fall sinnlos), allerdings damit im IMAP-Verzeichnis sichtbar (auch weniger sinnvoll). *:storage=500MB vergibt an jeden Nutzer ohne Quota-Einstellung automatisch ein 500MB-Limit.

Nun zur Datenbank-Konfiguration:

Sollte das MySQL-Nutzer Passwort Sonderzeichen enthalten, umschließt den connect-String mit Doublequotes:

connect = "host=localhost dbname=postfixadmin user=postfixadmin password=MYSQLPW"

dovecot-sql.conf
driver = mysql
connect = host=localhost dbname=postfixadmin user=postfixadmin password=MYSQLPW
default_pass_scheme = MD5-CRYPT
# Get the mailbox
user_query = SELECT '/var/vmail/%d/%n' as home, 'maildir:/var/vmail/%d/%n' as mail, 150 AS uid, 8 AS gid, CONCAT('*:bytes=', CAST(quota AS CHAR)) AS quota_rule FROM mailbox WHERE username = '%u' AND active = '1'
# Get the password
password_query = SELECT username as user, password, '/var/vmail/%d/%n' as userdb_home, 'maildir:/var/vmail/%d/%n' as userdb_mail, 150 as userdb_uid, 8 as userdb_gid, CONCAT('*:bytes=', CAST(quota AS CHAR)) AS  userdb_quota_rule FROM mailbox WHERE username = '%u' AND active = '1'

Vergesst bloß nicht die Abfrage von userdb_quota_rule in der password_query! Zusammen mit der userdb prefetch Direktive in der dovecot.conf erhöht diese Konfiguration zwar die Performance beim Datenbankzugriff, bestraft eine kleine Unachtsamkeit jedoch mit dem Ignorieren der Quota-Regeln!

Das Dictionary für die Quotas fehlt noch:

dovecot-dict-sql.conf
connect = host=localhost dbname=postfixadmin user=postfixadmin password=MYSQLPW
 
map {
  pattern = priv/quota/storage
  table = quota2
  username_field = username
  value_field = bytes
}
 
map {
  pattern = priv/quota/messages
  table = quota2
  username_field = username
  value_field = messages
}

Die Tabelle quota2 (ausgeliefert mit Postfixadmin) wurde speziell auf Dovecot 1.2 zugeschnitten!

Schließlich noch die Rechte begradigen:

chmod 600 /etc/dovecot/*.conf
chown vmail /etc/dovecot/*.conf
chmod 666 /var/log/dovecot.log

Postfix Admin

Wir nähern uns dem ersten Test. Bevor wir unser Admin-Interface Postfix Admin nutzen können, ist noch eine Basiskonfiguration und ein Durchlauf des mitgelieferten Setup-Skripts nötig. Aber eines nach dem Anderen.

Lokale Konfiguration

Die nun folgenden Parameter sind entsprechend dem eigenen System anzupassen. Achtet allerdings darauf, dass der Hash-Algorithmus mit dem von Dovecot übereinstimmt (in meinem Fall MD5-CRYPT)!

/etc/postfixadmin/config.inc.php
// TRUE um das Setup starten zu können
$CONF['configured'] = true;
$CONF['postfix_admin_url'] = 'http://example.com/postfixadmin';
// Sprache
$CONF['default_language'] = 'de';
// Für MySQL 5.x verwenden wir mysqli
$CONF['database_type'] = 'mysqli';
$CONF['admin_email'] = 'postmaster@example.com';
$CONF['encrypt'] = 'md5crypt';
$CONF['authlib_default_flavor'] = 'crypt';
$CONF['default_aliases'] = array (
    'abuse' => 'abuse@example.com',
    'hostmaster' => 'hostmaster@example.com',
    'postmaster' => 'postmaster@example.com',
    'webmaster' => 'webmaster@example.com'
);
// Wichtig für das korrekte Anlegen der Mailbox-Pfade
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
// Quota Einstellungen
$CONF['maxquota'] = '1000';
$CONF['quota'] = 'YES';
$CONF['quota_multiplier'] = '1048576';
$CONF['used_quotas'] = 'YES';
$CONF['new_quota_table'] = 'YES';
// Domain und Kontaktinfo
$CONF['vacation_domain'] = 'autoreply.example.com';
$CONF['user_footer_link'] = "http://example.com/";
$CONF['footer_text'] = 'Return to example.com';
$CONF['footer_link'] = 'http://example.com/';
// Specify '' for Dovecot and 'INBOX.' for Courier.
$CONF['create_mailbox_subdirs_prefix']='';
// Gibt Feedback über Quota-Status
$CONF['used_quotas'] = 'YES';
// if you use dovecot >= 1.2, set this to yes.
// Note about dovecot config: table "quota" is for 1.0 & 1.1, table "quota2" is
// for dovecot 1.2 and newer
$CONF['new_quota_table'] = 'YES';

Web Setup

Nun ist alles bereitet um das Web-Setup starten zu können. Dazu ruft man die URL zum Setup auf, z.B.
http://example.com/postfixadmin/setup.php

Aussehen wird es folgendermaßen:
Postfix Admin Setup

Das setzen des Setup-Passwortes verhindert das nachträgliche illegale hinzufügen eines Administrator-Kontos. Es sollte ebenso notiert werden, wie die MySQL-Passwörter. Nach dem Absenden des Formulars bekommt man den gehashten Wert zurück, der in etwa so aussehen kann:

$CONF['setup_password'] = 'ce8737fa0ac8640a9d2a3264b9cb0857:886c50b365dc9fe4d5dd28446d28d8b9b1265ff1';

Dies ist in der /etc/postfixadmin/config.inc.php einzutragen. Danach kann man einen neuen Superadmin anlegen und sich über http://example.com/postfixadmin/ mit den gesetzten Daten anmelden. Der Spaß sieht dann so aus:

Postfix Admin Login

Glückwunsch, du bist drin :-) Das Interface erklärt sich von selbst. Ab diesem Stadium der Anleitung könnt ihr bereits Domains, Aliasen und Mailboxen anlegen, allerdings müssen wir unseren Servern noch die SSL/TLS-Konfiguration spendieren, bevor wir uns Verbinden können.

Transportschicht-Verschlüsselung

Genau wie Anti-Spam ist auch das Thema SSL bzw. TLS etwas zu Umfangreich, um es jedesmal aufs Neue aufzurollen. Deshalb verweise ich wieder auf einen bereits existierenden Artikel, der die Erstellung von Schlüssel und Zertifikat beschreibt. Wenn man im Besitz jener Dateien ist, kann mit der Einrichtung der Mail-Dienste weiter gemacht werden.

Ich verwende in diesem Beispiel das Snakeoil-Zertifikat und den -Schlüssel, deshalb bezieht sich der folgende Teil darauf. Da es schier endlos viele Anbieter von „echten“ Zertifikaten gibt, bemüht man sich für eine alternative Konfiguration bitte zur nächsten Suchmaschine seiner Wahl! Vielleicht hilft auch das hier weiter.

Postfix TLS

Die folgenden Abschnitte sind in der main.cf zu ädern/ergänzen:

/etc/postfix/main.cf
# TLS parameters
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls = yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_auth_only = yes
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

Nun noch einmal

invoke-rc.d postfix restart

Dovecot TLS

Die dovecot.conf verträgt auch noch kleine Anpassungen:

/etc/dovecot/dovecot.conf
# SSL/TLS Konfig
ssl = yes
ssl_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
ssl_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
ssl_cipher_list = ALL:!LOW:!SSLv2
verbose_ssl = yes

Dovecot neu starten:

invoke-rc.d dovecot restart

Puh, geschafft :-) Der Mail-Server wäre hiermit einsatzfähig und bereit für Tests. Sollten trotz meiner ausführlich recherchierten Dokumentation Fehler auftreten, konsultiert bitte die entsprechenden Log-Files. Ansonsten viel Spaß mit eurem neuen Mail-System!

RoundCube Webmail

Solltet ihr euch entschieden haben, Webmail ebenfalls aufzusetzen, werden wir uns in diesem Abschnitt mit dessen Einrichtung und Anpassung an das System beschäftigen. Beachtet bitte, dass ab hier die Installation bereits erfolgt sein muss! Man wird auch diesmal von einem Setup-Skript begleitet, welches einem viel Arbeit abnimmt, doch zuerst nehmen wir noch ein paar Änderungen am Dateisystem vor:

Dateisystem

chown root:www-data -R /var/www/webmail/
chmod o-rwx -R /var/www/webmail/

Jetzt ein wichtiger Schritt: RoundCube bringt seine eigene .htaccess mit, in der für den Betrieb wichtige PHP-Flags vermerkt sind. Damit diese auch ausgewertet werden, fügt man in der Apache-Konfiguration z.B. im Default VHost noch dies ein:

/etc/apache2/sites-enabled/000-default
<Directory /var/www/webmail/>
    AllowOverride All
</Directory>

Die Pfade und VHosts sind natürlich an das bestehende System anzupassen und z.B. bei Nutzung von HTTPS entsprechend abzuändern. Die .htaccess selbst verträgt noch eine kleine Ergänzung zwischen den IfModule-Tags:

php_value       date.timezone           Europe/Vienna

Damit wird die Zeitzone gesetzt, welche zur korrekten Berechnung von Datum und Zeit nötig sind.

Zwingend notwendig ist außerdem das mod_rewrite, somit müssen wir diese noch aktivieren und den Indianer erneut neu starten/laden:

a2enmod rewrite
invoke-rc.d apache2 reload

MySQL Nutzer

Bilder sagen mehr als tausend Worte :-) Wir benötigen noch einen Account für die neue RoundCube Datenbank, simple Lösung mit phpMyAdmin:

Schwierig oder? :-P

Web Setup

Weiter geht es mit dem Web-Setup, zu finden unter dieser URL: http://example.com/webmail/installer/

Der Installer begrüßt einem mit den Requirements, die wir bei der Installation der vorherigen Komponenten schon erfüllt habe sollten:


Wenn man alles richtig und aufmerksam durchgeführt hat, erblickt man kein Rot (außer meinen Pfeil ;-)):


Nun füllt man nach bestem Gewissen das folgende Formular aus:


Schließlich folgt man den weiteren Anweisungen und kopiert die Konfiguration auf das System in die vorgegebenen Dateien:
Nach diesem Schritt passen wir abermals die Rechte an:

chown root:www-data -R /var/www/webmail/config
chmod o-rwx -R /var/www/webmail/config

Sollten diese Meldungen auftauchen

kann das hiermit begradigt werden.

chmod g+rwx /var/www/webmail/temp/ /var/www/webmail/logs/

Die Datenbank ist nun bereit zur Initialisierung:

Danach sollte es grünes Licht hageln:


Wenn man mit Postfix Admin schon Mailboxen angelegt haben sollte, kann man den SMTP-Server testen:

Dabei kann man Dovecot auch gleich einem Test unterziehen:


Hat alles geklappt, löscht man den Installer aus Sicherheitsgründen:

rm -rf /var/www/webmail/installer/

Testen des Webmail

Endspurt :-) Auf zur Location http://example.com/webmail/

Und man ist drin! ^_^

Es ist euch jetzt erlaubt, ein Freudentänzchen aufzuführen :-D

Sieve Plugin

RoundCube liefert im plugins/ Verzeichnis zwar ein managesieve-Plugin mit, allerdings bevorzuge ich das Plugin SieveRules, dessen Installation mit wenigen Befehlen erfolgt:

cd /var/www/webmail/plugins/
wget "http://www.tehinterweb.co.uk/roundcube/plugins/sieverules.tar.gz"
tar xf sieverules.tar.gz
rm sieverules.tar.gz
cp sieverules/config.inc.php.dist sieverules/config.inc.php
chown root:www-data -R sieverules/
find sieverules/ -type d -exec chmod 770 {} +
find sieverules/ -type f -exec chmod 660 {} +

Das Plugin muss noch aktiviert werden:

/var/www/webmail/config/main.inc.php
// List of active plugins (in plugins/ directory)
$rcmail_config['plugins'] = array('sieverules');

Danach erscheint eine neuer Tab Filter in den Einstellungen und mit dem Filtern kann begonnen werden:

Viel Spaß beim Filtern :-)

Password Plugin

Mit RoundCube selbst lässt sich auch das Passwort de Benutzers ändern, diese Funktionalität ist allerdings auch in einem standardmäßig nicht aktivem Plugin versteckt. Die Aktivierung und Einrichtung ist schnell vollzogen:

cd /var/www/webmail/plugins/password/
cp config.inc.php.dist config.inc.php
chown root:www-data config.inc.php

Jetzt müssen noch die Verbindungsdaten zur Datenbank und die Update-Query eingetragen werden:

/var/www/webmail/plugins/password/config.inc.php
// SQL Driver options
// ------------------
// PEAR database DSN for performing the query. By default
// Roundcube DB settings are used.
$rcmail_config['password_db_dsn'] = 'mysql://postfixadmin:MYSQLPW@localhost/postfixadmin';
 
// The SQL query used to change the password.
// The query can contain the following macros that will be expanded as follows:
//      %p is replaced with the plaintext new password
//      %c is replaced with the crypt version of the new password, MD5 if available
//         otherwise DES.
//      %D is replaced with the dovecotpw-crypted version of the new password
//      %o is replaced with the password before the change
//      %n is replaced with the hashed version of the new password
//      %q is replaced with the hashed password before the change
//      %h is replaced with the imap host (from the session info)
//      %u is replaced with the username (from the session info)
//      %l is replaced with the local part of the username
//         (in case the username is an email address)
//      %d is replaced with the domain part of the username
//         (in case the username is an email address)
// Escaping of macros is handled by this module.
// Default: "SELECT update_passwd(%c, %u)"
$rcmail_config['password_query'] = 'UPDATE mailbox SET password=%c WHERE username=%u AND domain=%d LIMIT 1';

Das Plugin muss nur noch aktiviert werden:

/var/www/webmail/config/main.inc.php
// List of active plugins (in plugins/ directory)
$rcmail_config['plugins'] = array('sieverules', 'password');

Es findet sich nach dem Login nun ein Passwort-Tab in den Einstellungen:

IMHO eines der nützlichsten Plugins!

Troubleshooting

Du hängst irgendwo fest? Es klappt nicht so wie beschrieben? Mails wollen einfach nicht ankommen? Du sitzt seit Stunden daran und bist langsam am Verzweifeln? Dann wende dich einfach ans Ubuntuusers-Forum! Dort geistere nicht nur ich herum, es gibt auch viele nützliche Threads und andere kompetente Nutzer, die dir weiter helfen können! Wenn alle Stricke reißen, kannst du mich auch direkt anschreiben, aber beachte dabei, dass ich auch noch andere Dinge zu tun habe und du im Forum eher eine Antwort bekommst und dein Problem nicht untergeht. Danke und viel Erfolg =)

Eins noch: bedenke, dass Linux-Administratoren keine Hellseher sind. Zu erklären was nicht funktioniert ist nur die halbe Miete. Ohne aussagekräftige Log-Auszüge und detaillierter Problembeschreibung erntest du nicht mehr als Spott, Hohn und auch Ärger über die verschwendete Zeit.

Quellen

Kommentare