Inhaltsverzeichnis

SRS - Sender Rewriting Scheme

SPF Logo Im Kapitel SPF - Sender Policy Framework sind wir bereits darauf eingegangen, dass mit unter Probleme bei Mailumleitungen und/oder WebFormularen auftauchen können. Mit SRS1) kann ein Mailserver die eMail-Adresse im Envelop umschreiben und anpassen.

Das nachfolgende Schaubild verdeutlicht, warum bei zu strenger Wahl des SPF-Records der Versand bei einer Weiterleitung (alias) fehlschlägt. Der empfangende Mailserver überprüft die Angaben HELO und MAIL FROM im Envelop der eMail. Hierzu frägt der Mailserver den SPF-Record des sendenden Systems ab und vergleicht die IP-Adresse/Namen des einliefernden Empfängers mit den legitimen Sendern des SMF-Records. Ist der einliefernde Mailserver berechtigt, kann mit der weiteren Annahme und Prüfung fortgefahren werden. Ist der einliefernde Mailserver aber nicht berechtigt, quittiert das System den Zustellversuch mit einem Fehler-(code) 550.

Mailversand einer eMail bei Weiterleitung (alias)Mailversand einer eMail bei Weiterleitung (alias)  Mail-Server mx1.example.org88.217.127.21  Mail-Server mx1.example.org88.217.127.21  Mail-Server mx01.nausch.org217.91.103.190  Mail-Server mx01.nausch.org217.91.103.190  Mail-Server mx1.piratenpartei-bayern.de88.198.212.215  Mail-Server mx1.piratenpartei-bayern.de88.198.212.215  DNS-Server vonnausch.org  DNS-Server vonnausch.org connect von mx1.example.org zu mx01.nausch.org eMail: From: n3rd@example.orgTo: pirat_django@piraten-it.guruDate: Tue, 18 Mar 2014 11:23:38 +0100 Subject: Termin Ahoi,kann leider nicht kommen! cul8rn3rd . 220 mx01.nausch.org ESMTP PostfixHELO mx1.example.org. 250 mx01.nausch.orgMAIL FROM:<n3rd@example.org>host -t TXT example.org Abfrage desSPF-Recordsvon example.org example.org descriptive text "v=spf1 ip4:88.217.127.21 mx -all" Nur der Mailserver mit derIP 88.217.217.21 ist berechtigteMails der Mail-Domainexample.org zu versenden! . 250 2.1.0 OkRCPT TO:<pirat_django@piraten-it.guru>. 250 2.1.0 OkÜbermittlung der Nachricht250 2.0.0 Ok: queued as 5957581 Beenden der Verbindung connect von mx01.nausch.org zu mx1.piratenpartei-bayern.de eMail: From: n3rd@example.orgTo: pirat_django@piraten-it.guruDate: Tue, 18 Mar 2014 11:23:38 +0100 Subject: Termin Ahoi,kann leider nicht kommen! cul8rn3rd . 220 mx1.piratenpartei-bayern.de ESMTP PostfixHELO mx01.nausch.org. 250 mx1.piratenpartei-bayern.deMAIL FROM:<n3rd@example.org>host -t TXT example.org Abfrage desSPF-Recordsvon example.org example.org descriptive text "v=spf1 ip4:88.217.127.21 mx -all" Nur der Mailserver mit derIP 88.217.217.21 ist berechtigteMails der Mail-Domainexample.org zu versenden!Die IP-Adresse 217.91.103.190 ist als Versender nicht berechtigt! . 550-5.7.1 SPF MAIL FROM check failed! Beenden der Verbindung  Bounce der Nachrichtzurück an denursprünglichen Absender! 

Da in dem fiktiven Beispiel der Mailserver mx01.nausch.org nicht berechtigt ist Nachrichten der Domain example.org zu verschicken, schlägt die Zustellung an das Zielsystemfehl und der Mailserver wird die zuvor angenommene eMail zurück an den Absender bouncen!

Damit die Nachricht nun beim eigentlichen Zielsystem ankommt, müssen wir dafür Sorge tragen, dass das relayende System, also unser Mailserver, beim MAIL FROM im Envelope unsere Domain als Absender setzt. Dann kann das eigentliche Zielsystem, unsere eMail annehmen, da wir für unseren Mailserver einen entsprechend gültigen SPF-Record vorweisen können. Für den Fall, dass die Nachricht aber vom Zielsystem nicht zugestellt werden kann, oder eben von diesem später gebounced werden könnte, müssen wir uns nun die Absender-Adresse des ursprünglichen Mailservers merken. Nur so haben wir die Möglichkeit, den ursprünglichen Absender über den Zustellfehlversuch zu informieren.

Und an dieser Stelle setzt nun Sender Rewriting Scheme (kurz SRS) an! Wird eine eMail weitergeleitet, so setzt der SRS-Deamon die Envelop-Adresse MAIL FROM nach folgendem Schema: SRS0+xxxx=yy=example.com=alice@yourdomain.org, den wird dann auch als Return-Path im Mailheader unserer eMail beim entsprechenden Zielsystem vorfinden.

Return-Path: <SRS0+bCEv=YT=web.de=honeypot_for_spam@nausch.org>

Sollte die eMail zu uns zurück-bouncen, so kann unser Mailserver mit den Angaben dann, den ursprünglichen Absender, in dem Beispiel also honeypot_for_spam@web.de rekonstruieren und den Bounce an den richtigen Absender zurück schicken. Damit nun der revers-SRS nicht als open-relay-Adresse missbraucht wrden kann, werden bei der Envelop-Adresse die beiden Feder xxx und yy eingesetzt, die zum einen eine kryptografische Signatur und einen Zeitstempel repräsentieren. Sollten bei einem Bounce diese Angaben nicht stimmen, wird die Annahme der Nachricht verweigert, also verworfen.

Installation

Für SRS setzen wir den Postfix SRS Deamon, kurz PostSRSd von Timo Röhling ein. PostSRSd nutzt dabei zwei TCP lookup tables. Details zu diesen TCP lookup Tabellen, finden sich in der zugehörigen manpage.

 # man 5 tcp_table
TCP_TABLE(5)                                                      TCP_TABLE(5)
 
NAME
       tcp_table - Postfix client/server table lookup protocol
 
SYNOPSIS
       postmap -q "string" tcp:host:port
 
       postmap -q - tcp:host:port <inputfile
 
DESCRIPTION
       The  Postfix  mail  system  uses optional tables for address rewriting or mail routing. These
       tables are usually in dbm or db format. Alternatively, table lookups can be directed to a TCP
       server.
 
       To  find  out  what types of lookup tables your Postfix system supports use the "postconf -m"
       command.
 
       To test lookup tables, use the "postmap -q" command as described in the SYNOPSIS above.
 
PROTOCOL DESCRIPTION
       The TCP map class implements a very simple protocol: the client  sends  a  request,  and  the
       server  sends  one reply. Requests and replies are sent as one line of ASCII text, terminated
       by the ASCII newline character. Request and reply parameters (see  below)  are  separated  by
       whitespace.
 
       Send and receive operations must complete in 100 seconds.
 
REQUEST FORMAT
       Each request specifies a command, a lookup key, and possibly a lookup result.
 
       get SPACE key NEWLINE
              Look up data under the specified key.
       put SPACE key SPACE value NEWLINE
              This request is currently not implemented.
 
REPLY FORMAT
       Each  reply  specifies a status code and text. Replies must be no longer than 4096 characters
       including the newline terminator.
 
       500 SPACE text NEWLINE
              In case of a lookup request, the requested data does not exist.  In case of an  update
              request, the request was rejected.  The text describes the nature of the problem.
 
       400 SPACE text NEWLINE
              This  indicates  an error condition. The text describes the nature of the problem. The
              client should retry the request later.
 
       200 SPACE text NEWLINE
              The request was successful. In the case of a lookup  request,  the  text  contains  an
              encoded version of the requested data.
 
ENCODING
       In  request  and  reply  parameters,  the  character %, each non-printing character, and each
       whitespace character must be replaced by %XX, where XX is the corresponding ASCII hexadecimal
       character value. The hexadecimal codes can be specified in any case (upper, lower, mixed).
 
       The Postfix client always encodes a request.  The server may omit the encoding as long as the
       reply is guaranteed to not contain the % or NEWLINE character.
 
SECURITY
       Do not use TCP lookup tables for security critical purposes.  The client-server connection is
       not protected and the server is not authenticated.
 
BUGS
       Only the lookup method is currently implemented.
 
       The client does not hang up when the connection is idle for a long time.
 
SEE ALSO
       postmap(1), Postfix lookup table manager
       regexp_table(5), format of regular expression tables
       pcre_table(5), format of PCRE tables
       cidr_table(5), format of CIDR tables
 
README FILES
       Use "postconf readme_directory" or "postconf html_directory" to locate this information.
       DATABASE_README, Postfix lookup table overview
 
LICENSE
       The Secure Mailer license must be distributed with this software.
 
AUTHOR(S)
       Wietse Venema
       IBM T.J. Watson Research
       P.O. Box 704
       Yorktown Heights, NY 10598, USA
 
                                                                  TCP_TABLE(5)

Ob der im Einsatz befindliche Postfix diese Tabellen unterstützt, können wir wie folgt abfragen.

 # postconf -d | grep mail_version && postconf -m
mail_version = 2.6.6
milter_macro_v = $mail_name $mail_version
btree
cidr
environ
hash
ldap
mysql
nis
pcre
proxy
regexp
static
unix

Postfix

Leider unterstützt der aus dem Base-Repository stammende Postfix in der Version 2.6.6 keine TCP Lookup Tabellen, so dass wir auf eine neuere Version ausweichen müssen.

Die Firma IMT-Systems GmbH stellt auf ihrem Download-Server aktuellere Postfix 2.10.0 RPM Pakete für CentOS 6 zur Verfügung.

Wir laden uns also die entsprechenden RPM-Pakete auf unseren Server, dazu wechslen wir aber erst in unser lokales Programmarchiv.

 # cd /usr/local/src/packages/

Dann holen wir uns die zwei Pakete via wget.

 # wget http://download.imt-systems.com/postfix/2.10/2.10.0/x86_64/postfix-2.10.0-1.el6.x86_64.rpm
 # wget http://download.imt-systems.com/postfix/2.10/2.10.0/x86_64/postfix-perl-scripts-2.10.0-1.el6.x86_64.rpm

Haben wir unseren Mailserver zuvor noch nicht installiert und konfiguriert, fahren wir erst mit der Erstinstallation aus dem Kapitel Installation eines sicheren Mailservers mit Postfix unter CentOS 6.x fort.

Bevor wir nun mit der Installation der beiden Pakete beginnen, stoppen wir ggf. unseren bereits laufenden Postfix-Mailserver.

  # service postfix stop
Shutting down postfix:                                     [  OK  ]

Haben wir noch keinen Postfix-Mailserver installiert, so tun wir das nun.

 # yum localinstall --nogpgcheck postfix-2.10.0-1.el6.x86_64.rpm postfix-perl-scripts-2.10.0-1.el6.x86_64.rpm

Haben wir bereits eine Installation und Konfiguration unseres Postfix-Mailservers vorzuweisen, updaten wir nun diese.

 # yum localupdate --nogpgcheck postfix-2.10.0-1.el6.x86_64.rpm postfix-perl-scripts-2.10.0-1.el6.x86_64.rpm

Mit dem Aufruf von postconf werden uns dann etwaige Konfigurationsparameter, die es in 2.6.6 gab aber im 2.10.0 nicht mehr angezeigt und wir können diese anpassen und überarbeiten. Passt alles, können wir nun unseren Postfix-Mailserver wieder starten.

 # service postfix start
Starting postfix:                                          [  OK  ]

Damit unser aktueller Postfix nicht bei einem Systemupdate ggf. überschrieben wird, excludieren wir diesen im alten Base-Repository.

 # vim /etc/yum.repos.d/CentOS-Base.repo
/etc/yum.repos.d/CentOS-Base.repo
...
[updates]
# Django : 2014-03-17
exclude=postfix*
 
...

Fragen wir nun erneut die Lookup Tabellen Unterstützungen ab, werden uns im Gegensatz zur Version 2.6.6 bei der 2.10.0 wesentlich mehr angeboten.

 # postconf -d | grep mail_version && postconf -m
mail_version = 2.10.0
protocol
milter_macro_v = $mail_name $mail_version
btree
cidr
environ
fail
hash
internal
ldap
memcache
mysql
nis
pcre
proxy
regexp
socketmap
static
tcp
texthash
unix

SRS-Deamon

Als laden wir uns das aktuelle RPM auf unseren Server.

 # cd /usr/local/src/packages
 # wget http://repository.nausch.org/public/x86_64/postsrsd-1.0.1-1.el6.x86_64.rpm

Dann installieren wir das Paket.

 # yum localinstall postsrsd-1.0.1-1.el6.x86_64.rpm

Altenativ können wir das Paket natürlich auch direkt von Djangos Repository aus installieren.

 # yum localinstall http://repository.nausch.org/public/x86_64/postsrsd-1.0.1-1.el6.x86_64.rpm

Ein Update des Paketes geht entsprechend der Installation.

 # yum localupdate http://repository.nausch.org/public/x86_64/postsrsd-1.0.1-1.el6.x86_64.rpm

Was uns das Paket alles mitbringt, zeigt uns wie immer der Aufruf von rpm -qil <paketname>.

 # rpm -qil postsrsd
Name        : postsrsd                     Relocations: (not relocatable)
Version     : 1.0.1                             Vendor: django
Release     : 1.el6                         Build Date: Fri 28 Mar 2014 11:08:53 AM CET
Install Date: Fri 28 Mar 2014 11:14:34 AM CET      Build Host: vml010039.intra.nausch.org
Group       : System Environment/Daemons    Source RPM: postsrsd-1.0.1-1.el6.src.rpm
Size        : 41781                            License: GPLV2+
Signature   : RSA/SHA1, Fri 28 Mar 2014 11:08:54 AM CET, Key ID 31b4758f7c65ab27
Packager    : Django <django@nausch.org>
URL         : https://github.com/roehling/postsrsd/archive/1.0.1.tar.gz
Summary     : PostSRSd provides the Sender Rewriting Scheme (SRS) via TCP-based lookup tables for Postfix.
Description :
PostSRSd provides the Sender Rewriting Scheme (SRS) via TCP-based
lookup tables for Postfix. SRS is needed if your mail server acts
as forwarder.
/etc/rc.d/init.d/postsrsd
/etc/sysconfig/postsrsd
/usr/sbin/postsrsd
/usr/share/doc/postsrsd-1.0.1
/usr/share/doc/postsrsd-1.0.1/README.md
/usr/share/doc/postsrsd-1.0.1/main.cf.ex
/var/lib/postsrsd

Konfiguration

SRS-Deamon

Die Konfiguration des postsrsd-Daemons gestaltet sich vergleichsweise einfach und erfolgt lediglich mit Hilfe Der Datei /etc/sysconfig/postsrsd. Mit unserem Editor der Wahl, z.B. vim bearbeiten wir diese Konfigurationsdatei.

 # vim /etc/sysconfig/postsrsd
/etc/sysconfig/postsrsd
# Default settings for postsrsd
 
# Local domain name. 
# Addresses are rewritten to originate from this domain. The default value 
# is taken from `postconf -h mydomain` and probably okay.
#
#SRS_DOMAIN=example.com
# Django : 2014-03-27
SRS_DOMAIN=nausch.org
 
# Exclude additional domains.
# You may list domains which shall not be subjected to address rewriting.
# If a domain name starts with a dot, it matches all subdomains, but not
# the domain itself. Separate multiple domains by space or comma.
#
#SRS_EXCLUDE_DOMAINS=.example.com,example.org
 
# Secret key to sign rewritten addresses.
# When postsrsd is installed for the first time, a random secret is generated
# and stored in /etc/postsrsd.secret. For most installations, that's just fine.
#
#SRS_SECRET=/etc/postsrsd.secret
# Django : 2014-03-27
SRS_SECRET=/etc/postsrsd.secret
 
# Local ports for TCP list.
# These ports are used to bind the TCP list for postfix. If you change
# these, you have to modify the postfix settings accordingly. The ports
# are bound to the loopback interface, and should never be exposed on
# the internet.
#
#SRS_FORWARD_PORT=10001
#SRS_REVERSE_PORT=10002
# Django : 2014-03-27
SRS_FORWARD_PORT=10001
SRS_REVERSE_PORT=10002
 
# Drop root privileges and run as another user after initialization. 
# This is highly recommended as postsrsd handles untrusted input.
#
RUN_AS=nobody

Postfix

In der Postfix-Konfigurationsdatei /etc/postfix/main.cf tragen wir nun noch die Erweiterungen für die TCP Lookup Tabellen nach.

/etc/postfix/main.cf
...
 
# Django : 2014-03-18
# Lookup-Tabelle zum Umschreibungen von Absender eMail-Adressen im SMTP-Envelop und im Header der eMail
sender_canonical_maps = btree:/etc/postfix/sender_canonical_maps, tcp:127.0.0.1:10001
#
# Definition welche Adressen umgeschrieben werden sollen
sender_canonical_classes = envelope_sender
#
# Lookup-Tabelle zum Umschreibungen von Empfänger eMail-Adressen im SMTP-Envelop und im Header der eMail
recipient_canonical_maps = btree:/etc/postfix/recipient_canonical_maps, tcp:127.0.0.1:10002
#
# Definition welche Adressen umgeschrieben werden sollen
recipient_canonical_classes = envelope_recipient
 
...

Programmstart

erster manueller Start des Daemon

Nun können wir das erste mal PostSRSd anstarten.

 # service postsrsd start
Starting Postfix Sender Rewriting Scheme Daemon:           [  OK  ]

In der Prozessliste finden wir mindestens einen neuen Prozess, der gestartet wurde:

 # ps aux | grep postsrsd
nobody    6170  0.0  0.0   6184   352 ?        S    11:20   0:00 /usr/sbin/postsrsd -4 -f10001 -r10002 -dnausch.org -s/etc/postsrsd.secret -unobody -p -c -X -D
nobody    7151  0.0  0.0   6188   316 ?        S    11:41   0:00 /usr/sbin/postsrsd -4 -f10001 -r10002 -dnausch.org -s/etc/postsrsd.secret -unobody -p -c -X -D
nobody    7300  0.0  0.0   6188   500 ?        S    11:44   0:00 /usr/sbin/postsrsd -4 -f10001 -r10002 -dnausch.org -s/etc/postsrsd.secret -unobody -p -c -X -D
nobody    7301  0.0  0.0   6188   316 ?        S    11:44   0:00 /usr/sbin/postsrsd -4 -f10001 -r10002 -dnausch.org -s/etc/postsrsd.secret -unobody -p -c -X -D

Mittels netstat können wir überpfüfen, ob die beiden Ports 10001 und 10002 geöffnet wurden.

 # netstat -tulpen | grep 1000
tcp        0      0 127.0.0.1:10001             0.0.0.0:*                   LISTEN      0          40632      5185/postsrsd       
tcp        0      0 127.0.0.1:10002             0.0.0.0:*                   LISTEN      0          40634      5185/postsrsd

Läuft unser Daemon kann mit Hilfe von lsof sehen wir nicht nur den geöffneten port, sondern auch die Verbindungen die dort anliegen.

 # lsof -i :10001
COMMAND   PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
postsrsd 6170  nobody    5u  IPv4 574244      0t0  TCP localhost:scp-config (LISTEN)
postsrsd 7151  nobody    5u  IPv4 574244      0t0  TCP localhost:scp-config (LISTEN)
cleanup  7299 postfix   22u  IPv4 583245      0t0  TCP localhost:43341->localhost:scp-config (ESTABLISHED)
postsrsd 7300  nobody    0u  IPv4 583246      0t0  TCP localhost:scp-config->localhost:43341 (ESTABLISHED)
postsrsd 7300  nobody    5u  IPv4 574244      0t0  TCP localhost:scp-config (LISTEN)
postsrsd 7301  nobody    5u  IPv4 574244      0t0  TCP localhost:scp-config (LISTEN)
 # lsof -i :10002
postsrsd 6170  nobody    6u  IPv4 574246      0t0  TCP localhost:documentum (LISTEN)
smtpd    7146 postfix   40u  IPv4 582010      0t0  TCP localhost:57592->localhost:documentum (ESTABLISHED)
postsrsd 7151  nobody    0u  IPv4 582011      0t0  TCP localhost:documentum->localhost:57592 (ESTABLISHED)
postsrsd 7151  nobody    6u  IPv4 574246      0t0  TCP localhost:documentum (LISTEN)
cleanup  7299 postfix   23u  IPv4 583248      0t0  TCP localhost:57652->localhost:documentum (ESTABLISHED)
postsrsd 7300  nobody    6u  IPv4 574246      0t0  TCP localhost:documentum (LISTEN)
postsrsd 7301  nobody    0u  IPv4 583249      0t0  TCP localhost:documentum->localhost:57652 (ESTABLISHED)
postsrsd 7301  nobody    6u  IPv4 574246      0t0  TCP localhost:documentum (LISTEN)

automatisches Starten des Dienste beim Systemstart

Damit der Deamon PostSRSd automatisch bei jedem Systemstart startet, denn ohne laufenden postsrsd verweigert nun unser postfix die Annahme der Nachrichten, kann die Einrichtung des Start-Scripte über folgenden Befehle erreicht werden:

 # chkconfig postsrsd on

Die Überprüfungung ob postsrsd wirklich bei jedem Systemstart automatisch mit gestartet werden, kann durch folgenden Befehle erreicht werden:

 # chkconfig --list | grep postsrsd
 postsrsd       	0:off	1:off	2:on	3:on	4:on	5:on	6:off

Wichtig sind jeweils die Schalter on bei den Runleveln - 2 3 4 5.

Umschreibungen / Logging

Im Maillog unseres Mailservers werden die Umschreibungen entsprechend dokumentiert.

 # less /var/log/maillog
Mar 18 21:01:59 vml000080 postsrsd[5806]: srs_forward: <honeypot_for_spam@web.de> rewritten as <SRS0+BaCI=YT=web.de=honeypot_for_spam@nausch.org>

Im Header zugestellten eMail beim Empfänger wird dies auch im Return-Pathhinterlegt.

Return-Path: <SRS0+BaCI=YT=web.de=honeypot_for_spam@nausch.org>

Bounced das Zielsystem die Nachricht, weil dieses z.B. die Nachricht wegen einer vollen Mailbox nicht zustellen kann, kann das relayende System nun problemlos den eigentlichen Absender informieren, da der PostSRSd die Zieladresse wieder ermitteln und umschreiben (srs_reverse) kann.

Mar 13 21:27:25 vml000080 postsrsd[6883]: srs_reverse: <SRS0+bCev=YT=web.de=honeypot_for_spam@nausch.org> rewritten as <honeypot_for_spam@web.de>
...
...
Mar 18 21:27:26 vml000080 postfix/smtp[6884]: 8413383: to=<honeypot_for_spam@web.de>, orig_to=<SRS0+bCev=YT=web.de=honeypot_for_spam@nausch.org>, relay=mx-ha03.web.de[213.165.67.104]:25, delay=0.75, delays=0.06/0/0.41/0.29, dsn=2.0.0, status=sent (250 Requested mail action okay, completed: id=0LtrOf-1X9H7q3CS5-011BDN)

Links

1)
Sender Rewriting Scheme