Postfix für SuSE Linux 11.x konfigurieren

Installation von MySQL und zusätzlich benötigter Software

Dokumentation ausstehend

Installation von Courier und Saslauthd

Dokumentation ausstehend

MySQL Passwörter einrichten

Dokumentation ausstehend

MySQL Datenbank für Postfix/Courier erstellen

Wir erstellen eine Datenbank mit der Bezeichnung mail:
mysqladmin -u root -p create mail

Als Nächstes begeben wir uns in die MySQL Kommandozeile:
mysql -u root -p

In der MySQL Kommandozeile erstellen wir den Benutzer mail_admin mit dem Passwort xxxxx, der SELECT,INSERT,UPDATE,DELETE Privilegien in der mail Datenbank hat. Mit diesem Benutzer werden sich Postfix und Courier mit der mail Datenbank in Verbindung setzen:
GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO 'mail_admin'@'localhost' IDENTIFIED BY 'xxxxx';
GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO 'mail_admin'@'localhost.localdomain' IDENTIFIED BY 'xxxxx';
FLUSH PRIVILEGES;

Immer noch in der MySQL Kommandozeile, erstellen wir die Tabellen, die Postfix und Courier benötigen:
USE mail;

CREATE TABLE domains (
domain varchar(50) NOT NULL,
PRIMARY KEY (domain) )
TYPE=MyISAM;

CREATE TABLE forwardings (
source varchar(80) NOT NULL,
destination TEXT NOT NULL,
PRIMARY KEY (source) )
TYPE=MyISAM;

CREATE TABLE users (
email varchar(80) NOT NULL,
password varchar(20) NOT NULL,
quota INT(10) DEFAULT '10485760',
PRIMARY KEY (email)
) TYPE=MyISAM;

CREATE TABLE transport (
domain varchar(128) NOT NULL default '',
transport varchar(128) NOT NULL default '',
UNIQUE KEY domain (domain)
) TYPE=MyISAM;

quit;

Die domains Tabelle speichert jede virtuelle Domain, für die Postfix E-Mails erhalten sollte (z.B. example.com).
domain
ccf-it.com


Die forwardings Tabelle ist für das Aliasing einer eMail Adresse zur anderen, z.B. eMails für an weiterleiten.
sourcedestination
info@example.comsales@example.com


Die users Tabelle speichert alle virtuellen Benutzer (d.h. eMail Adressen, da eMail Adresse und Benutzername identsich sind),
Passwörter (in verschlüsselter Form!) und einen Quota-Wert für jede eMail Box (in diesem Beispiel ist der Standardwert 10485760 Bytes, was 10MB bedeutet).
emailpasswordquota
service@ccf-it.comNo9.E4skNvGa. (”secret” in encrypted form)10485760


Die transport Tabelle ist optional, sie ist für fortgeschrittene Benutzer geeignet. Sie erlaubt Mails an einzelne Benutzer,
ganze Domains oder alle Mails an einen anderen Server weiterzuleiten. Zum Beispiel würde
domaintransport
ccf-it.comsmtp:1.2.3.4


alle eMails für ccf-it.com via smtp Protokoll an den Server mit der IP Adresse 1.2.3.4 weiterleiten (die eckigen Klammern [] bedeuten
“schlage den MX DNS Record nicht nach” (was für IP Adressen Sinn macht…).
Wenn Du stattdessen einen Fully Qualified Domain Name (FQDN) nutzt, verwendest Du die eckigen Klammern nicht.).

Konfiguration von Postfix

Nun müssen wir Postfix mitteilen, wo es alle Informationen in der Datenbank finden kann. Dafür müssen wir sechs Textdateien erstellen.
Du wirst feststellen, dass ich Postfix mitteile, sich mit MySQL auf der IP Adresse 127.0.0.1 anstatt sich mit localhost zu verbinden.
Postfix läuft in einem Chroot Gefängnis und hat keinen Zugriff auf den MySQL Socket welchen er versuchen würde zu verbinden,
wenn ich Postfix mitgeteilt hätte, localhost zu verwenden. Wenn ich 127.0.0.1 verwende, nutzt Postfix den TCP Netzwerkbetrieb
um sich mit MySQL zu verbinden, was auch im Chroot Gefängnis kein Problem darstellt.

Erstellen der sechs Textdateien.
vi /etc/postfix/mysql-virtual_domains.cf

user = mail_admin
password = xxxxx
dbname = mail
query = SELECT domain AS virtual FROM domains WHERE domain='%s'
hosts = 127.0.0.1

vi /etc/postfix/mysql-virtual_forwardings.cf

user = mail_admin
password = xxxxx
dbname = mail
query = SELECT destination FROM forwardings WHERE source='%s'
hosts = 127.0.0.1

vi /etc/postfix/mysql-virtual_mailboxes.cf

user = mail_admin
password = xxxxx
dbname = mail
query = SELECT CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/') FROM users WHERE email='%s'
hosts = 127.0.0.1

vi /etc/postfix/mysql-virtual_email2email.cf

user = mail_admin
password = xxxxx
dbname = mail
query = SELECT email FROM users WHERE email='%s'
hosts = 127.0.0.1

vi /etc/postfix/mysql-virtual_transports.cf

user = mail_admin
password = xxxxx
dbname = mail
query = SELECT transport FROM transport WHERE domain='%s'
hosts = 127.0.0.1

vi /etc/postfix/mysql-virtual_mailbox_limit_maps.cf

user = mail_admin
password = xxxxx
dbname = mail
query = SELECT quota FROM users WHERE email='%s'
hosts = 127.0.0.1

chmod o= /etc/postfix/mysql-virtual_*.cf
chgrp postfix /etc/postfix/mysql-virtual_*.cf

Nun erstellen wir einen Benutzer und eine Gruppe namens vmail mit dem Home Verzeichnis /home/vmail. Hier werden alle Mail Boxes gespeichert.
groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /home/vmail -m

Als Nächstes werden wir Postfix etwas konfigurieren.
postconf -e ‘myhostname = server1.example.com’
postconf -e ‘mydestination = server1.example.com, localhost, localhost.localdomain’
postconf -e ‘mynetworks = 127.0.0.0/8′
postconf -e ‘virtual_alias_domains =’
postconf -e ‘ virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, mysql:/etc/postfix/mysql-virtual_email2email.cf’
postconf -e ‘virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf’
postconf -e ‘virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf’
postconf -e ‘virtual_mailbox_base = /home/vmail’
postconf -e ‘virtual_uid_maps = static:5000′
postconf -e ‘virtual_gid_maps = static:5000′
postconf -e ’smtpd_sasl_auth_enable = yes’
postconf -e ‘broken_sasl_auth_clients = yes’
postconf -e ’smtpd_sasl_authenticated_header = yes’
postconf -e ’smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination’
postconf -e ’smtpd_use_tls = yes’
postconf -e ’smtpd_tls_cert_file = /etc/postfix/smtpd.cert’
postconf -e ’smtpd_tls_key_file = /etc/postfix/smtpd.key’
postconf -e ‘transport_maps = proxy:mysql:/etc/postfix/mysql-virtual_transports.cf’
postconf -e ‘virtual_create_maildirsize = yes’
postconf -e ‘virtual_mailbox_extended = yes’
postconf -e ‘virtual_mailbox_limit_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailbox_limit_maps.cf’
postconf -e ‘virtual_mailbox_limit_override = yes’
postconf -e ‘virtual_maildir_limit_message = “The user you are trying to reach is over quota.”‘
postconf -e ‘virtual_overquota_bounce = yes’
postconf -e ‘proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains
$relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks
$virtual_mailbox_limit_maps’
postconf -e ‘inet_interfaces = all’
postconf -e ‘alias_database = hash:/etc/postfix/aliases’
postconf -e ‘alias_maps = hash:/etc/postfix/aliases’
touch /etc/postfix/aliases
postmap /etc/postfix/aliases

Danach erstellen wir das SSL Zertifikat, das für TLS benötigt wird:
cd /etc/postfix
openssl req -new -outform PEM -out smtpd.cert -newkey rsa:2048 -nodes -keyout smtpd.key -keyform PEM -days 365 -x509

Generating a 2048 bit RSA private key
.+++
........................................................+++
writing new private key to 'smtpd.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:DE
State or Province Name (full name) [Some-State]:NRW
Locality Name (eg, city) []:Lichtenau
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Reinhold Flecke CCF
Organizational Unit Name (eg, section) []:Husen
Common Name (eg, YOUR name) []:Reinhold Flecke
Email Address []:rf@ccf-consulting.de

Ändere dann die Berechtigungen des smtpd.keys:
chmod o= /etc/postfix/smtpd.key

Konfiguration von Saslauthd

Bearbeite /etc/sasl2/smtpd.conf.
vi /etc/sasl2/smtpd.conf

So sollte das file aussehen:
# all parameters are documented into:
# /usr/share/doc/cyrus-sasl/options.html

# The mech_list parameters list the sasl mechanisms to use,
# default being all mechs found.
#mech_list:         plain login

# To authenticate using the separate saslauthd daemon, (e.g. for
# system or ldap users). Also see /etc/sysconfig/saslauthd.
#pwcheck_method:    saslauthd
#saslauthd_path:    /var/lib/sasl2/mux

# To authenticate against users stored in sasldb.
#pwcheck_method:    auxprop
#auxprop_plugin:    sasldb
#sasldb_path:       /var/lib/sasl2/sasl.db

pwcheck_method: authdaemond
log_level: 3
mech_list: PLAIN LOGIN
authdaemond_path:/var/lib/authdaemon/socket

Startup Links für Postfix erstellen und Postfix, saslauthd und courier-authdaemon starten:
chmod 755 /etc/authlib/authdaemonrc
chkconfig postfix on
/etc/init.d/courier-authdaemon start
/etc/init.d/postfix start
/etc/init.d/saslauthd start

Konfiguration von Courier

Nun müssen wir Courier mitteilen, dass es sich gegenüber unserer MySQL Datenbank authentifizieren soll.
Bearbeite zunächst /etc/courier/authdaemonrc
vi /etc/courier/authdaemonrc

und ändere den Wert von authmodulelist so dass es heißt:
[...]
authmodulelist="authmysql"
#authmodulelist="authpam authpwd authshadow"
[...]

Bearbeite dann /etc/courier/authmysqlrc. Es sollte ganz genau so aussehen (Achtung: vergewissere Dich, dass Du die korrekten Datenbank Angaben eingibst):
cp /etc/courier/authmysqlrc /etc/courier/authmysqlrc_orig
vi /etc/courier/authmysqlrc

MYSQL_SERVER localhost
MYSQL_USERNAME mail_admin
MYSQL_PASSWORD xxxxx
MYSQL_PORT 0
MYSQL_DATABASE mail
MYSQL_USER_TABLE users
MYSQL_CRYPT_PWFIELD password
#MYSQL_CLEAR_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
MYSQL_QUOTA_FIELD quota

Starte Courier neu:
/etc/init.d/courier-authdaemon restart
/etc/init.d/courier-imap restart
/etc/init.d/courier-pop restart

Wenn Du Folgendes ausführst
telnet localhost pop3

kannst Du sehen, ob Dein POP3 Server richtig funktioniert. Er sollte +OK Hello there. zurückgeben (tippe quit um wieder zur Linux Kommandozeile zu gelangen):
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
+OK Hello there.
quit
+OK Better luck next time.
Connection closed by foreign host.

Installation von Amavisd-new, ))SpamAssassinund?ClamAV((

Um amavisd-new, spamassassin und clamav zu installieren, führe folgenden Befehl aus:
yast -i amavisd.new spamassassin pax cabextract lha clamav klamav unzip bzip2 arj p7zip unarj

Nun müssen wir /etc/amavisd.conf bearbeiten.
vi /etc/amavisd.conf


Änderungen eintragen!!!
chkconfig clamd on
chkconfig freshclam on
freshclam
/etc/init.d/clamd start
/etc/init.d/amavis start
freshclam
/etc/init.d/freshclam start

Nun müssen wir Postfix so konfigurieren, dass es eingehende E-Mails durch amavisd-new leitet:
postconf -e 'content_filter = amavis:[127.0.0.1]:10024'
postconf -e 'receive_override_options = no_address_mappings'

Hänge danach folgende Zeilen /etc/postfix/master.cf an:
vi /etc/postfix/master.cf

[...]
amavis unix - - - - 2 smtp
        -o smtp_data_done_timeout=1200
        -o smtp_send_xforward_command=yes

127.0.0.1:10025 inet n - - - - smtpd
        -o content_filter=
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o smtpd_restriction_classes=
        -o smtpd_client_restrictions=
        -o smtpd_helo_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o mynetworks=127.0.0.0/8
        -o strict_rfc821_envelopes=yes
        -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
        -o smtpd_bind_address=127.0.0.1

und starte Postfix neu:
/etc/init.d/postfix restart

Installation von Razor, Pyzor und DCC und Konfiguration von SpamAssassin

Änderungen eintragen!!!

Du kannst Deine SpamAssassin Konfiguration überprüfen, indem Du Folgendes ausführst:
spamassassin -D --lint

Es dürften keine Fehler angezeigt werden.

Führe danach dies aus:
/etc/init.d/amavisd restart

Nun aktualisieren wir unsere SpamAssassin Rulesets wie folgt:
sa-update --nogpg

Wir erstellen einen Cron Job, so dass die Rulesets regelmäßig aktualisiert werden. Führe dies aus
crontab -e

um den Cron Job Editor zu öffnen. Erstelle den folgenden Cron Job:
35 2 * * * /usr/bin/sa-update --nogpg &> /dev/null

Damit werden die Rulesets jeden zweiten Tag um 2:35 Uhr aktualisiert.

Quota Überschreitungsmeldung

Wenn Du Meldungen bezüglich aller E-Mail Konten erhalten möchtest, die über Quota sind, dann führe Folgendes aus:
cd /usr/local/sbin/
wget http://puuhis.net/vhcs/quota.txt
mv quota.txt quota_notify
chmod 755 quota_notify

Öffne /usr/local/sbin/quota_notify und bearbeite die Variablen zu Beginn. Weiter unten in der Datei (gegen Ende) gibt es zwei Zeilen, denen Du ein % Zeichen anhängen solltest:
vi /usr/local/sbin/quota_notify

[...]
my $POSTFIX_CF = "/etc/postfix/main.cf";
my $MAILPROG = "/usr/sbin/sendmail -t";
my $WARNPERCENT = 80;
my @POSTMASTERS = ('service@ccf-consulting.de');
my $CONAME = 'Reinhold Flecke CCF';
my $COADDR = 'rf@ccf-consulting.de';
my $SUADDR = 'rf@ccf-consulting.de';
my $MAIL_REPORT = 1;
my $MAIL_WARNING = 1;
[...]
           print "Subject: WARNING: Your mailbox is $lusers{$luser}% full.n";
[...]
           print "Your mailbox: $luser is $lusers{$luser}% full.nn";
[...]

Führe dies aus
crontab -e

um einen Cron Job für dieses Skript zu erstellen:
0 0 * * * /usr/local/sbin/quota_notify &> /dev/null


Postfix testen

Um herauszufinden, ob Postfix für SMTP-AUTH und TLS bereit ist, führe Folgendes aus
telnet localhost 25

Nachdem Du die Verbindung zu Deinem Postfix Mail Server aufgebaut hast, tippe
ehlo localhost

Wenn Du die Zeile
250-STARTTLS
und
250-AUTH PLAIN LOGIN
siehst, ist alles in Ordnung.
telnet localhost 25

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 hetzner.ccf-consulting.net ESMTP Postfix
ehlo localhost
250-hetzner.ccf-consulting.net
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
quit
221 2.0.0 Bye
Connection closed by foreign host.

Die Datenbank füllen und testen

Um die Datenbank zu füllen, kannst Du die MySQL Kommandozeile verwenden:
mysql -u root -p

mysql> USE mail;

Du musst wenigstens Einträge in der Tabelle domains und users erstellen.

Domain Tabelle füllen

mysql> INSERT domains (domain) VALUES('ccf-consulting.net'); 
mysql> INSERT domains (domain) VALUES('ccf-it.net'); 
mysql> INSERT domains (domain) VALUES ('reinhold-flecke.com');
mysql> INSERT domains (domain) VALUES ('reinhold-flecke.de');
mysql> select * from domains;
+---------------------+
| domain              |
+---------------------+
| ccf-consulting.net  |
| ccf-it.de           |
| reinhold-flecke.com |
| reinhold-flecke.de  |
+---------------------+
4 rows in set (0.00 sec)

mysql>

User Tabelle füllen

in die user Tabelle die eMail user anlegen
mysql> INSERT users (email, password, quota) VALUES ('rf@ccf-it.de', ENCRYPT('XXXXX'), 10485760);

User Tabelle updaten

update des passwords von user passwords
mysql> UPDATE users set password=ENCRYPT('XXXXX') where email='rf@ccf-it.de';

Benutzer aus user Tabelle löschen

Benutzer aus der user Tabelle löschen.
mysql> delete from users where email='rf@ccf-it.de';


Forwarding Tabelle füllen

eMail Adresse von nach umleiten.
mysql>INSERT forwardings (source, destination) VALUES ('rf@ccf-it.de', 'reinhold.flecke@ccf-it.de');

Die forwardings Tabelle könnte folgende Einträge haben:
source destination Beschreibung
info@example.com sales@example.com Redirects emails for to
@example.com thomas@example.com Creates a Catch All account for . All emails to example.com will arrive at , except those that exist in the users table (i.e., if exists in the users table, mails to will still arrive at ).
@example.com @otherdomain.de This redirects all emails to example.com to the same user at otherdomain.de. E.g., emails to will be forwarded to .
info@example.com sales@example.com
billing@otherdomain.de
Forward emails for to two or more email addresses. All listed email addresses under destination receive a copy of the email.


Transport Tabelle füllen

Die transport Tabelle könnte folgende Einträge haben:
domain transport Beschreibung
example.com : Delivers emails for example.com locally. This is as if this record would not exist in this table at all.
example.com smtp:mail.otherdomain.de Delivers all emails for example.com via smtp to the server mail.otherdomain.com.
example.com smtp:mail.otherdomain.de:2025 Delivers all emails for example.com via smtp to the server mail.otherdomain.com, but on port 2025, not 25 which is the default port for smtp.
example.com smtp:[1.2.3.4]
smtp:[1.2.3.4]:2025
smtp:[mail.otherdomain.de]
The square brackets prevent Postfix from doing lookups of the MX DNS record for the address in square brackets. Makes sense for IP addresses.
.example.com smtp:mail.otherdomain.de Mail for any subdomain of example.com is delivered to mail.otherdomain.de.
* smtp:mail.otherdomain.de All emails are delivered to mail.otherdomain.de.
joe@example.com smtp:mail.otherdomain.de Emails for are delivered to mail.otherdomain.de.


Um mehr zu erfahren, siehe auch:
man transport


Bitte immer daran denken, dass die Reihenfolge der Einträge in der transport Tabelle wichtig ist! Die Einträge schließen sich von oben nach unten an.
Wichtig: Postfix verwendet einen Caching Mechanism für den Transport, daher kann es eine Weile dauern, bis Deine Änderungen in der transport Tabelle übernommen werden. Wenn Du möchtest, dass sie sofort übernommen werden, lass Folgendes laufen
postfix reload

nachdem Du die Änderungen in der transport Tablle vorgenommen hast.








Das Originaldokument ist zu finden unter http://ccf-it.de/tiki-5.0/tiki-index.php?page=Postfix_SuSE11