msmtp ersetzt den Mail-Server
Bei einem gescheiterten Cron-Job oder einem Problem in der RAID-Konfiguration sollte eigentlich sofort eine Mail an den Admin gehen. Wenn auf dem Server ein Mailserver installiert ist, funktioniert das mehr oder weniger auf Anhieb: Sie müssen maximal einen Mail-Alias angeben oder die gewünschte Empfängeradresse in /etc/crontab eintragen.
Aber nicht jeder Server braucht auch einen Mail-Server! Dessen Administration verursacht selbst jede Menge Arbeit. Bei »kleinen« Servern ohne richtigen MTA (Mail Transfer Agent) ist msmtp eine gute Alternative. Das Programm übergibt die zu sendenden Nachrichten einfach an einen externen SMTP-Server.
Ich habe msmtp vor ein paar Tagen auf einem frisch installierten Virtualisierungs-Host (Ubuntu 26.04) eingerichtet. Dieser Beitrag fasst die Konfiguration zusammen.
Funktionsweise
msmtp ist kein Mail-Server. Das Programm nimmt keine Mails von außen entgegen, hat keine Warteschlange und kümmert sich auch nicht um die Zustellung an den Ziel-Server. Es macht nur eines: Es reicht eine Nachricht per SMTP an einen externen Mail-Server weiter, bei dem Sie ein Konto haben, z.B. bei Ihrem Mail-Provider (mailbox, Gmail etc.). Dieser Server erledigt dann den Rest.
Für Cron & Co. ist das ideal: Diese Programme rufen zum Mail-Versand traditionell /usr/sbin/sendmail auf. Das Paket msmtp-mta stellt genau dieses Kommando zur Verfügung (als Link auf msmtp). Damit funktioniert der Mail-Versand für alle Programme, die einen lokalen Mail-Server erwarten.
Der Preis für die Einfachheit: Ist der SMTP-Server gerade nicht erreichbar, scheitert der Versand, und die Mail ist verloren. Es gibt keinen zweiten Versuch eine Stunde später.
Installation
Unter Debian und Ubuntu installieren Sie drei Pakete:
apt install msmtp msmtp-mta bsd-mailx
msmtp ist das eigentliche Programm, msmtp-mta richtet /usr/sbin/sendmail ein, und bsd-mailx stellt das Kommando mail zur Verfügung, mit dem Sie im Terminal oder in Scripts unkompliziert Mails versenden können.
Während der Installation fragt ein Dialog, ob Sie das AppArmor-Profil für msmtp aktivieren möchten. Die Defaulteinstellung lautet Nein, und dabei habe ich es belassen. Wenn Sie AppArmor aktivieren, darf passwordeval (siehe unten) nur einige ausgewählte Hilfsprogramme aufrufen (cat, gpg, pass, secret-tool usw.). Details können Sie in /usr/share/doc/msmtp/README.Debian nachlesen.
Konfiguration
Die systemweite Konfiguration befindet sich in /etc/msmtprc. Meine Datei sieht (mit anonymisierten Adressen) so aus:
# Datei /etc/msmtprc
# Default-Werte für alle weiteren Accounts
defaults
auth on
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile /var/log/msmtp.log
aliases /etc/aliases
# erster Account
account myfirstaccount
host smtp.example.com
port 587
user admin@example.com
passwordeval "cat /etc/msmtp-password"
from server1@example.com
# optional: weitere Accounts
account myotheraccount
...
# welcher Account gilt per Default
account default : myfirstaccount
Der Abschnitt defaults enthält Einstellungen, die für alle Konten gelten: Authentifizierung, TLS (hier mit STARTTLS auf Port 587), die Datei mit den CA-Zertifikaten, eine Logging-Datei und die Alias-Datei. Darauf folgt die Definition des eigentlichen Kontos. Sie können mehrere Konten definieren, für einen Server reicht aber eines. account default : ... legt fest, welches Konto msmtp verwendet.
Zu einigen Details:
- user und from: Oft stimmen
user(zur Authentifizierung) undfrom(die Absenderadresse) überein. Auf jeden Fall muss Ihr Provider die Absenderadresse für das angegebene Konto akzeptieren. Einige Provider erlauben Aliasse. Ich verwende für jeden Server eine eigene Alias-Adresse. Auf diese Weise sehe ich im Posteingang sofort, woher eine Nachricht kommt. -
passwordeval: Das Passwort könnten Sie mit
passworddirekt inmsmtprcangeben. Ich habe es stattdessen in die Datei/etc/msmtp-passwordausgelagert.passwordevalführt das angegebene Kommando aus und verwendet dessen Ausgabe als Passwort. -
aliases:
msmtpwertet/etc/aliasesaus. Damit landen Mails an lokale Empfänger wierootbei einer »richtigen« Adresse (siehe unten).
Manche Provider bieten anstelle von (oder zusätzlich zu) STARTTLS auf Port 587 eine von Anfang an verschlüsselte Verbindung auf Port 465 an (SMTPS). Wichtig ist tls_starttls off, weil msmtp per Default STARTTLS verwendet:
# Datei /etc/msmtprc (Variante mit Port 465, nur die geänderten Zeilen)
defaults
tls_starttls off
...
account myfirstaccount
port 465
...
Welche Variante Sie wählen, ist letztlich egal, solange Ihr Provider sie unterstützt. Wenn Sie tls_starttls und port nicht zusammenpassend einstellen, hängt msmtp beim Verbindungsaufbau bzw. scheitert mit einer TLS-Fehlermeldung.
Die Passwortdatei darf nur root lesen:
touch /etc/msmtp-password
chmod 600 /etc/msmtp-password
nano /etc/msmtp-password # Passwort eintragen
Hinweis: Wenn Ihr Provider es anbietet, verwenden Sie anstelle des Passworts für Ihr Mail-Konto ein eigenes App-Passwort. Bei Gmail ist das zwingend erforderlich. Ein Server, der Status-Mails versendet, braucht keinen Zugriff auf Ihr gesamtes Konto.
Logging
Die Logging-Datei richtet msmtp beim ersten Versand selbst ein. Für jede Mail kommt eine Zeile hinzu:
Nov 05 14:07:01 host=smtp.example.com tls=on auth=on user=admin@example.com from=server1@example.com recipients=server1@example.com mailsize=452 smtpstatus=250 smtpmsg='250 2.0.0 Ok: queued as ...' exitcode=EX_OK
Die Datei wächst nur langsam. Eine Logrotate-Konfiguration richtet das Paket nicht ein. Wer Ordnung haben will, legt /etc/logrotate.d/msmtp selbst an:
# Datei /etc/logrotate.d/msmtp
/var/log/msmtp.log {
monthly
rotate 12
compress
missingok
notifempty
}
Eine Alternative zur eigenen msmtp-Logging-Datei ist das Journal: Ersetzen Sie in msmtprc die Zeile logfile ... durch syslog on (oder syslog LOG_MAIL, wenn die Einträge in die Mail-Kategorie gehören sollen). msmtp protokolliert dann jeden Versand mit dem Kennzeichen msmtp. Zum Lesen verwenden Sie journalctl -t msmtp (t wie tag). journalctl -u msmtp funktioniert dagegen nicht, weil msmtp kein systemd-Dienst ist, sondern bei jedem Versand neu gestartet wird.
journalctl -t msmtp -n 20 # die letzten 20 Einträge
journalctl -t msmtp -f # laufend verfolgen
Aliasse am Server und Cron
Viele Systemprogramme senden ihre Mails an root. Damit diese Mails nicht im Nirwana verschwinden, braucht es einen Eintrag in /etc/aliases:
# Datei /etc/aliases
root: server1@example.com
Anders als bei Postfix oder Exim ist hier kein newaliases erforderlich: msmtp liest die Datei bei jedem Aufruf. Wenn Sie alle lokalen Empfänger (also nicht nur root) umleiten möchten, hilft eine zusätzliche Zeile default: server1@example.com.
Für Cron-Jobs in /etc/crontab habe ich außerdem MAILTO eingestellt:
# Datei /etc/crontab
SHELL=/bin/sh
MAILTO=server1@example.com
...
Mit der obigen Alias-Datei ist MAILTO nicht notwendig. MAILTO erlaubt aber bei Bedarf eine von /etc/aliases abweichende Einstellung. Bei mir ist der Absender aller Server-Mails gleichzeitig auch der Empfänger. Damit landet alles, was der Server zu berichten hat, in einem Postfach.
Ausprobieren
Für einen ersten Test senden Sie eine Mail an eine externe Adresse und an root. Führen Sie die Kommandos als root aus (z.B. nach sudo -s), weil nur root die Passwortdatei lesen darf (siehe auch den letzten Abschnitt).
echo "Test 1" | mail -s "msmtp-Test" ich@example.com
echo "Test 2" | mail -s "msmtp-Test an root" root
Wenn etwas nicht klappt, hilft msmtp -v bzw. sendmail -v beim Debugging. tail /var/log/msmtp.log zeigt, was zuletzt passiert ist.
echo "Test 3" | sendmail -v ich@example.com
Um die Mails von Cron zu testen, habe ich vorübergehend einen Cron-Job eingerichtet, der jede Minute läuft und eine Ausgabe liefert (und den ich danach natürlich wieder gelöscht habe):
# Datei /etc/cron.d/mailtest
* * * * * root echo "Hallo von Cron"
Kommt die Cron-Mail nicht an, lohnt sich ein Blick ins Journal. msmtp selbst schreibt in der obigen Konfiguration nur in seine eigene Logging-Datei, Cron protokolliert aber jeden Job und meldet auch, wenn die Übergabe an sendmail scheitert:
journalctl -u cron --since "10 min ago"
... CRON[4711]: (root) CMD (echo "Hallo von Cron")
... CRON[4710]: (root) MAIL (mailed 15 bytes of output but got status 0x004e from MTA)
Die Statuszahl ist der Exit-Code von msmtp in hexadezimaler Schreibweise (siehe /usr/include/sysexits.h). 0x4e = 78 steht für EX_CONFIG, also für einen Fehler in der Konfiguration, 0x4b = 75 (EX_TEMPFAIL) für einen nicht erreichbaren Server. Die Meldung No MTA installed, discarding output bedeutet, dass /usr/sbin/sendmail fehlt, also msmtp-mta nicht installiert ist.
RAID, SMART und Updates
Mit dem funktionierenden sendmail-Ersatz können nun auch andere Dienste Mails versenden. Auf meinem Server waren mir drei Dinge wichtig: Warnungen über defekte RAID-Arrays, drohende Probleme mit den SSDs und Berichte über automatische Updates. Alle drei Dienste senden ihre Mails an root; dank /etc/aliases landen sie in meinem Postfach.
mdadm: Unter Ubuntu enthält /etc/mdadm/mdadm.conf bereits die Zeile MAILADDR root, und der Dienst mdmonitor läuft automatisch, sobald es ein Software-RAID gibt. Ich musste also nichts ändern. Mit dem folgenden Kommando erhalten Sie für jedes RAID-Array eine Testmail:
mdadm --monitor --scan --oneshot --test
smartd: Das Paket smartmontools ist unter Ubuntu Server nicht standardmäßig installiert. Nach apt install smartmontools überwacht smartd alle Datenträger. Die mitgelieferte Konfigurationsdatei /etc/smartd.conf sieht bereits Mails an root vor (Option -m root):
# Datei /etc/smartd.conf
DEVICESCAN -d removable -n standby -m root -M exec /usr/share/smartmontools/smartd-runner
Um eine Testmail auszulösen, habe ich eine temporäre Konfigurationsdatei mit der Option -M test verwendet und smartd einmalig damit ausgeführt:
echo "/dev/nvme0n1 -m root -M test" > /tmp/smartd-test.conf
smartd -q onecheck -c /tmp/smartd-test.conf
rm /tmp/smartd-test.conf
Regelmäßige Selbsttests der Datenträger führt smartd in dieser Konfiguration übrigens nicht durch. Dazu müssten Sie in smartd.conf die Option -s ergänzen (siehe man smartd.conf).
unattended-upgrades: Automatische Updates sind unter Ubuntu standardmäßig aktiv, aber ohne Mail-Benachrichtigung. Anstatt /etc/apt/apt.conf.d/50unattended-upgrades zu ändern, habe ich eine eigene kleine Datei eingerichtet:
# Datei /etc/apt/apt.conf.d/52unattended-upgrades-mail
Unattended-Upgrade::Mail "root";
Unattended-Upgrade::MailReport "on-change";
on-change bedeutet, dass nur dann eine Mail kommt, wenn tatsächlich Pakete aktualisiert wurden oder etwas schiefgegangen ist. Alternativen sind always (jeden Tag eine Mail) und only-on-error. Zum Testen habe ich vorübergehend always eingestellt und unattended-upgrade -v ausgeführt. Obwohl es nichts zu aktualisieren gab, kam ein Bericht per Mail. Danach habe ich die Einstellung wieder auf on-change zurückgesetzt.
Mail-Versand für gewöhnliche Benutzer
In der obigen Konfiguration kann nur root Mails versenden, weil nur root die Passwortdatei lesen darf. Ruft ein anderer Benutzer mail oder sendmail auf, scheitert msmtp beim Auslesen des Passworts. Für einen Server, auf dem ohnehin nur Systemdienste und Cron-Jobs von root Mails versenden, ist das genau richtig.
Soll doch einmal ein gewöhnlicher Benutzer Mails versenden, ist die einfachste Lösung eine eigene Konfigurationsdatei .msmtprc in seinem Home-Verzeichnis. Am schnellsten kopiert der Benutzer /etc/msmtprc (die Datei ist für alle lesbar) und ändert dann zwei Zeilen: Die Logging-Datei und die Passwortdatei müssen in seinem Home-Verzeichnis liegen.
cp /etc/msmtprc ~/.msmtprc
# Datei ~/.msmtprc (geänderte Zeilen)
logfile ~/.msmtp.log
passwordeval "cat ~/.msmtp-password"
Die Passwortdatei darf nur für den Benutzer selbst lesbar sein (chmod 600 ~/.msmtp-password). Wenn Sie das Passwort stattdessen mit password direkt in .msmtprc eintragen, gilt das für diese Datei; bei zu großzügigen Rechten verweigert msmtp den Dienst. Damit Cron-Mails dieses Benutzers nicht an seinen lokalen Account gehen, stellen Sie in seiner Crontab (crontab -e) außerdem MAILTO=... ein.
Fazit
msmtp ist in wenigen Minuten eingerichtet. Für Server, die keinen eigenen Mail-Server brauchen, ist das viel angenehmer als eine ganze Postfix-Installation, deren einziger Zweck darin besteht, wenige Status-Mails zu versenden.
Wenn Sie die fehlende Warteschlange stört, sind nullmailer oder dma (DragonFly Mail Agent) denkbare Alternativen: Beide Programme sind ähnlich minimalistisch, speichern Mails aber zwischen, wenn der SMTP-Server gerade nicht erreichbar ist.
