MX-Backup mit ISPConfig unter Debian Buster einrichten

Betreibt man ein Mailserver mit ISPConfig 3, so kann es passieren, dass wegen Netzwerkstörungen oder anderer Störungen, mal der Haupt E-Mail Server nicht erreichbar ist. Doch was passiert den, wenn jemand eine E-Mail an die vom Server verwaltete Adresse schickt? Bei der Standard-Konfiguration vieler E-Mail Clients oder Server, wird die E-mail zu einem späteren zeitpunkt nochmals verschickt. Dies ist jedoch unsicher und sollte vom Server gehandhabt werden. In diesem Beitrag zeige ich euch, wie man mithilfe eines Postfix Relay Systems sicherstellen könnt, dass auch alle E-mails zum richtigen Empfänger gelangen, auch mal wenn der Haupt E-mail Server ausfällt. Realsieren, werden wir es mit Postfix.

Was wir brauchen

  • vServer oder ein dedicated Server mit mind. 500MB Ram -1 Kern – 500MB 15GB HDD/SSD

Los Geht`s

Wie wird es technisch realisiert?

Alle E-Mail Server werden anhand der DNS Einstellugnen(MX Resource) gefunden und dann zum richtigen Mail Server weiterverschickt. Diesen Trick nutzen wir, um ein Fail Over Szenario zu realisieren. Wir haben in der DNS Einstellung einer Domain zwei sog. MX-Resource Einträge. Der eine MX Eintrag ist jedoch höher Priorisiert, als der andere, sodass der E-Mail Client versucht den höhreren priorisierten MX Record aufzulösen. Dieser ist unser Primärer Server. Ist jedoch der Server nicht erreichbar wird der Client den Record nicht auflösen können. In diesem Fall wird der Client den zweiten Eintrag des MX Eintrags auflösen. In unserem Fall ist dies der Sekundäre E-Mail Server. Dieser wird die E-Mail annehmen und solange zwischenspeichern, bis der Master Server wieder erreichbar ist. Ist dies der Fall werden alle zwischengespeicherten E-Mails zum Masterserver weiterverschickt. Die Dauer und die Länge der Nachrichten können wir dabei selber bestimmen.

Mehr Infos über MX Einträge -> https://de.wikipedia.org/wiki/MX_Resource_Record

DNS Einstellungen tätigen

Um ein Master/Slave System aufzusetzen, ist es nun wichtig, DNS Einstellungen für die jweiligen Domains zu tätigen. Wir fügen ein 2. MX Record Eintrag mit einer höheren Priorität ein als der 1. MX Eintrag. Dies könnte in etwa so aussehen:

example.com. 86400 IN MX 10 mail1.example.com.
example.com. 86400 IN MX 20 mail2.example.com.

Hierzu fehlen noch die A-Records:

mail2. 86400 IN A X.X.X.X
mail1. 86400 IN A X.X.X.X

X.X.X.X stehen für die jeweiligen IP Adressen der Servers. Bitte beachtet, dass es bis zu 24h dauern kann, bis die DNS Einstellungen auch in allen Browserns in kraft treten.

Wir können nun die DNS Einstellungen mit dig(domain information groper) testen:

dig <example-domain> MX

Die Ausgabe könnte so aussehen:

; <<>> DiG 9.7.3 <<>> <example-domain> MX
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23556
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;<example-domain>.      IN      MX

;; ANSWER SECTION:
<example-domain>. 86400 IN      MX      20 mail2.<example-domain>.
<example-domain>. 86400 IN      MX      10 mail1.<example-domain>.
...

Ist nun unser primärer Server mail1.example.com nicht zu erreichen, werden alle E-Mails an unser sekundärer Server mail2.example.com weitergeleitet.

MySQL Master / Slave System aufsetzen

Da wir ISPConfig benutzen, um E-Mail Konten zu verwalten, werden wir ein einfache Replikation der Datenbank benutzen, um auch auf dem Sekundären Server alle E-Mail Konten zu haben. Doch warum brauchen wir den die E-Mail Daten auf dem Sekundären Server? Nun, aus sicherheitsgründen. Denn wenn E-Mails zum Sekundären Server ankommen, möchten wir gerne überprüfen, ob der Server auch den Empfänger als E-Mail Konto kennt. Solch eine Prüfung sollte auch vom Sekundären Server gemacht werden, da sonst die Gefahr besteht, dass der Primäre Server zu viele Spam E-Mails bekommt. Auch muss dann später der Primäre Server weniger prüfen. Um eine Replikation einer MariaDB/MySQL Datenbank zu realisieren, installieren wir auf dem Sekundären Server eine MariaDB. Dies machen wir mit der Paketverwaltung APT.

apt install mariadb-server mariadb-client

Danach das übliche…

 	
mysql_secure_installation

Wir setzen ein Root Passwort, löschen anonyme Benutzer, erlauben remote Zugriffe und löschen alle anderen Daten. Nun testen wir die Verbindung zum Master/Haupt Server.

ping -c2 <Maste IP Adresse>
#ggf. mit telnet port prüfen
telnet <Maste IP Adresse> 3306

Sollte auf dem Master Server schon Daten/Tabellen befinden, dumpen wir sie und importieren sie auf dem Slave/Backup Server.

mysqldump --user=root --password="<password>" --all-databases > dump.sql
scp dump.sql <benutzername>@<Slave-ip>:/root

Auf dem Slave Server:

mysql -u <user> -p<passwort> < dump.sql

Fertig. Nun richten wir die Replikation auf dem Master Server ein.

Master konfigurieren

Wir bearbeiten die Master Konfiguration vom MySQL Server. und fügen/veränderung folgende Werte.

	
nano /etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
bind-address  = 0.0.0.0
server-id = 1
log_bin = 1

log_bin = /var/log/mysql/mysql-bin.log
log_bin_index  = /var/log/mysql/mariadb-bin.index
binlog_format  = mixed
  • 0.0.0.0 = Dies bedeutet, dass alle IP Verbindungen erlaubt wären. Hier kann auch nur die Slave IP stehen.
  • server-id =1 Server ID. Der Master sollte immer die 1 bekommen

Nun starten wir den MySQl Server neu:

systemctl restart mysql

Danach loggen wir uns in die MySQL Datenbank des Masters als root User an und erstellen ein Slave User:

mysql -u root -p
grant replication slave on *.* TO <Benutzername>@'<ip-slave>' identified by '<Starkes-Passwort>';
FLUSH PRIVILEGES;

In der MySQL Konsole schauen wir uns den Status des Masters an:

SHOW MASTER STATUS;

Wir merken uns die Position(position) und die Datei(file). Diese werden wir später brauchen.

Slave konfigurieren

Auf dem Slave/Sekundären Server machen wir nun folgendes:

  • Wir bearbeiten auch hier die 50-server.conf
  • Starten die Replikation

nano /etc/mysql/mariadb.conf.d/50-server.cnf

und fügen/verändern:

server-id = 2
bind-address  = 0.0.0.0
log_bin = /var/log/mysql/mysql-bin.log
  • 0.0.0.0 = Hier kann auch die IP Adresse des Primären/Master Server eingetragen werden.
  • server-id = 2 Der Sekundäre Server bekommt die ID 2

Wir restarten nun den MySQL Server auf dem Slave und loggen uns in die Konsole ein:

systemctl restart mysql
mysql -u root -p

In der MySQL Konsole binden wir den Slave an und starten die Replikation:

CHANGE MASTER TO MASTER_HOST='<IP des Masters>', MASTER_USER='<Slave user>', MASTER_PASSWORD='<Passwort>', MASTER_LOG_FILE='<gemerkte File>', MASTER_LOG_POS=<gemerkte Position>;
START SLAVE;

Nun schauen wir uns den Status an:

SHOW SLAVE STATUS\G

Sowohl Slave_IO_Running, als auch Slave_SQL_Running müssen auf Yes stehen. Sollte dies nicht der Fall sein, so wird keine Replikation gemacht. Hierzu bitte in der /var/log/mysql/error.log schauen und ggf. fixen. Bei mir hat es erst beim zweiten Versuch geklappt. Also nicht Ausfgeben 😉

Postfix installieren

Wir installieren den Postfix wie auf einem gewöhnlichen E-Mail Server. Das geht am besten mit der Paketverwaltung APT:

#Mailman setzen
echo <Mail MX Name> > /etc/mailname
#Postfix und eingie andere nützliche Tools/modules installieren
apt-get install postfix postfix-mysql postfix-policyd-spf-python

Postfix konfigurieren

So nun haben wir ein vollwertigen Postfix Server. Jedoch wird er aktuell weder E-Mail senden, noch E-Mails annehmen. Nun konfigurieren ihn so um, dass er zu einem Mail Slave/Relay Server fungiert. Er wird nur E-mails annehmen, die dem Postfix als Empfänger bekannt sind(Bekannte E-Mail Adressen , die in ISPConfig verwaltet werden). Auch werden wir eine kleine Filterung der E-Mails vornehmen.

Wir editieren nun die /etc/postfix/main.cf

Diese sollte so aussehen:

#Postfix MX backup
#Postfix version testet: v3.4.14
#See http://www.postfix.org/postconf.5.html for more information


#Whether or not to use the local biff service. 
#This service sends "new mail" notifications to users who 
#have requested new mail notification with the UNIX command "biff y".
biff = no

#Aliase
#warning: dict_nis_init: NIS domain name not set fix
#The alias databases that are used for local delivery.
alias_maps = hash:/etc/aliases

#Set Hostname for Postfix
#The internet hostname of this mail system. 
#The default is to use the fully-qualified domain name (FQDN).
myhostname = <Backup Mail Server Domain>

#Postfix Origdomain
#The domain name that locally-posted mail appears to come from, 
#and that locally posted mail is delivered to.
myorigin = /etc/mailname

#The list of domains that are delivered via the $local_transport mail delivery transport. 
#local transport for internal users
mydestination = $myhostname, localhost

#The list of "trusted" remote SMTP clients that have more privileges than "strangers". 
#In particular, "trusted" SMTP clients are allowed to relay mail through Postfix. 
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128

#The text that follows the 220 status code in the SMTP greeting banner. 
#Some people like to see the mail version advertised. 
#By default, Postfix shows no version.
smtpd_banner = $myhostname MX Backup ESMTP $mail_name (Debian/GNU)

#Optional restrictions that the Postfix SMTP server applies in the context of 
#a client RCPT TO command, after smtpd_relay_restrictions. 
smtpd_recipient_restrictions =
        permit_sasl_authenticated
	permit_mynetworks        
	reject_non_fqdn_sender
        reject_non_fqdn_recipient
        reject_unauth_destination
        reject_invalid_helo_hostname
        reject_non_fqdn_helo_hostname
        reject_unknown_client_hostname
        reject_unauth_pipelining
        reject_unknown_sender_domain
        reject_rbl_client bl.spamcop.net
        reject_rbl_client sbl-xbl.spamhaus.org
        reject_rbl_client ix.dns1.manitu.net
        reject_rhsbl_client bl.spamcop.net
        reject_rhsbl_client sbl-xbl.spamhaus.org
        reject_rhsbl_client ix.dns1.manitu.net
        permit_mx_backup
#What destination domains (and subdomains thereof) this system will relay mail to.     
#Check Destination per MySQL/IspConfig DB
relay_domains = mysql:/etc/postfix/mysql-virtual_domains.cf

#Optional lookup tables with all valid addresses in the domains that match $relay_domains.
relay_recipient_maps = 
        mysql:/etc/postfix/mysql-virtual_mailboxes.cf
        mysql:/etc/postfix/mysql-virtual_forwardings.cf
        mysql:/etc/postfix/mysql-virtual_email2email.cf

#The set of characters that can separate a user name from its extension (example: user+foo), 
#or a .forward file name from its extension (example: .forward+foo). 
recipient_delimiter = +

#The list of error classes that are reported to the postmaster. The default is to report only 
#the most serious problems. 
#bounce = Send the postmaster copies of the headers of bounced mail, and send transcripts of SMTP sessions when Postfix rejects mail. 
#2bounce = Send undeliverable bounced mail to the postmaster. 
#data = Send the postmaster a transcript of the SMTP session with an error because a critical data file was unavailable.
#delay = Send the postmaster copies of the headers of delayed mail. 
#policy = Send the postmaster a transcript of the SMTP session when a client request was rejected because of (UCE) policy.
#protocol = Send the postmaster a transcript of the SMTP session in case of client or server protocol errors. 
#resource = Inform the postmaster of mail not delivered due to resource problems. 
#software = Inform the postmaster of mail not delivered due to software problems. 
notify_classes = delay, resource, software

#The maximal time between attempts to deliver a deferred message. 
maximal_backoff_time = 10m

#The minimal time between attempts to deliver a deferred message
minimal_backoff_time = 1m

#The time between deferred queue scans by the queue manager
queue_run_delay = 60s

#Consider a message as undeliverable, when delivery fails with a temporary error, 
#and the time in the queue has reached the maximal_queue_lifetime limit. 
maximal_queue_lifetime = 4w

Nun brauchen wir noch die MySQL Konfigurationen vom Master. Wir kopieren uns diese vom Primären Server und fügen diese auf dem Sekundären Server unter /etc/postfix/ hinzu.

  • mysql-virtual_domains.cf
  • mysql-virtual_mailboxes.cf
  • mysql-virtual_forwardings.cf
  • mysql-virtual_email2email.cf

Wir überprüfen nun die im Inhalt der CF befindlichen MySQL Anmeldedaten und loggen uns testweise mit den Daten auf die Datenbank an.

Sollte es nicht gehen. Erstellen wir auf dem Slave ein lokalen Benutzer, der die IspConfig Datenbank lesen kann.

mysql -u root -p
CREATE USER 'mxuser'@'localhost' IDENTIFIED BY '<PASSWORD>';
GRANT SELECT ON dbispconfig.* TO 'mxuser'@'localhost';
FLUSH PRIVILEGES;

Danach passen wir die *.cfs an.

Nun haben wir es fast geschafft. Mit

postconf -n
#und
postfix check

überprüfen wir nun alle Konfigurationen und Starten postfix neu:

#Restart des Servers
systemctl restart postfix
#Status prüfen
systemctl status postfix

Sollten keine Fehler auftauchen haben wirs schon Geschafft.

Testen

Wir schalten manuell den Primären Mail Server aus und schicken an eine E-mail Adresse, die von ISPCOnfig verwaltet wird, eine Test E-Mail. Wenn man auf dem Versendeten Server in die Logs schauen kann, wird man folgendes sehen:

Sep  7 13:06:05 mail2 postfix/smtpd[32448]: connect from smtp2-1.dca.wordpress.com[192.0.96.238]
Sep  7 13:06:06 mail2 postfix/smtpd[32448]: 15E8C12077C: client=smtp2-1.dca.wordpress.com[192.0.96.238]
Sep  7 13:06:06 mail2 postfix/cleanup[32455]: 15E8C12077C: message-id=<31759950.18731.0@wordpress.com>
Sep  7 13:06:06 mail2 postfix/qmgr[32013]: 15E8C12077C: from=<daniel=triopsi.com@b.wordpress.com>, size=22715, nrcpt=1 (queue active)
Sep  7 13:06:06 mail2 postfix/smtpd[32448]: disconnect from smtp2-1.dca.wordpress.com[192.0.96.238] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
Sep  7 13:06:06 mail2 postfix/relay/smtp[32456]: connect to <Haupt-Mail-Server>[91.210.226.16]:25: Connection refused

Die E-mail wurde angenommen und versucht den Primären E-Mail Server zu erreichen. Diese ist jedoch nicht zu erreichen. Daraufhin wird die E-Mail an den Sekundären Server weitergeleitet und zwischengespeichert. Ist der Haupt E-Mail Server wieder erreichbar, so schickt der Sekundäre E-Mail Server alle zwischengespeicherten E-mails wieder zurück zum Primären E-Mail Server. Dies könnte in den Logs so aussehen:

Sep  7 13:15:46 mail2 postfix/qmgr[32013]: DCE8S7CE87R: from=<test@example.com>, size=22715, nrcpt=1 (queue active)
Sep  7 13:15:52 mail2 postfix/qmgr[32013]: 15E8C12077C: removed

In der E-Mail sieht man nun im Header, dass diese vom Mail Backup Server kam.

...
Delivered-To: user@example.com
Received: from localhost (localhost.localdomain [127.0.0.1])
	by <mailserver>(Postfix) with ESMTP id D373E2FDCB49
	for <mailuser>; Mon,  7 Sep 2020 15:15:52 +0200 (CEST)
X-Virus-Scanned: Debian amavisd-new at profoxi.de
Authentication-Results: profoxi.de (amavisd-new); dkim=pass (2048-bit key)
	header.d=...
Received: from <Haup E Mail Server> ([127.0.0.1])
	by localhost (<Haup E Mail Server> [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id yAyvGbOFkFzS for <mailuser>;
	Mon,  7 Sep 2020 15:15:52 +0200 (CEST)
Received: from <Mail backup Server> (unknown [X.X.X.X])
	by <Mail backup Server> (Postfix) with ESMTP id 58F512FDC5A4
	for <mailuser>; Mon,  7 Sep 2020 15:15:52 +0200 (CEST)
...

Das wars. 😀

Nun haben wir ein vollwertiges E-Mail Backup System erstellt.

Viel Spaß beim nachbauen 🙂

Wie hilfreich war dieser Beitrag?

Klicke auf die Sterne um zu bewerten!

Durchschnittliche Bewertung 0 / 5. Anzahl Bewertungen: 0

Bisher keine Bewertungen! Sei der Erste, der diesen Beitrag bewertet.

Triopsi
Triopsi

Hi, mein Name ist Daniel R. Baumann. Ich bin seit 2007 Webseitenentwickler und entwickle bzw. administriere verschiedene Webprojekte. Ich berichte hier alle wichtigen News, Tipps und Tricks rund um das Thema IT.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.