Inhaltsverzeichnis

Virtueller E-Mail Server unter Debian Etch mit Postfix

Vorwort

Über diese Dokumentation

  • Dieses Dokument wurde ein drittes Mal neu aufgesetzt. Die ersten beiden Versionen sind nicht mehr verfügbar.

* Diese Anleitung wurde auch unter Debian Etch getestet und funktioniert.

  • Wenn Sie Kontakt mit mir aufnehmen möchten, können Sie dieses Kontaktformular nutzen.
  • Copyright © 2006 Claus Malter. Diese Dokumentation dürfen Sie unter den Bedingungen der Creative Commons License Sharealike Version 2.5 verwenden. Sollten Sie Auszüge aus meinem Werk in Ihrer eigenen Arbeit verwenden, lesen Sie bitte vorher die Creative Commons License gründlich durch.
  • Es handelt sich lediglich, um eine Step-by-Step Anleitung. Wenn Sie die Schritte einzeln bearbeiten, erhalten Sie (hoffentlich) das gewünschte Ergebnis. Das Dokument wird theoretisches Wissen nur anschneiden, aber auf keinen Fall vertiefen.
  • Wenn Sie Änderungen an dieser Dokumentation vornehmen, dürfen Sie sich unter dem Punkt „Danksagungen“ eintragen. Sollten Sie einen großen Teil der Dokumentation überarbeiten, dürfen Sie sich auch unter „Autoren“ eintragen.

Was wird voraus gesetzt?

  • Gewisse Grundkenntnisse in der Installation, Konfiguration und Administration sollten Sie für diese Dokumentation mitbringen. Vor allem bei den folgenden Programmen:
    • MySQL (grobe Kenntniss des SQL-Syntax)
    • Postfix (Basiskenntnisse)
    • Linux (grundlegende Kenntnisse)
  • Dieser E-Mail-Server wurde auf einem Debian Sarge System umgesetzt. Er läuft auch auf Debian Etch / Lenny.

Changelog

25. August 2010

  • Infos zur Installation auf Lenny zugefügt

12. August 2010

  • Infos zu Problemen beim Update von Etch auf Lenny zugefügt
  • GreyListing per Postgrey uns sqlgrey zugefügt

08. August 2010

  • Webadmin zugefügt

24. Juni 2009

  • Mail-Filterung per GDBM-Datei zugefügt

29. Mai 2009

  • Erstellung eines globalen Zertifikates für den Mailserver zugefügt
  • Maildrop-Tipps zugefügt

10. Juni 2007

23. März 2007

  • Kleiner Fehler in der main.cf behoben. Die vms-email2email.cf wurde nicht eingebunden. Aus diesem Grund wurden Forward-Regeln auch bei bestehenden Postfächern ausgeführt, was z.B. bei catchall-Forwarding-Regeln Probleme macht.

06. Februar 2007

  • Tipp bei der Postfix Installation ergänzt.

15. März 2006

  • Eine intensive Überarbeitung der alten Version.

03. April 2006

  • In der Doku hat etwas sehr wichtiges gefehlt, damit die Authentifizierung am smtp mit verschlüsselten Passwörtern aus der Datenbank funktioniert (Kapitel Postfix_und_SASL/MySQL).
  • Kleinigkeiten hinzugefügt.

09. Mai 2006

  • Viele kleine Verbesserungen und Korrekturen
  • POP3/IMAP Zertifikate für Courier

19. Februar 2006

  • Update für Etch

Kleine Einführung

Was ist ein virtueller Mail-Server?

Ein virtueller Mail-Server speichert die Informationen zu Postfächern und Benutzern in einer Datenbank. In diesem Beispiel in einer MySQL-Datenbank. Ein virtueller Mail-Server wird eingerichtet, wenn eine große Anzahl an Nutzern verwaltet werden muss. „Große“ Email-Provider nutzen dieses Prinzip. Durch die Speicherung in einer Datenbank entstehen einige Vorteile. Zum Beispiel können die Daten durch ein Web-Interface sehr einfach administriert werden. Oder die Daten aus der Datenbank können in anderen Anwendungen verwendet werden.

Der Vorteil

Wie schon erwähnt können die Postfächer in einer Datenbank (folgend DB) verwaltet werden. Ein weiterer Vorteil besteht darin, dass keine Benutzer auf Betriebssystem-Ebene angelegt werden müssen. Ein umständliches Editieren der Aliase ist nicht mehr notwendig. Postfix unterstützt generell zwei Möglichkeiten, die Administration vieler Benutzer zu vereinfachen.

  • Virtual Domains: Es können mehrere Domänen verwaltet und verwendet werden und zudem jeder Domäne ein Nutzer zugeordnet werden.
  • Database Queries: Durch die DB wird die konventionelle Datenhaltung in Textdateien abgelöst. Postfix fragt bei der DB nach den Informationen die Postfix benötigt. Zum Beispiel Benutzername, Passwort und Home-Verzeichnis. Durch diese Benutzerverwaltung in einer Datenbank ist es möglich auf diese Daten auch aus anderen Anwendungen zuzugreifen. Zum Beispiel ein Administrationsinterface.

Features

Mit Hilfe dieser Dokumentation erstellen Sie einen eigenen Mail-Server, der den „großen“ E-Mail-Providern in nichts nachsteht:

  • IMAP Zugang
  • Webmail Interface
  • SPAM-Filter
  • Authentifizierung beim SMTP
  • Domänenverwaltung über MySQL Datenbank

Elemente des Mail-Servers

In der Linux-/Unix-Welt gibt es keine Komplettlösung für einen Mail-Server. Ein Mail-Server besteht aus mehreren Komponenten. Üblicherweise wird ein MTA (Mail Transfer Agent) und der eigentliche Mail-Server, der die Protokolle POP3 oder IMAP unterstützt, eingesetzt. Diese werden bei gängigen Windows-Produkten direkt in einer Anwendung zusammengeführt.

Mit dieser Dokumentation werden Sie folgende Komponenten einsetzen.:

  • Postfix: Postfix ist der Mail Transfer Agent, kurz MTA. Dieser kümmert sich um das Versenden und Empfangen von Mails über das Simple Mail Transfer Protocol (SMTP). Postfix ist eine Alternative zum Konfigurationsgigant sendmail.
  • MySQL: MySQL ist eine freie Software und steht seit einiger Zeit unter der GPL und einer kommerziellen Lizenz zur Verfügung. Es gehört zu den am weitesten verbreiteten Open-Source-Programmen. Aus der MySQL Datenbank bezieht Postfix die nötigen Informationen über Domänen, Weiterleitungen, Benutzer-Konten und Passwörter. Ein wichtiger Bestandteil des virtuellen E-Mail Servers
  • Courier: Courier ist ein Mail Transfer Agent („MTA“), kompatibel zu Sendmail. Er wurde von Sam Varshavchik entwickelt. Das Programm ist unter der GPL frei verfügbar. Wir benötigen hingegen nur ein Modul des Programms. Und zwar den courier-IMAP. Courier-IMAP ist der eigentliche Mail-Server. Er gewährt den Zugang zu den Mails und bietet noch ein paar andere Funktionen. Das Protokoll hierbei ist IMAP. Im Gegensatz zum POP3-Protokoll verbleiben die Mails in der Regel auf dem Mailserver, und werden nur bei Bedarf auf den Client-Rechner übertragen.
  • SASL: SASL ist die Abkürzung des englischen Begriffs Simple Authentication and Security Layer. Es handelt sich hierbei um ein Authentifizierungsprotokoll. Wir werden es dazu nutzen, um auch außerhalb des Netzes, in dem sich Postfix befindet, E-Mails verschicken zu können. Ein direkter Versand von Mails ist nur innerhalb des Netzes möglich. Wer sich außerhalb befindet, muss sich vorher authentifizieren.
  • Spamassassin: Mit diesem sehr guten Spam-Filter, werden eingehende Mails, bevor sie dem Nutzer übermittelt werden, geprüft. Die Mails werden anhand einer Score bewertet. Das sofortige Löschen von Spam-Mail ist möglich.
  • Maildrop: Ist der MDA (Mail Delievery Agent). Mit diesem können Regeln erstellt, werden wohin z.B Mails „geliefert“ werden. Spam z.B ein speziellen Ordner. (Hier ist zu beachten, dass ich es nocht geschafft habe, Maildrop an die virtuelle Struktur anzupassen. Maildrop Regeln gelten bei mir leider nur global und verschieben z.B für alle User „möglichen Spam“ in den Ordner Spam.)
  • Phpmyadmin: Diese PHP-Anwendung kann optional genutzt werden. Es macht das Verwalten der MySQL-Tabellen sehr einfach.

Installation und Konfiguration

Unter Debian

Mittels apt-get (oder aptitude) werden die Pakete installiert.

apt-get update
apt-get install postfix postfix-mysql \
	mysql-client mysql-server \
	courier-authdaemon courier-authlib-mysql \
	courier-pop courier-pop-ssl courier-imap \
	courier-imap-ssl postfix-tls libsasl2 \
	libsasl2-modules libsasl2-modules-sql \
	openssl spamassassin spamc courier-maildrop \
        libpam-mysql libwww-perl libarchive-tar-perl

Statt libsasl2 installieren Sie unter Debian Lenny das Paket libsasl2-2 und zusätzlich perl-modules.

Installieren Sie noch zusätzlich das Paket sasl2-bin, (z.B. unter Debian: apt-get install sasl2-bin) wenn nach der Installation dieser Pakete kein Initscript für saslauthd (/etc/init.d/saslauthd) vorhanden sein sollte.

Tipp: Während der Postfix installation werden Sie nach einem Alias gefragt an den alle E-Mails weitergeleitet werden sollen von usern mit der uid 0 damit diese E-Mails keine root-Rechte erlangen können. Hier müssen wir folgendes Eintragen:

root: foobar

Für Debian Etch werden die gleichen Pakete Installiert. Bei der Postfix Installation wird nicht mehr nach dem oben genannten Eintrag gefragt.

Die Datenbank und ihre Tabellen

Als erstes beginnen wir mit der MySQL Datenbank. Entweder Sie erledigen folgende Schritte per Hand und Kommandozeile oder verwenden das vorgestellte phpmyadmin. Hier wird der Weg über die Kommandozeile dokumentiert. Es sollte kein Problem sein, dies in phpmyadmin umzusetzen.

Datenbank und Benutzer anlegen

Wenn Sie den MySQL-Server zum ersten Mal starten, kann der Benutzer root ohne Passwort auf die Datenbank zugreifen. Zu unterscheiden ist der Benutzer root im Betriebssystem und in MySQL. Es handelt sich hierbei nicht um die selben Benutzer. Jedoch sollten wir das Passwort als erstes ändern:

mysqladmin -u root password IhrPasswort

Nun wird eine Datenbank angelegt. Der Name kann frei gewählt werden. In diesem Beispiel lautet der Name mailserver. Sollten Sie einen anderen Namen verwenden, muss das folgend beachtet werden.

mysqladmin -u root -p -h localhost create mailserver

Auf die Datenbank sollte nicht per root zugegriffen werden. Deshalb erstellen wir einen Benutzer, der auf die Datenbank Zugriff hat. Ich nenne ihn mailadmin. Und zum Schluss werden die Benutzerdaten und die Zugriffsrechte neu eingelesen.

mysql -u root -p -h localhost
mysql> grant select on mailserver.* to mailadmin@localhost identified by 'Passwort';
mysql> flush privileges;

Erstellen der Tabellen

Es werden nun folgende Tabellen benötigt. Diese analog zum Beispiel oben mit der Kommandozeile oder per phpmyadmin einfügen. Als erstes wieder mit der DB verbinden und vor allem die Datenbank auswählen.

mysql -u root -h localhost -p
mysql> use mailserver;

Dann können die folgenden SQL-Befehle eingetippt werden:

  • Die Tabelle der zu verwaltenen Domänen
CREATE TABLE domains (
domain varchar(63) NOT NULL,
PRIMARY KEY (domain) )
TYPE=MyISAM;
  • Weiterleitungen
CREATE TABLE forwardings (
source varchar(127) NOT NULL,
destination TEXT NOT NULL,
PRIMARY KEY (source) )
TYPE=MyISAM;
  • Benutzertabellen
CREATE TABLE users (
email varchar(127) NOT NULL,
password varchar(31) NOT NULL,
PRIMARY KEY email (email)
) TYPE=MyISAM;

Nötige Änderung am MySQL Server

Postfix arbeitet in einer chroot Umgebung. Das heisst, es wird eine Betriebssystemumgebung innerhalb des Betriebssystems geschaffen, in der der Mailserver seine Arbeit verrichtet. Zu MySQL verbindet man sich in der Standardkonfiguration über ein Socket. Dies ist eine Datei im Dateisystem, über die eine Verbindung zum Server hergestellt wird. Da nun Postfix keinen Zugriff auf das restliche Betriebssystem hat, muss das am MySQL Server geändert werden. Hier zu editiert man Datei /etc/mysql/my.cnf. Folgende beide Zeilen sollten so in der Datei stehen:

bind-address    = 127.0.0.1
#skip-networking

Danach den Server neu gestartet und schon kann man auf den MySQL-Server über das Loopback zugreifen.

/etc/init.d/mysql restart

mysql -u root -h 127.0.0.1 -p

Postfix Konfigurationsdateien

Editieren der main.cf

In der Postfix Konfigurationsdatei (/etc/postfix/main.cf) werden nun die nötigen Einstellungen vorgenommen. Ich gehe davon aus, dass Sie noch eine unveränderte Konfigurationsdatei vorliegen haben, die bei der Installation von Debian eingerichtet wird. Nicht aufgeführte Parameter belassen Sie einfach so, wie sie sind.

Die Tabellen werden folgend an dieses Kapitel mit Daten gefüllt.

Parameter Bedeutung
myhostname = … Hier wird der Full Qualified Domain Name (FQDN) angegeben. Zum Beispiel 'mailserver.de'
mydestination = … Dieser Parameter definiert in unserem Fall nur lokale Domänen. Es werden keine virtuellen Domänen angegeben.
mynetworks = 192.168.1.0/24 Es können mehrere IP-Bereiche angegeben werden, aus denen Mails über den SMTP verschickt werden dürfen
virtual_alias_domains = Dieser Wert bleibt leer.
virtual_alias_maps =
mysql:/etc/postfix/vms-forwardings.cf
mysql:/etc/postfix/vms-email2email.cf
Die Tabelle forwardings betrifft diese Einstellung. In dieser Tabelle können Weiterleitungen definiert werden. Dazu später mehr. Das Script vms-email2email.cf sorgt dafür, das bei bestehenden Postfächern keine Forward-Regeln benutzt werden.
virtual_mailbox_domains =
mysql:/etc/postfix/vms-domains.cf
Hier ist die wichtige Information hinterlegt, wo Postfix die zu verwaltenden virtuellen Domänen findet.
virtual_mailbox_maps =
mysql:/etc/postfix/vms-mailboxes.cf
In dieser MySQL Tabelle stehen die Benutzer, deren Passwörter und Speicherort der E-Mails
virtual_mailbox_base = /home/vmail Das ist der Pfad, an dem Postfix die Dateien ablegt. Für jede Domain wird ein Unterverzeichnis erstellt, in welchem sich widerum die Benutzer Verzeichnisse befinden. Auf das Verzeichnis vmail hat schliesslich der Benutzer vmail Zugriff.
virtual_uid_maps = static:5000 Eben haben Sie das Verzeichnis für den Mailserver angegeben. Hier wird nun definiert, wem dieses Verzeichnis gehört. Hierzu legen wir später einen Benutzer namens vmail an, mit der User ID 5000.
virtual_gid_maps = static:5000 Außerdem wird auch eine Gruppe namens vmail angelegt. Diese erhält die Group ID 5000.
smtpd_sasl_auth_enable = yes Mit dieser Einstellung wird der SASL Authenfizierungsmechanismus für den SMTP aktiviert. Das ermöglicht später, dass Benutzer außerhalb von mynetworks Mails verschicken können.
broken_sasl_auth_clients = yes Manche E-Mail Clients haben ein Problem mit der SASL Authentifizierung. Mit dieser Einstellung wird versucht, auch „disabled clients“ zu unterstützen.
smtpd_recipient_restrictions =
permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
Hier wird definiert, wer über den SMTP Mails verschicken darf. Und zwar permit_mynetworks. Sprich jeder, innerhalb des definierten Bereichs mynetworks (siehe weiter oben). permit_sasl_authenticated bedeutet, dass Benutzer, die sich am SMTP authentifiziert haben, ebenfalls Mails verschicken dürfen. reject_unauth_destination verwirft das Absenden von Emails zu Zielmaschinen, die nicht unter $inet_interfaces, $mydestination, $virtual_alias_domains der $virtual_mailbox_domains zu finden sind und zu Zielmaschinen, die nicht unter $relay_domains oder in deren Subdomains zu finden sind (ausser Sender-spezifisches Routing).
smtpd_use_tls = yes Authentifizierte SMTP Verbindungen verschlüsseln wir mit SSL.
smtpd_tls_cert_file =
/etc/postfix/smtpd.cert
Bei einer verschlüsselten Verbindung bedarf es eines Zertifikats. Dieses werden wir später noch erstellen.
smtpd_tls_key_file =
/etc/postfix/smtpd.key
Und für jedes Zertifikat braucht es einen privaten (geheimen) Schlüsselt. Auch dieser wird im Zuge des Zertifikats erstellt.

Anlegen eines Benutzers

Nun muss auf Ebene des Betriebssystems ein Benutzer angelegt werden, der die ganzen virtuellen Postfächer und Domänen verwaltet. Technisch gesehen hat unser E-Mail Server dann nur noch einen einzigen Benutzer, der alle Mails bekommt. Der Benutzer vmail verteilt die E-Mails dann anhand der Informationen aus der MySQL Datenbank auf die einzelnen Domänen auf. Man kommt nicht darum herum, mindestens einen Benutzer anzulegen.

groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /home/vmail -m

Die UID/GID 5000 ist im Grunde willkürlich. Sie darf jedoch nicht schon mal im System vergeben sein. Und außerdem muss darauf geachtet werden, dass in der main.cf die selben IDs angegeben wurden.

Zusätzliche Postfix Konfigurationsdateien

In der main.cf haben wir auf viele Dateien verwiesen, die bis zu diesem Zeitpunkt noch nicht existierten. Diese erstellen wir jetzt. In den einzelnen Dateien werden die Informationen zur Datenbank abgelegt. Der einzelne Parameter aus der main.cf kann dann mit MySQL-Benutzer und -Passwort die Informationen aus der Tabelle lesen. Erstellen Sie folgende vier Dateien und achten Sie jeweils auf die Werte. Sollten Sie im vorherigen Teil andere Werte verwendet haben, müssen Sie das hier nun berücksichtigen.

  • vms-domains.cf
user = mailadmin
password = ...
dbname = mailserver
table = domains
select_field = 'virtual'
where_field = domain
hosts = 127.0.0.1
  • vms-forwardings.cf
user = mailadmin
password = ...
dbname = mailserver
table = forwardings
select_field = destination
where_field = source
hosts = 127.0.0.1
  • vms-mailboxes.cf
user = mailadmin
password = ...
dbname = mailserver
table = users
select_field = CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/')
where_field = email
hosts = 127.0.0.1
  • vms-email2email.cf
user = mailadmin
password = ...
dbname = mailserver
table = users
select_field = email
where_field = email
hosts = 127.0.0.1

Kleiner Zwischentest

Geben Sie in der Shell postfix reload und postfix check ein. Sollten keine Warnungen angezeigt werden, sind Sie mit diesem Teil fertig

TROUBLESHOOTING: Die Warnung „dict_open_dlinfo: wildcard dynamic map entry no longer supported.“ lässt sich relativ einfach beheben:

In der Datei /etc/postfix/dynamicmaps.cf diese Zeile…

/usr/lib/postfix/dict_%s.so      dict_%s_open

…ersetzen durch einzelne Ausdrücke, da Platzhalter wie * offensichtlich nicht (mehr) erlaubt sind. Das ganze sieht dann so aus:

tcp /usr/lib/postfix/dict_tcp.so dict_tcp_open 
pcre /usr/lib/postfix/dict_pcre.so dict_pcre_open 
sdbm /usr/lib/postfix/dict_sdbm.so dict_sdbm_open mkmap_sdbm_open

Der Eintrag:

mysql   /usr/lib/postfix/dict_mysql.so          dict_mysql_open

sollte ja sowieso existieren, damit Postfix auch was mit der MySQL DB anfangen kann.

Postfix und SASL (SMTP-Authentifizierung)

Postfix und SASL/MySQL

In dieser Konfiguration können Benutzer aus dem Netz mynetworks ohne Authentifizierung Mails verschicken. Jedoch soll es den selben Nutzern möglich sein, die sich außerhalb finden. Damit der Server kein offenes Relay darstellt und somit für Spam missbraucht werden kann, sollen sich die Benutzer authentifizieren. Dies soll per Benutzername und Passwort geschehen. Als erstes mal ein Verzeichniss erstellt, falls dieses noch nicht vorhanden ist:

mkdir /etc/postfix/sasl

Die Datei /etc/postfix/sasl/smtpd.conf anlegen (z.B mit touch smtpd.conf und dann ein vi smtpd.conf) und folgenden Inhalt einfügen:

pwcheck_method: saslauthd
auxprop_plugin: sql
mech_list: plain login
allow_plaintext: true
sql_engine: mysql
sql_hostnames: 127.0.0.1
sql_user: mailadmin
sql_passwd: ...
sql_database: mailserver
sql_select: select password from users where email='%u@%r'

Nun muss der saslauthd noch angepasst werden. Dazu wird folgendes gemacht:

mkdir -p /var/spool/postfix/var/run/saslauthd

Die Datei /etc/default/saslauthd mit einem Editor geöffnet und folgenden Inhalt einfügen bzw. ersetzen:

Wichtig: Vorher den saslauthd beenden. Und zwar mit '/etc/init.d/saslauthd stop'.

START=yes
MECHANISMS="pam"
OPTIONS="-m /var/spool/postfix/var/run/saslauthd -r"

Achtung: Lars hatte mich angeschrieben, weil er Probleme mit dem Saslauthd hatte. Er hat herausgefunden, dass PARAMS mit OPTIOS ersetzt werden muss. Dies kann ich nur darauf zurück führen, dass in Debian Etch diese Option geändert wurde.

Das Verzeichnis /var/spool/postfix/var/run/saslauthd sollte die Rechte 755 haben und dem User root:root gehören.

Außerdem benötigt es eine Anpassung beim PAM. Hier zu wieder mit einem Editor die Datei /etc/pam.d/smtp erstellen bzw. editieren:

auth    required   pam_mysql.so user=mailadmin passwd=password host=127.0.0.1 db=mailserver table=users usercolumn=email passwdcolumn=password crypt=1
account sufficient pam_mysql.so user=mailadmin passwd=password host=127.0.0.1 db=mailserver table=users usercolumn=email passwdcolumn=password crypt=1

Achtung: André hatte mich angeschrieben, das bei einer Lenny-Installation die Datei /etc/pam.d/smtp bereits folgende Einträge beinhaltet die Probleme mit dem Login machen:

@include common-auth
@include common-account
@include common-password

Diese Eintrage einfach entfernen oder auskommentieren und schon klappt es mit dem Login.

Damit Postfix auf SASL zugreifen kann, führen Sie einmal aus:

adduser postfix sasl

Danach den saslauthd wieder starten (/etc/init.d/saslauthd start).

Hinweis zum Update von Etch auf Lenny:

Der sasld macht nach einen Update von Etch auf Lenny einige Probleme.

Es finden sich dannn folgende Einträge im Log

SASL authentication failure: Password verification failed
SASL PLAIN authentication failed: generic failure
SASL authentication failure: cannot connect to saslauthd server: Permission denied
SASL LOGIN authentication failed: generic failure

Abhilfe ist ganz einfach :

Der OPTION-Eintrag in /etc/default/saslauth muss etwas erweitert werden auf

OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r"

und weiterhin muss der Postfix-User der Gruppe sasl zugefügt werden.

adduser postfix sasl

sowie eine kleine Vorbereitung für kommende Updates

dpkg-statoverride --add root sasl 710 /var/spool/postfix/var/run/saslauthd

Danach Postfix und saslauthd einmal neu starten (/etc/init.d/poistfix restart /etc/init.d/saslauthd restart).

TLS zur Verschlüsselung von SMTP

„Früher“ wurde bei vielen Anwendungen im Web das Passwort im Klartext übermittelt. Auch Provider, wie GMX haben sich nicht darum gekümmert die Passwörter ihrer Kunden vor fremden Zugriff zu schützen. Heutzutage ist endlich ein Bewusstsein entstanden, dass solche Informationen verschlüsselt werden müssen. Für Benutzer, die sich am SMTP authentifizieren müssen, wird nun ein Zertifikat erstellt. Wir werden ein eigenes erstellen, dass nicht von einer offiziellen (und kommerziellen) Zertifizierungsstelle signiert wurde. Sicherheitstechnisch birgt das keinen Nachteil. Wieder in das Postfix Verzeichnis gewechselt und das Zertifikat angelegt:

cd /etc/postfix
openssl req -new -outform PEM -out smtpd.cert -newkey rsa:2048 -nodes -keyout smtpd.key -keyform PEM -days 365 -x509

Country Name (2 letter code) [AU]:'''DE'''
State or Province Name (full name) [Some-State]:'''Munich'''
Locality Name (eg, city) []:'''Munich'''
Organization Name (eg, company) [Internet Widgits Pty Ltd]:'''FKDB'''
Organizational Unit Name (eg, section) []:'''Wiki'''
Common Name (eg, YOUR name) []:'''domain.de'''
Email Address []:'''postmaster@domain.tld'''

Ganz wichtig ist hier, dass der Common Name, der Hostname ist, auf den man sich schliesslich auch verbindet (bzw. in diesem Fall, der SMTP horch). Andernfalls meckert der Mail Client, dass das Zertifikat nicht korrekt ist.

Der Schlüssel darf nicht für alle Systembenutzer lesbar sein:

chmod 600 /etc/postfix/smtpd.key

Mal kurz testen

Führen Sie postfix reload aus, um Postfix neu zu starten. Dann führen Sie telnet localhost 25 aus und geben EHLO anywhere.org ein. Sie sollten dafür mit der Zeile 250-STARTTLS belohnt werden. Bingo - TLS funktioniert.

Tipp: Aus der Telnet-Sitzung kommen Sie mit der Tastenkombination Strg+5 wieder raus. Dann noch ein quit eingegeben und Sie befinden sich wieder auf der Konsole.

Einrichten von Courier-IMAP

Als erstes muss der Authentifizierungs Daemon eingerichtet werden. Hierzu muss die Datei /etc/courier/authdaemonrc folgende Zeile enthalten:

authmodulelist="authmysql"

Diese Zeile gibt dem Daemon bekannt, dass die Authentifizierung mittels einer MySQL Datenbank durchgeführt wird. Hier gibt es die verschiedensten Module, die den Rahmen der Dokumentation sprengen würden. Denkbar wäre zum Beispiel auch LDAP.

Als nächstes machen wir uns an die Datei /etc/courier/authmysqlrc ran. Beachten Sie hier, dass beim Bearbeiten dieser Datei keine unnötigen Leerzeichen eingefügt werden und ebenso auf keinen Fall Tabulatoren.

MYSQL_SERVER 127.0.0.1
MYSQL_USERNAME mailadmin
MYSQL_PASSWORD ...
MYSQL_PORT 0
MYSQL_DATABASE mailserver
MYSQL_USER_TABLE users
MYSQL_CRYPT_PWFIELD password
MYSQL_UID_FIELD 5000
MYSQL_GID_FIELD 5000
MYSQL_LOGIN_FIELD email
MYSQL_HOME_FIELD "/home/vmail"
MYSQL_MAILDIR_FIELD CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/')
# MYSQL_NAME_FIELD name

Wichtig: Kommentieren Sie MYSQL_NAME_FIELD aus, sonst wird der erzeugte SQL-Query zur Abfrage der Benutzerdaten beim Login fehlerhaft sein.

Nun starten wir den authdaemon noch neu: /etc/init.d/courier-authdaemon restart.

POP3/IMAP Zertifikate erstellen

Courier verwendet standardmäßig ein Zertifikat, das bei der Installation erzeugt wird. Möchte man ein eingenes Zertifikat generieren, geht man folgendermaßen vor:

Editieren Sie die Konfigurationsdatei /etc/courier/imapd.cnf (analog für pop3 /etc/courier/pop3d.cnf) und ersetzen Sie die vorgegebenen Werte durch Ihre eigenen. Anschliessend können die Zertifikate durch mkimapdcert (bzw. mkpop3dcert) erzeugen. Diese werden im Verzeichnis /usr/lib/courier erstellt und müssen anschliessend nach /etc/courier/ verschoben werden. Sie heißen imapd.pem (bzw. pop3d.pem).

IMAP:

vi /etc/courier/imapd.cnf
mkimapdcert
cd /usr/lib/courier
mv imapd.pem /etc/courier
ln -s /etc/courier/imapd.pem imapd.pem
/etc/init.d/courier-imap restart

POP3:

vi /etc/courier/pop3d.cnf
mkpop3dcert
cd /usr/lib/courier
mv pop3d.pem /etc/courier
ln -s /etc/courier/pop3d.pem pop3d.pem
/etc/init.d/courier-pop restart

Falls beim Erzeugen des Zertifikats ein Fehler ausgegeben wird, dass das zu generierende Zertifikat schon existiert, löschen Sie einfach das Standardzertifikat /etc/courier/imapd.pem

Fertig. Sie können nun mit dem Funktionstest der einzelnen Komponenten beginnen!

Der Funktionstest

Datenbank mit Daten versorgen

Sofern Sie und ich nichts vergessen haben, sollte der folgende Test erfolgreich durchzuführen sein. Hierzu muss in die Datenbank nun eine Domäne und ein Benutzer eingefügt werden. Außerdem muss für der entsprechende Benutzer (vorerst) auch händisch im Verzeichnis /home/vmail ein Unterverzeichnis erstellt werden:

cd /home/vmail
mkdir mailserver.de
cd mailserver.de
maildirmake claus

Wichtig: Ändern Sie den Besitzer des neu angelegten Ordners auf 'vmail' ab.

Je nachdem, wie ihre Domäne heisst, fügen Sie diese der Tabelle domains zu (zu beachten ist natürlich, wie Sie in vorherigen Schritten die Domain genannt haben):

Feld Wert
domain mailserver.de

Und nun ein Benutzer. Zu beachten ist das Passwortfeld. Dies wird mit der MySQL-Funktion ENCRYPT() verschlüsselt. Diesem Benutzer haben Sie mit dem Befehl maildirmake ein Benutzerverzeichnis erstellt.

Feld Wert
email claus@mailserver.de
password IhrPasswort

WICHTIG: Hier muss darauf geachtet werden, dass das Feld Passwort mit der MySQL Funktion ENCRYPT verschlüsselt werden muss. Dies geht ganz einfach über phpmyadmin. Oder per Kommandozeile:

ENCRYPT('IhrPasswort')

Forwardings

Um Forwardings zu erstellen, muss man einfach in der Datenbank in der Tabelle forwardings die Adressen eintragen.

Source: Wohin die E-Mail ursprünglich geschickt wurde. Destination: Wohin die E-Mail geleitet werden soll.

Beispiele:

Source: @domain.de Destination: root@domain.de

Dieses Beispiel würde alle E-Mails an die Domain an root@domain.de weiterleiten

Source: webmaster@domain.de Destination: root@domain.de root@bla.de

Der Test

Jetzt können Sie ihren Mail konfigurieren und probieren, ob Sie sich eine Mail zuschicken können. Oder wir nutzen telnet, um eine Mail zu verschicken:

# telnet localhost 25

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 sprayen.de ESMTP Postfix (Debian/GNU)

ehlo mailserver.de

250-mailserver.de
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250 8BITMIME

mail from:<claus@mailserver.de>

250 Ok

rcpt to:<claus@mailserver.de>

250 Ok
data
354 End data with <CR><LF>.<CR><LF>

Dies ist eine Telnet Mail.
.

250 Ok: queued as 9D72563306

quit

221 Bye
Connection closed by foreign host.

In den Logdateien /var/log/syslog bzw. /var/log/mail.log sollte nun etwa folgendes zu finden sein:

Mar 16 12:46:16 hostname postfix/smtpd[7463]: connect from hostname[127.0.0.1]
Mar 16 12:46:16 hostname postfix/smtpd[7463]: A5D2E31AC: client=hostname[127.0.0.1]
Mar 16 12:46:33 hostname postfix/cleanup[7511]: A5D2E31AC: message-id=<20060316124633.A5D2E31AC@hostname>
Mar 16 12:46:34 hostname postfix/qmgr[7511]: A5D2E31AC: from=claus@mailserver.de, size=313, nrcpt=1 (queue active)
Mar 16 12:46:59 hostname postfix/virtual[7513]: A5D2E31AC: to=claus@mailserver.de, relay=virtual, delay=10, status=sent (delivered to maildir)

Die zugestellte Mail sollte sich nun im Homeverzeichnis des Benutzers vmail befinden:

find /home/vmail

Wenn alles soweit funktioniert hat, können Sie sich auf die Schulter klopfen. Wenn es Probleme gibt, dann kontrollieren Sie noch einmal alle vorhergehende Schritte und wenden sich bei unlösbaren Problemen an mich, über das Forum (http://forum.freakempire.de).

Fügen Sie nun alle Benutzer und Domänen in die Datenbank ein. Wie oben schon beschrieben.

Der Spamassassin

Im Zeitalter die E-Mail Kommunikation ist leider das Spam-Aufkommen in den letzten Jahren drastisch gestiegen. Leider hat man in der Entwicklung der Mail-Protokolle, dies damals nicht berücksichtigt. Als Beispiel, kann man als Absender jede beliebe Adresse angeben, ohne das dies beim Empfänger geprüft wird. Mittlerweile haben sich aber auch Gegenmaßnahmen, wie z.B Spamfilter, entwickelt, die dem entgegen steuern. Spamassassin ist ein solches Programm, dass recht zuverlässig Spam filtert.

Den Spamassassin haben wir ganz am Anfang schon installiert.

Konfiguration

Spamassassin

Als erstes wird die Datei /etc/spamassassin/local.cf editiert:

required_hits 3
add_header all Level _STARS(X)_
rewrite_header Subject Spam [_HITS_]
dns_available yes
auto_learn 1

Diese Einstellungen bedeuten, dass ab 3 Punkten, die Mail als Spam identifiziert wird. Mails die ich für normal erhalte, haben einen Score von -3.0 bis +2.0. Aber das heisst noch nicht, dass wir Mails mit einem Score über 3.0 löschen. Dazu später mehr. Bei den folgenden zwei Zeilen werden dem Header Informationen zugefügt. Ein solcher generierter Header vom SA (Spamassassin) schaut z.B so aus:

X-Spam-Checker-Version: SpamAssassin 3.1.0 (2005-09-13) on localhost.intern X-Spam-Status: No, score=-2.2 required=3.0 tests=AWL,BAYES_00,HTML_40_50, HTML_MESSAGE,SPF_HELO_PASS autolearn=ham version=3.1.0

Diese Header Informationen werden wir später noch benötigen.

Sollte SA zuviele Emails aussortieren, den Wert auf 5.0 stellen.

Postfix

Bei Postfix muss nun die Datei master.cf angepasst werden. Folgende zwei Zeilen sind wichtig. Der Rest der Datei muss so bleiben wie er ist.

smtp inet n - - - - smtpd -o content_filter=spamassassin
[...]
spamassassin unix - n n - - pipe user=vmail argv=/usr/bin/spamc -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}

Nun muss folgende Änderung in der Datei '/etc/default/spamassassin' vorgenommen werden:

ENABLED=1

Nun Postfix und den Spamassassin neu starten:

/etc/init.d/postfix restart
/etc/init.d/spamassassin restart

Der Spamassassin braucht eine Zeit lang „zu lernen“ was Spam ist und was nicht. Haben Sie Geduld. Es gibt die Möglichkeit mit dem Programm sa-learn manuell dem Spamassassin Spam beizubringen. Ich werde dies bei Gelegenheit in die Dokumentation aufnehmen.

Maildrop

Ich nutze Maildrop, um Spam entweder zu löschen, oder in einen Ordner zu verschieben, in dem möglicher Spam aufbewahrt wird. Quasi Mails, bei dem man nicht 100% sagen, dass es sich wirklich um Spam handelt und von einem menschlichem Auge begutachtet werden sollte.

Dazu wird wieder an Postfix geschraubt. Erst die main.cf. Diese wird um zwei Zeilen ergänzt:

maildrop_destination_recipient_limit = 1
virtual_transport = maildrop

Außerdem nochmal die Postfix Datei master.cf. Diese wird um eine Zeile ergänzt:

maildrop unix - n n - - pipe flags=DRhu user=vmail argv=/usr/bin/maildrop -d vmail ${user} ${nexthop}

Nun gehen Sie in das Verzeichnis /home/vmail und erstellen eine Datei .mailfilter mit den folgenden Rechten:

cd /home/vmail
touch .mailfilter
chmod 600 .mailfilter
chown vmail:vmail .mailfilter

Und folgendem Inhalt:

RECIPIENT=$1
DOMAIN=$2
SPAMDIR = $HOME/$DOMAIN/$RECIPIENT/.Lowspam/
TRASHDIR = $HOME/$DOMAIN/$RECIPIENT/.Trash/
import SENDER
DEFAULT=$HOME/$DOMAIN/$RECIPIENT
SPAM=7
LOWS=3

if ( /^(X-Spam-Status: Yes, score=)([0-9]+)\./ )
{
    if ( $MATCH2 >= $SPAM )
    {
    DELTAG=1
    to $TRASHDIR
    }
   if ( $MATCH2 >= $LOWS )
    {
    `test -d $SPAMDIR`
    if ( $RETURNCODE == 1 )
    {
    `/usr/bin/maildirmake $SPAMDIR`
    }
    exception {
        to $SPAMDIR
    }
   }
}

Das ist nun eine wirkliche Bastlerlösung. Leider habe ich es noch nicht geschafft, maildrop auch über eine MySQL Datenbank mit Informationen zu versorgen. Diese .mailfilter prüft, welchen Score die Mail vom SA erhalten hat. Sollte der Score 3.0 erreicht worden sein, wird die Mail in das IMAP Verzeichnis .Lowspam geschoben. Existiert das Verzeichnis nicht, wird es erstellt (mit maildirmake). Erreicht die Spam-Mail einen Score von 7, wird sie in das Verzeichnis .Trash geschoben. Dieser .mailfilter gilt global für alle Benutzer, weshalb es eventuell nicht wünschenswert ist. Wünschenswert wäre hingegen, dass sich jeder User selber Filterregeln erstellen kann.

Sobald ich dies geschafft habe, werde ich diese Doku erweitern.

Das Webmail Interface

Es ist immer praktisch, wenn man von jedem Rechner mit Internetzugang auf seine Mails zugreifen kann. Um auch auf ihrem Mailserver ein Webinterface zu nutzen, sollten Sie einen Apache mit SSL Unterstützung laufen haben.

Squirrelmail ist eine sehr gute Webmail Applikation. Sehr einfach zu installieren und konfigurieren. Sie sollten es aber wirklich nur über einen SSL Webserver nutzen.

Squirrelmail erhält man hier: http://www.squirrelmail.org/

Maildrop variabel für die virtuellen User

Mein erster Ansatz war es, die Maildrop-Regeln variabler für die virtuellen User anzulegen. Dies ist eigentlich sehr einfach.

Beim Maildrop-Aufruf werden der Name und der Domain des virtuellen Users übergeben.

Mittels einfacher Regeln lassen sich so User, Domain und Domainübergreifende Userregeln erstellen.

Domainregeln

`test -f $HOME/rulez.$DOMAIN`
if ( $RETURNCODE == 0 )
{
    include $HOME/rulez.$DOMAIN
}

Userregeln

`test -f $HOME/rulez.$RECIPIENT@$DOMAIN`
if ( $RETURNCODE == 0 )
{
    include $HOME/rulez.$RECIPIENT@$DOMAIN
}

Domainübergreifende Userregeln

(intressant für webmaster@ postmaster@ usw.)

`test -f $HOME/rulez.$RECIPIENT@all`
if ( $RETURNCODE == 0 )
{
    include $HOME/rulez.$RECIPIENT@all
}

Spamassassin-Regeln in eine MySQL-DB

Mich störten auch die unflexiblen Regeln vom Spamassassin in den Konfigurationsdateien. Weiterhin sollten auch diese Regeln speziell für die virtuellen User anpassbar sein.

Deshalb werden die Regeln in eine MySQL-Datenbank ausgelagert. Es ist jedoch weiterhin möglich über die Konfigurationsdatei Werte zu setzen.

Allerdings benötigt Spamassassin PERL und einige CPAN-Module für den Datenbankzugriff, diese werden wir jetzt installieren.

PERL

Als erstes werden wir Perl CPAN auf die aktuellste Version updaten. Dazu in der Konsole

perl -MCPAN -e shell

Nehmen Sie die Standardeinstellungen. Wenn sie CPAN das erste mal benutzen, kommen ein paar Fragen (die default-Werte können so übernommen werden) und Perl wird in /usr/local/bin/perl neu kompiliert. Das kann unter Umständen ein bisschen dauern.

Anschließend

install Bundle::CPAN

um CPAN zu aktualiesieren und auch hier werden einige Fragen zum komplieren kommen. Anschliessend

reload cpan

Nun noch ein paar weitere Befehle, die weitere von Spamassassin benötige Module installiert

conf prerequisites_policy ask
install HTML::Parser
install DB_File
install Net::DNS
install Digest::SHA1
install MIME::Base64
install IP::Country::Fast
install Mail::SpamAssassin
install Mail::SPF::Query
quit

Damit ist die Installation von PERL beendet

Die Spamassassin-Datenbank

Spamassassin benötigt dafür eine Datenbank. Es besteht die Möglichkeit die mailserver-Datenbank um eine Tabelle zu erweitern, da mir aber eine saubere Trennung lieber ist, habe ich mich für eine weitere Datenbank und einen weiteren MySQL-User entschieden.

Deshalb eine Datenbank angelegt. Auch deser Name kann frei gewählt werden. In diesem Beispiel lautet der Name spamassassin.

mysqladmin -u root -p -h localhost create spamassassin

Auch hier erstellen wir einen Benutzer, der auf die Datenbank Zugriff hat. Ich nenne ihn spamassassin. Und zum Schluss werden die Benutzerdaten und die Zugriffsrechte neu eingelesen.

mysql -u root -p -h localhost
mysql> grant select on spamassassin.* to spamassassin@localhost identified by 'Passwort';
mysql> flush privileges;

Das erstellen der Datanbank erfolgt analog der DB-Erstellung us dem HowTo per Kommandozeile oder per phpmyadmin mit mit folgendem SQL-Befehl:

CREATE TABLE userpref (
  username varchar(100) NOT NULL default '',
  preference varchar(50) NOT NULL default '',
  value varchar(200) NOT NULL default '',
  prefid int(11) NOT NULL auto_increment,
  PRIMARY KEY  (prefid),
  KEY username (username)
) TYPE=MyISAM;

Die Spamassassin-Regeln

Weiterhin fügen wir gleich ein paar globale Regeln ein:

username preference value
$GLOBAL required_score 3
$GLOBAL add_header all TEST Datenbankregeln IO
$GLOBAL add_header all Level _STARS(X)
$GLOBAL rewrite_header Subject Spam [_HITS_]
$GLOBAL dns_available yes
$GLOBAL auto_learn 1

Erläuterung zu den Regeln:

  • username

$GLOBAL Regel gilt für alle Mailaccounts %mailserver.de Regel gilt für alle Mailaccounts des Domains mailserver.de user@mailserver.de Gilt nur für den speziellen Mailaccount

  • preference

o Einträge siehe Spamassassin-Doc [1]

  • value

o Einträge siehe Spamassassin-Doc [2]

Die Spamassassin-Konfiguration

Jetzt muss noch die Konfiguration von Spamassassin angepasst werden.

Dazu den Eintrag OPTIONS in /etc/default/spamassassin anpassen

OPTIONS="-u vmail --create-prefs --max-children 5 --sql-config --helper-home-dir=/var/vmail
         --virtual-config-dir=/var/vmail/spamassassin"

und die Datei local.cf in /etc/spamassassin um die Datenbankzugriff erweitern

user_scores_dsn			DBI:mysql:spamassassin:localhost
user_scores_sql_username	spamassassin
user_scores_sql_password	Passwort
user_scores_sql_custom_query    SELECT preference, value FROM _TABLE_ WHERE username = _USERNAME_ 
                                OR username = '$GLOBAL' OR username = CONCAT('%',_DOMAIN_) ORDER BY username ASC

Der Eintrag user_scores_sql_custom_query bitte in eine Zeile !!

Anschliessend noch ein mit /etc/init.d/spamassassin restart den Spamassassin neustarten und schon sollten die Regeln aus der Datenbank funktionieren. Zum testen ob die Regeln funktionieren : Die 2. Regel bewirkt einen Headereintrag an dem man leicht erkennen kann das die Regel auch benutzt werden. Der Headereintrag sollte dann so aussehen : X-Spam-TEST: Datenbankregeln IO

Postfix anpassen

Bisher funktioniern zwar die Regeln aus der Datenbank, allerdings funktioniert die Zuordnung der Regeln zu den virtuellen Usern nicht, da Spamassassin die virtuellen User nicht kennt.

Auch hier bin ich einen anderen Weg gegangen als das HowTo. Ich binde den Spamassassin nicht per Postfix sondern per Maildrop ein.

Dazu müssen die Einträge in der master.cf von Postfix wieder rückgangig gemacht werden.

Weiterhin muss die Datei .mailfiter aus dem Howto in /home/vmail um einen xfilter-Eintrag erweitert werden.

RECIPIENT=$1
DOMAIN=$2

...

xfilter "/usr/bin/spamc -u $RECIPIENT@$DOMAIN"

if ( /^(X-Spam-Status: *Yes, score=)([0-9]+)\./ )
...

eMails auf Viren untersuchen

Leider gehört es heute schon fast zur Pflicht, seine eMails auf Viren zu untersuchen. Zum einbinden von Spamassassin und Virenscannern in ein Mailserver wird meistens auf AMaViS (A Mail Virus Scanner) zurückgegriffen. Da wegen der Spamregeln der virtuellen User Spammssassin bereits über maildrop aufgrufen wird habe ich mich auch beim Antivirusprog gegen AMaViS entschieden und binde auch den Virenscanner per maildrop ein. Diese Möglichkeit bietet natürlich nicht ganz die Einstellmöglichkeiten von AMaViS, reichen für meine Bedürfnisse allerdings aus.

Virenscanner installieren

Beim Virenscanner habe ich mich für ClamAV entschieden. Er läßt sich leicht per apt-get install clamav installieren.

Das Virenscannerscript erstellen

Um den Virenscanner in die mailfilter-Datei in /home/vmail einzubinden wird noch ein kleines Script benötigt. Dieses Script wird mit

touch     /home/vmail/bin/clamscan.sh
chmod 750 /home/vmail/bin/clamscan.sh

erstellt und das Script ausführbar gemacht.

Diese Datei mit eine beliebigen Editor dann bearbeiten das sie so aussieht

!/bin/bash
# Created by Tom Walsh, slim at ala.net
# slightly modified by Wolfgang Ziegler, nuppla at gmx.at
 
RUN=clamscan
# Enable this line, if you are using the clamav-daemon.
# RUN=clamdscan
 
#start
MSG=$(cat /proc/self/fd/0) # stdin -> $MSG
SCAN=$(echo "$MSG" | $RUN - --stdout --disable-summary)
EXIT="$?"
VIRUS=$(echo "$SCAN" | awk '{print $2}')
SUBJECT=$(echo "$MSG" | reformail -x Subject:)
 
if [ "$EXIT" == "1" ]; then
 SUBJECT="**VIRUS** [$VIRUS] $SUBJECT"
 MSG=$(echo "$MSG" | reformail -i"X-Virus-Status: INFECTED")
 MSG=$(echo "$MSG" | reformail -i"Subject: $(echo "$SUBJECT")")
else
 MSG=$(echo "$MSG" | reformail -i"X-Virus-Status: CLEAN")
fi
 
echo "$MSG"
exit 0

Einbinden in den Mailfilter

Das Script kann dann einfach in die Mailfilter eingebunden werden.

Als erstes wird der Ablageort für virenverdächtige eMails gesetzt. Ich lege zur Sicherheit auch diese eMails nach User & Domain getrennt ab und markiere die Einträge der eMail im Logfile. Weiterhin sollten nur eMails ab einer bestimmten Größe gescannt werden, da das scannen der eMails besonders bei größeren eMails recht systemlastig werden kann.

# Ablageort für als virenverdächtigte eingestufte eMails
VIRUSQUARANTINE = $HOME/VIREN/$DOMAIN-$RECIPIENT/

# eMails scannen ??
VSCAN=1

# Nur eMails kleiner VSCANSIZE scannen
VSCANSIZE="2000000"

if ( $VSCAN )
{
    if( $SIZE < $VSCANSIZE )
    {
        exception {
          xfilter "/home/vmail/bin/clamscan.sh"
        }
    }

    if(/^X-Virus-Status:.*INFECTED/)
    {
      exception {
         log "Viren-Mail !!!"
         to $VIRUSQUARANTINE
      }
    }
}

Weitere Planung

  • Ein CRON-Auftrag der regelmäßig die Virenmailordner leert
  • Evtl. die eMail-Accounts über eine eingegangene Viren-eMail informieren.

Mailvorfilterung

Greylisting

Das Greylisting Verfahren bezeichnet eine Form der Spam-Bekämpfung bei E-Mails, bei der die erste E-Mail von unbekannten Absendern zunächst abgewiesen und erst nach einem weiteren Zustellversuch angenommen wird.

Unter Debian findet man für Postfix folgende Greylisting-Daemons:

Postgrey

Postgrey ist ein Greylist-Server der mit Berkeley-DBs arbeitet.

Installieren geht Debian-like per

apt-get install postgrey

dann noch die main.cf von postfix ( /etc/postifx/main.cf ) editieren und die smtpd_recipient_restrictions um

check_policy_service inet:127.0.0.1:60000

erweitern.

Sollte dann also etwa so aussehen

smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_policy_service inet:127.0.0.1:60000

Danach Postgrey und Postfix einmal neu starten (/etc/init.d/postgrey restart /etc/init.d/postfix restart).

Das wars.

sqlgrey

sqlgrey basiert nicht auf textbasierten Berkeley-DB sondern nutzt SQL-Datenbanken (MySQL, SQLite oder PostgreSQL).

Das macht das ganze absturzsicherer, da es durchaus vorkommen kann das nach einem Servercrash die DBs von PostGrey nicht mehr lesbar sind, und aus diesem Grund der Mailserver keine Mails mehr annimmt.

Auch hier geht das installieren per

apt-get install sqlgrey

dann noch die main.cf von postfix ( /etc/postifx/main.cf ) editieren und die smtpd_recipient_restrictions um

check_policy_service inet:127.0.0.1:2501

erweitern.

Sollte dann also etwa so aussehen

smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_policy_service inet:127.0.0.1:2501

Auch hier benötigen wir eine Datenbank und einen MySQL-User welche genauso wie beim Mailserver angelegt werden.

mysqladmin -u root -p -h localhost create greysql

mysql -u root -p -h localhost
mysql> grant select on greysql.* to greysql@localhost identified by 'Passwort';
mysql> flush privileges;

Hinweis:

Wenn die Datenbank über ein anderes Programm angelegt wird, die Datenbank darf NICHT als CHARACTER SET utf8 haben, sqlgrey arbeite dann nicht damit.


Nun die Konfigurationsdatei von SQLGrey editieren

vi /etc/sqlgrey/sqlgrey.conf

und mindestens folgende Einträge vornehmen (db_pass entsprechend ampassen)

db_type = mysql
db_name = sqlgrey

db_host = localhost
db_port = default
db_user = sqlgrey
db_pass = ...

Jetzt noch den SQLGrey und Postfix einmal neu starten (/etc/init.d/sqlgrey restart /etc/init.d/postfix restart).

Für sqlgrey gibt es eine kleine, aber ausreichende Adminoberfläche sgwi (SQLGrey Web Interface).

Weitere Möglichkeiten

Postfix kann die Entscheidung, ob eine Mail angenommen wird, an einen externen policy daemon delegieren. An Hand von DNS Daten, inkonsistente HELO Strings und RBLs können Mails bereits während des SMTP Dialogs abgelehnt werden. Das spart Bandbreite, schont die CPU durch weniger Scans mit Spamassassin o.ä. Tools auf dem Mailserver und erspart rejects für fälschlicherweise auf einer Blackliste geführten sauberen Host. Auch Greylisting ist mit diesen Daemons möglich.

Unter Debian findet man für Postfix folgende Daemons:

policyd-weight

Inhalt folgt noch…

postfix-policyd

Inhalt folgt noch…

Erstellen eines globalen CA-signierten SSL-Zertifikates

Falls die unterschiedlichen Zertifikate der einzelnen Mailsysteme stören, kann man sich auch ganz einfach ein globales Zertifikat erstellen. Das mach auch ein späteres Update des Zertifikates, z.B. bei Ablauf, einfacher.

Da Zertifikate, die nur selbstunterschreiben wurden, als unsicher gelten und in neueren Browser zu Fehlermeldungen führen (Fehlercode: sec_error_ca_cert_invalid) kann und sollte man dieses auch von einer CA (Certificate Authority), z.B. CACERT, signieren lassen.
Sollte man eine CA wählen die in den Browsern bereits als Zertifizierungsstelle vorhanden ist braucht man sein Zertifikat auch nicht mehr in die Zertifikatsliste der Browser importieren, sie werden anstandslos akzeptiert.

Vorarbeiten

Als Ablageordner des Zertifikates und des Schlüssels wähle ich /etc/.my_ssl/mailserver/ Diesen Ordner legen wir erst einmal an

mkdir -p /etc/.my_ssl/mailserver

Erzeugen eines RSA Schlüssels

Als erstes erzeugen wir einen RSA-Schlüssel

openssl genrsa -out /etc/.my_ssl/mailserver/mailserver.key 2048

Erstellen einer Config-Datei

Nun erstellen wir eine Config-Datei die die persönlichen Infos unseres Zertifikates enthält Dazu mit

vi /etc/.my_ssl/openssl.mailserver.conf

eine Datei mit folgendem Inhalt erstellen

RANDFILE               = $ENV::HOME/.rnd

[ req ]
default_bits = 2048
default_keyfile = keyfile.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
prompt = no
output_password = topsecret

[ req_distinguished_name ]
C = DE
ST = [State or Province Name]
L = [Locality Name]
O = [Organizational Name]
OU = [Organizational Unit Name]
CN = DOMAINNAME --- WICHTIG !!!!
emailAddress = mailmaster@DOMAINNAME

[ req_attributes ]
challengePassword = 

Erstellen einer CSR-Datei

Um das Zertifikat signieren zu lassen benötigen wir eine CSR-Datei (Certificate Signing Request).

Diese erstellen wir:

openssl req -new -nodes -days 3650                        \
        -key    /etc/.my_ssl/mailserver/mailserver.key    \
        -out    /etc/.my_ssl/mailserver/mailserver.csr    \
        -config /etc/.my_ssl/openssl.mailserver.conf

Signiertes Zertifikate erstellen

Die ebend erstellte CSR-Datei kopieren und bei der CA signieren lassen.
Da dieses von CA zu CA unterschiedlich ist kann ich hier nur auf die Hilfe-Seiten des entsprechende Webseite verweisen.

Kurzanleitung CACERT
  • Unter Domains den Domain und gegebenenfalls den Subdomain anmelden und bestätigen.
  • Unter Server Zertifikate per Copy&Paste den Inhalt der CSR-Datei einfügen.
  • Wenn alles korrekt ist erhält man kurz darauf das Zertifikat.
  • Dieses dann per Copy&Paste in die CRT-Datei einfügen.

Erstellen einer CRT-Datei

Die von der CA erhaltenen Daten in die CRT-Datei (Certificate) einfügen

vi /etc/.my_ssl/mailserver/mailserver.crt

Erstellen einer PEM-Datei

Das Zertifikat liegt jetzt in 2 Dateien vor, dem Key (mailserver.key) und dem Zertifikat (mailserver.crt). Für den SMTP-Server benötigen wir das Zertifikat jedoch als PEM-Datei, die wir uns ganz einfach erstellen können.

cat 	/etc/.my_ssl/mailserver/mailserver.crt 	\
	/etc/.my_ssl/mailserver/mailserver.key 	\
	> /etc/.my_ssl/mailserver/mailserver.pem

Sicherheit

Auch dieser Schlüssel darf nicht für alle Systembenutzer lesbar sein:

chmod 600 /etc/.my_ssl/mailserver/mailserver.key

In den Configs des Mailserver einarbeiten

Anschliessen brauchen wir nur noch die Konfigurationen des Mailsystemes anzupassen. Dazu in den fogenden Dateien die entsprechenden Parameter anpassen.

Protokol Datei Parameter Alt Neu
SMTP /etc/postfix/main.cf smtpd_tls_cert_file = /etc/postfix/smtpd.cert /etc/.my_ssl/mailserver/mailserver.crt
SMTP /etc/postfix/main.cf smtpd_tls_key_file = /etc/postfix/smtpd.key /etc/.my_ssl/mailserver/mailserver.key
POP3 /etc/courier/pop3d-ssl TLS_CERTFILE = /etc/courier/imapd.pem /etc/.my_ssl/mailserver/mailserver.pem
IMAP /etc/courier/imapd-ssl TLS_CERTFILE = /etc/courier/pop3d.pem /etc/.my_ssl/mailserver/mailserver.pem

SSL für einen Webserver benutzen

Das erstellte Zertifikat kann natürlich auch für eine Webmail Interface benutzt werden. Dazu muss das Webmail Interface unter dem selben Domain laufen der im Zertifikat angegeben wurde.

Beispiel-Konfiguration für Webserver Apache2

NameVirtualHost *IP-Adresse*:443
<VirtualHost *IP-Adresse*:443>
        ServerName DOMAIN.DE:443
        ServerAdmin webmaster@DOMAIN.DE
    # SSL
        SSLEngine On
            SSLCipherSuite HIGH:MEDIUM
            SSLCertificateFile    /etc/.my_ssl/mailserver/mailserver.crt
            SSLCertificateKeyFile /etc/.my_ssl/mailserver/mailserver.key
    # Web-Verzeichnis
        DocumentRoot /var/www/mail_ssl
            <Directory /var/www/mail_ssl>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
            </Directory>
</VirtualHost>

F.A.Q / Sonstige Fragen Antworten

Fehlermeldung vom spamassassin im syslog

F: Ich erhalte folgende Fehlermeldungen beim Empfangen einer Mail im syslog:

Mar 21 21:05:22 hostname spamd[5338]: Use of uninitialized value in hash element at /usr/share/perl5/Mail/SpamAssassin/Message/Metadata/Received.pm line 321, <GEN2> line 36.
Mar 21 21:05:22 hostname spamd[5338]: Use of uninitialized value in hash element at /usr/share/perl5/Mail/SpamAssassin/Message/Metadata/Received.pm line 322, <GEN2> line 36.
Mar 21 21:05:22 hostname spamd[5338]: Use of uninitialized value in hash element at /usr/share/perl5/Mail/SpamAssassin/Message/Metadata/Received.pm line 321, <GEN2> line 36.
Mar 21 21:05:22 hostname spamd[5338]: Use of uninitialized value in hash element at /usr/share/perl5/Mail/SpamAssassin/Message/Metadata/Received.pm line 322, <GEN2> line 36.
Mar 21 21:05:22 hostname spamd[5338]: Use of uninitialized value in pattern match (m//) at /usr/share/perl5/Mail/SpamAssassin/Message/Metadata/Received.pm line 210, <GEN2> line 36.
Mar 21 21:05:22 hostname spamd[5338]: Use of uninitialized value in pattern match (m//) at /usr/share/perl5/Mail/SpamAssassin/Message/Metadata/Received.pm line 212, <GEN2> line 36.
Mar 21 21:05:22 hostname spamd[5338]: Use of uninitialized value in concatenation (.) or string at /usr/share/perl5/Mail/SpamAssassin/Message/Metadata/Received.pm line 213, <GEN2> line 36.

A: Der perl DNS Support fehlt. Unter Debian ganz einfach behoben mit:

apt-get install libnet-dns-perl

Tipps

Benötigte aber gelöschte Ordner unter IMAP

Eines meiner schlimmsten Probleme war das, das meine IMAP-Benutzer vordefinierte und benötigte Ordner umbenennen oder komplett löschen, z.B. der Spam-Ordner oder Ordner in dem Newsletter zugeordnet werden.

Deshalb habe ich meine Maildrop-Filtern etwas erweitert und 2 Dateien erstellt, so das ich sicherstellen kann das wichtige Ordner überprüft werden und gegebenfalls neu angelegt werden.

Datei /home/vmail/.maildirmake mit folgendem Inhalt :

`test -d $DIR`
if ( $RETURNCODE == 1 )
{
   `/usr/bin/maildirmake $DIR`
}

Datei /home/vmail/.mkdir mit folgendem Inhalt :

`test -d $DIR`
if ( $RETURNCODE == 1 )
{
   `/bin/mkdir $DIR`
}

Anschliessend habe ich ich meine Maildrop-Regel etwas umgeschrieben.
Um dafür zu sorgen das wichtige Ordner IMMER vorhanden sind:

# Domainverzeichnis
    DIR="$HOME/maildir/$DOMAIN"
    include $FILTERDIR/.mkdir
# Userverzeichnis
    DIR="$DEFAULT"
    include $FILTERDIR/.maildirmake
# Spamdir
    DIR="$SPAMDIR"
    include $FILTERDIR/.maildirmake

oder direkt vor der Zuordnung in einen Ordner, dann

    if(/^X-Status:.*NEWSLETTER/)
    {
      exception {
         to $HOME/$DOMAIN/$RECIPIENT/.Newsletter/
      }
    }

umgeschrieben in

    if(/^X-Status:.*NEWSLETTER/)
    {
      exception {
         DIR="$HOME/$DOMAIN/$RECIPIENT/.Newsletter/"
         include $HOME/.maildirmake
         to $DIR
      }
    }

Filterung per GDBM

Auf der Suche nach einer einfachen Zuordnung von eMails einer Absenderadresse zu einem IMAP-Ordner habe ich eine einfache Lösung per GDBM gefunden. GDBM-Datenbanken sind dateibasierter Datenbanken.

Dazu muss man erstmal eine einfache GDBM-Datenbank erstellen, leider ist der GDBM-Support in PHP-Version aus Debian Etch nicht vorhanden ist weshalb ich auf Ruby umgeschwenkt bin.

Mittels apt-get (oder aptitude) werden die benötigten Pakete installiert.

apt-get update
apt-get install ruby libgdbm-ruby

Dann erstellen wir ein kleines Ruby-Script /home/vmail/bin/gdbm_cmd.ry

#!  /usr/bin/ruby -w
dbfile="/home/vmail/newsletter.db"
if ARGV[0] == "add"
    if ARGV[1] && ARGV[2]
        require 'gdbm'
        GDBM.open(dbfile) { |gdbm|
            gdbm[ ARGV[1] ] = ARGV[2]
        }
        print "1"
    else
        print "0"
    end
elsif ARGV[0] == "del"
    if ARGV[1]
        require 'gdbm'
        GDBM.open(dbfile) { |gdbm|
            gdbm.delete ARGV[1]
        }
        print "1"
    else
        print "0"
    end
elsif ARGV[0] == "list"
    require 'gdbm'
    count = 0
    gdbm = GDBM.open(dbfile)
    gdbm.each_pair do |key,value|
        count += 1
        print "#{count}\t#{key}\t#{value}\n"
    end
    gdbm.close
else
    print "\n\tERROR\n\n"
end

und anschliessend wird das Script ausführbar gemacht.

chmod 750 /home/vmail/bin/gdbm_cmd.ry

Jetzt füllen wir die GDBM-Datenbank.

Alle eMails der Absender test@abc.de und test@xyz.de kommen in de Ablage,
der Newsletter von newsletter@xyz.de in den Unterordner XYZ des Ordners Newsletter

gdbm_cmd.ry add test@abc.de Ablage
gdbm_cmd.ry add test@xyz.de Ablage
gdbm_cmd.ry add newsletter@xyz.de Newsletter.XYZ

Nun fehlt nur noch der dazu gehörende Maildrop-Filter

gdbmopen("/home/vmail/newsletter.db")
foreach /^(To|Cc): .*/
{
    foreach (getaddr($MATCH)) =~ /.+/
    {
        listbox = gdbmfetch(tolower($MATCH))
        if ($listbox ne "")
        {
            DIR="$HOME/$DOMAIN/$RECIPIENT/.$listbox"
            include $HOME/.maildirmake
            to $DIR
        }
    }
}
gdbmclose

Weitere Befehle für die Datenbank

Löschen eines Eintrages

gdbm_cmd.ry del test@abc.de Ablage

Anzeige alle Datenbank-Einträge

gdbm_cmd.ry list

Mailadmin per Webseite

Zu guter Letzt

Quellen

Autoren

Fragen

Hi, zuersteinmal danke für das aussergewöhnlich ausführliche HowTo. Trotzdem hab ich zwei Probleme:

1.Ich habe gerade mal versucht, eine neue Emailadresse anzulegen, indem ich einfach in die Tabelle users eine entsprechend neue Zeile eingetragen habe. Irgendwie scheint das aber nicht auszureichen. Muss ich immer noch per Hand in /home/vmail/domain.de/ einen neuen Mailuser eintragen?

2.Wie kann ich Aliase anlegen? Das muss doch auch irgendwie über MySQL gehen?

— Tobias Dobberphul 2010/02/01 23:20


Hi Tobias,

lies dir mal nochmal diesen Abschnitt durch, da steht das eigentlich beides:

http://wiki.freakempire.de/doku.php/linux/virtueller_e-mail_server_unter_debian_etch_und_postfix#der_funktionstest

zu 1.) Ja, musst du. Einmal mit maildirmake ein Verzeichnis für jeden User für die entsprechende Domain (auf Besitzer achten).

zu 2.) Ja, das geht. Steht hier: http://wiki.freakempire.de/doku.php/linux/virtueller_e-mail_server_unter_debian_etch_und_postfix#forwardings

Viele Grüße, — Tim Rühenbeck 2010/02/08 13:42


Hi Tim,

das man mehrere Adressen mit Leerzeichen eingeben kann, hab ich übersehen, danke. Aber gibt es wegen des Neu-Erstellen eines Accounts keine andere Lösung, als einen root-Befehl? Jetzt ist es doch nicht so einfach, wie erhofft, den Mailserver durch ein Web-Skript zu administrieren. Gibt es auch Lösungen, die rein über die Datenbank gehen? Also einfach nen neues Tupel in der Datenbank einfügen ?

Mfg, — Tobias Dobberphul 2010/02/09 01:00

P.S.: Ich werde demnächst das Tutorial um Greylisting erweitern, wenns recht ist.


Hi Tobias,

also mir fallen da zwei Lösungen zu ein. Du brauchst ja auf jeden Fall ein Mail-Verzeichnis pro User:

1) Du erstellst „auf Vorrat“ eine Reihe von Mail-Verzeichnissen, die du Mail1, Mail2, …, Mailn nennst. In Tabelle users legst du jetzt noch ein Feld „maildir“ an. In dieses Feld trägst du für jeden User dann den Pfad zum Mailverzeichnis ein (bei einem neuen User nimmst du dann eins, das noch nicht benutzt wird). In den Dateien /etc/postfix/vms-mailboxes.cf und /etc/courier/authmysqlrc trägst du für das Mailbox-Feld „maildir“ ein. Sollte funktionieren, habs aber nicht getestet.

2) Du benutzt ein Skript, dass Mailboxen erstellt. Ich hab mir sowas auch gemacht:

#!/bin/bash

USERNAME=$1
DOMAIN=$2

cd /home/vmail/$2
maildirmake $1
maildirmake /home/vmail/$2/$1/.Junkmail
maildirmake /home/vmail/$2/$1/.Sent
maildirmake /home/vmail/$2/$1/.Trash
maildirmake /home/vmail/$2/$1/.Templates
chown -R vmail:vmail /home/vmail

Dieses Skript muss dann vom Web-Skript beim User-Anlegen aufgerufen werden. (php? → system() ). Wahrscheinlich läuft dein Webserver aber nicht unter dem Benutzer vmail und auch nicht mit Root-Rechten (sollte er auch nicht!). Dann hilft es, wenn du das Skript kompilierst und mit dem Setuid-Bit den User beim Ausführen immer auf vmail setzt (bei nicht kompilieren Skripten funktioniert das normalerweise nicht).

— Tim Rühenbeck 2010/02/12 14:54


Hi Tim,

informationstechnisch gesehen ist nur die zweite Lösung akzeptabel, vor allem, da es bei mir um einen mittelgroßen Mailserver mit bis zu 5000 Postfächern geht. Muss mich dann bloß darum kümmern, dass die Eingaben nicht zu Unsicherheiten im System führen. Ich hatte das so schon mal versucht, aber komme mit den Berechtigungen nicht klar. Der Webserver läuft ja unter www-data, hat also, Gott sei Dank, keine root-Rechte. Wie kann ich denn den User beim Ausführen auf root oder vmail legen?

Mfg, — Tobias Dobberphul 2010/02/22 12:01


Hi nochmal,

ich habe es jetzt ausprobiert über die Maildirs auf Vorrat. Ich habe es so gelöst, dass ein Script per cronjob nachschaut, ob noch Maildirs „frei“ sind. Wenn eine gewissen Anzahl überschritten ist, erstellt es neue auf Vorrat.

Dafür müssen die Dateien /etc/postfix/vms-mailboxes.cf und /etc/courier/authmysqlrc angepasst werden. Außerdem muss wie oben schon gesagt die Tabelle „users“ erweitert werden um die Spalte „maildir“. Außerdem muss für die Spalte „email“ auch „null“ erlaubt sein.

/etc/postfix/vms-mailboxes.cf den Eintrag beim select_field ändern auf:

select_field = CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',maildir,'/')

/etc/courier/authmysqlrc den Eintrag beim MYSQL_MAILDIR_FIELD ändern auf:

MYSQL_MAILDIR_FIELD     CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',maildir,'/')

Mfg, — Tobias Dobberphul 2010/06/10 11:48


Hi, irgendwie verstehe ich das Problem nicht ganz und vor allem ist mir das anlegen von Maildirs auf Vorrat etwas suspekt. Wenn ich es richtig lese, geht es darum das man für jeden neuen User per Console und maildirmake erstmal das Grundgerüst anlegen muss, da der Courier das nicht kann.

Soweit richtig, nur das Courier das nicht kann heißt nicht das man das nicht trotzdem vom Mailserver machen lassen kann. Mit Hilfe von Maildrop und meines Tipps bzgl. der Ordner die immer gerne gelöscht werden. Ich lege also neue User einaml in der DB an und schicke ihnen anschliessen eine „Willkommen“-eMail, die den Rest erledigt.

Hier mal der grobe Maildrop-Ablauf bei einer ankommenden Mail :

  • Systemcheck
    • Existiert das DOMAIN-Verzeichnis - wenn nicht mit mkdir angelegt
    • Existiert das Userverzeichnis sowie das Viren-Quarantäne/Backup/SPAM/SPAM-Lernverzeichnis - wenn nicht jeweils mit maildirmake anlegen
  • Mailcheck auf Viren, Spam, evtl. Backup
  • Userregeln
    • bei der abschliessenden Zuordnung wird auch hier kontrolliert ab dieser existiert und falls nicht mit maildirmake angelegt

Mfg, — Matthias Sennewald 2010/08/13 10:53

Danksagungen

Andreas Mayer, Mark Romen, Florian Stadler, Tim Rühenbeck, Andre

linux/virtueller_e-mail_server_unter_debian_etch_und_postfix.txt · Zuletzt geändert: 2011/05/22 13:04 von reiner_wir2.info
chimeric.de = chi`s home Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0