PHP mail(), sendmail und MSMTP
PHP mail()-Funktion & sendmail
Wenn Dein Webserver nicht gleichzeitig ein E-Mail-Server ist, scheitert der korrekte Mail-Versand via sendmail
. Das betrifft sowohl die häufig von Skripten verwendete PHP-Funktion mail()
, als auch die klassischen Mailutils, die z.B. auch vom cron
-Daemon für Benachrichtigungen verwendet werden.
Mit MSMTP besteht jedoch die Möglichkeit, E-Mails über einen externen Mail-Server zuzustellen.
Im folgenden zeige ich Dir, wie du MSMTP installierst und einrichtest, sowie den Mail-Versand via Mailutils und PHP konfigurierst.
Anmerkungen
- Die Server-Konfiguration in den folgenden Beispielen ist für Hosted Mailcow; sollte jedoch bei den meisten Mailservern funktionieren
- Im folgenden gehe ich von einem eigenen E-Mail-Postfach für den Server aus:
server@example.com
. Der Account kann außerdem den alternativen Absenderwebmaster@john-doe.example
nutzen.
MSMTP installieren
Debian/Ubuntu
sudo apt-get install msmtp msmtp-mta mailutils
ArchLinux
ArchLinux nutzt s-nail als mailx-Implementierung, d.h. das mailutils
-Paket enthält kein mailx
-Binary.
sudo pacman -S msmtp msmtp-mta mailutils s-nail
macOS
brew install msmtp msmtp-mta mailutils
Achtung
Alle via Homebrew installierten Pakete haben einen Prefix, vergleichbar mit /usr/local/
bei FreeBSD-Ports:
- Apple Silicon:
/opt/homebrew
- Intel:
/usr/local
Dieser muss bei den im folgenden genannten Pfaden immer voran gestellt werden, also z.B. /opt/homebrew/etc/mail.rc
statt /etc/mail.rc
auf einem Apple Silicon-Mac.
/etc/msmtprc
Die systemweite Konfiguration von MSMTP befindet sich in der Datei /etc/msmtprc
. Alternativ kann auch pro Benutzer eine ~/.msmtprc
genutzt werden, worauf wir hier jedoch verzichten werden.
Zunächst werden einige Default-Werte für alle Accounts festgelegt, und das Logging feinjustiert.
#
# /etc/msmtprc
#
#
# Defaults for all accounts
#
defaults
# Hosted Mailcow
host hosted.mailcow.de
port 587
tls on
tls_starttls on
auth on
# Syslog logging with facility LOG_MAIL instead of the default LOG_USER
syslog LOG_MAIL
# Logfile
#logfile /var/tmp/msmtp.log
Es folgen die Einstellungen für die Accounts. Hier wird der Account server@example.com
konfiguriert, sowie die alternative Absenderadresse webmaster@john-doe.example
mit dem selben Account:
#
# Account server[@example.com]
#
account server
from "example.com Server" <server@example.com>
user server@example.com
password asdf1234
# Alternate envelope-from address
account webmaster : server
from "john-doe.example Webmaster" <webmaster@john-doe.example>
Als Standard-Account wird webmaster@john-doe.example
genutzt; außerdem wird eine Mailalias-Datei angegeben, damit für Cronjobs und die Mailutils lokalen Benutzern Accounts zugeordnet werden:
# Set a default account
account default: webmaster
# Map local users to mail addresses (for crontab)
aliases /etc/msmtp_aliases
/etc/msmtp_aliases
Die Alias-Datei hat das gleiche Format wie /etc/aliases
, außer dass Benutzer nicht anderen Benutzern zugeordnet werden, sondern zu E-Mail-Adressen. Außerdem kann ein default
-Empfänger angegeben werden für alle nicht explizit erwähnten Nutzer.
# vim: set filetype=mailaliases:
#
# /etc/msmtp_aliases
#
root: hostmaster@example.com
john: mail@john-doe.example
# Default
default: hostmaster@example.com
/etc/mail.rc
Um die Mailutils zu verwenden, muss in der Datei /etc/mail.rc
das zu verwendende sendmail-Kommando festgelegt werden:
set sendmail="/usr/bin/msmtp -t"
Desweiteren bietet das Paket oben bereits mit installierte msmtp-mta eine Drop-In-Kompatiblität mit sendmail für alle Programme, die nicht auf die sendmail
-Option in der /etc/mail.rc
zugreifen. Wann immer möglich empfehle ich jedoch, MSMTP explizit als sendmail-Implementierung einzustellen, siehe dazu auch weiter unten die PHP-Konfiguration.
Mit Mailutils testen
Mit mailx
kannst Du nun den Versand von E-Mails an lokale Nutzer testen. Die Abfrage nach CC und Betreff wird mit <Enter> bestätigt, und am Ende der Mail beendet ein <Strg>+<D> die Eingabe und die Mail wird versendet:
$ mailx root
Cc:
Subject: mailx-Test via MSMTP
Hallo root!
Dies ist eine Testmail, die von mailx an MSMTP übergeben werden soll, um dann via
SMTP ausgeliefert zu werden.
--
mfg
John Doe
^D
php.ini
Da PHP nicht auf /etc/mail.rc
zugreift, muss das sendmail-Kommando auch in der php.ini
nochmal angegeben werden. Der Pfad dieser hängt meist von der Verwendeten Runtime und PHP-Version ab; bei PHP-FPM 8.2 unter Raspbian ist dies z.B. /etc/php/8.2/fpm/php.ini
.
[mail function]
; For Unix only. You may supply arguments as well (default: "sendmail -t -i").
; https://php.net/sendmail-path
#sendmail_path = "/usr/bin/msmtp -C /var/www/.msmtprc -t"; Per-user config
sendmail_path = "/usr/bin/msmtp -t" ; Global config
Jetzt testen wir den Versand mit einem kleinen PHP-Skript:
<?php
$email = Array(
"subject" => "PHP mail() via MSMTP",
"recipient" => "mail@john-doe.example",
"message" => "Hallo!\n\nDiese E-Mail wurde mit der PHP-mail()-Funktion via MSMTP zugestellt.\n\n-- \nmfg\nWebmaster",
);
mail($email["recipient"], $email["subject"], $email["message"]);
crontab
In crontab-Dateien kann eine Empfänger-Adresse für Benachrichtigungen angegeben werden. So kannst Du dann die Benachrichtigungsmails anhand des Empfängers von Deinem Mailfilter verarbeiten lassen:
# Beispiel-crontab-Datei
MAILTO=crontab@john-doe.com
# m h dom mon dow command
@reboot /usr/bin/env /usr/local/sbin/dns-update.sh
0 * * * * /usr/bin/env /usr/local/sbin/dns-update.sh