Kürzlich haben wir bei der Bearbeitung eines Kundenprojektes festgestellt, dass plötzlich von der Seite versendete Emails nicht mehr ankamen. Es gab keine Veränderungen an den PHP-Scripten. Warum also ging plötzlich die Mailzustellung von der Webseite aus nicht mehr? Was hatte der Mailserver damit zu tun? Und wie hilft man in einem solchen Fall rasch weiter?
Mails versenden ist heutzutage ja schon nichts Besonderes mehr. Eigentlich! Das merkt der eine oder andere spätestens an den Unmengen von Spam-Emails, die täglich im virtuellen Briefkasten landen. Aber natürlich gibt es auch viele nützliche Mails und gerade Firmenwebseiten sind natürlich darauf angewiesen, dass diese auch ordnungsgemäß ankommen. Sei es das Kontaktformular für allgemeine Anfragen oder ein Formular, mit dem sich Bewerber auf offene Stellen bewerben können. Gerade in Zeiten des Fachkräftemangels ist es essentiell, dass insbesondere diese Emails möglichst alle erst mal ankommen. Was aber, wenn die Emails nicht mehr ankommen? Wenn der Server nur noch eine Fehlermeldung ausgibt (hoffentlich)? Oder schlicht und ergreifend einfach nur in einem Postfach, dass täglich mehrere Emails erhält auf einmal gar keine einzige Email eintrifft? Dann ist vermutlich irgendwas am Server verändert oder gestört und sollte ganz dringend behoben werden!
Fehleranalyse (nicht nur Mailserver)
Wenn man sich eines solchen Problems nähert, braucht man zunächst eine Strategie, dem Problem als näher zu kommen. Da hier der Emailversand nicht mehr ging, gab es vor allem vier Möglichkeiten, woran das primär liegen könnte:
- Es hat sich vielleicht doch in irgendeinem Script etwas verändert – vielleicht durch das Update eines Scriptes, das man gar nicht selbst geschrieben hat aber entsprechend nutzt
- Eine Einstellung an der PHP-Version hat sich geändert (das kann über die PHP.INI passieren genauso wie ein – automatisches – Update der Version oder Updates auf abhängige Softwarepakete auf dem Server)
- Einstellungen im Mailserver haben sich geändert (Emailadresse wurde gelöscht, Einstellungen zur Emailadresse haben sich verändert etc.)
- Bedienfehler, der bisher nur noch nicht aufgetaucht war.
Der letzte Punkt ist meistens unwahrscheinlich. Warum sollte der Emailversand auch bei einer ganzen Reihe von Formularen auf einmal und plötzlich nicht mehr funktionieren?
Da auf Seiten der Programmierung auch erst mal nichts geändert worden war und i.d.R. kleinere Änderungen in der PHP-Version nicht gleich dazu führen, dass etwas Essentielles, wie z.B. der Emailversand, gar nicht mehr funktionieren, ist auch diese Variante unwahrscheinlich.
Aber ein Blick in die entsprechenden PHP Dateien hilft hier trotzdem weiter: Man erfährt so immerhin relativ schnell, über welche Art und Weise Emails versendet werden. Das kann beispielsweise über die PHP-eigene Funktion mail() passieren. Das ist oftmals gerade in relativ einfachen Projekten eine durchaus gute Lösung, wenn die versendeten Emails nicht besonders aufwändig oder z.B. Anhänge realisiert werden sollen.
Hier war es in dem Fall genauso gelöst. Das hieß aber zugleich, das sich irgendwas wohl verändert haben musste, was die Funktionalität von mail() beeinflusste.
Wie die PHP-Funktion mail() arbeitet
Die Funktion an sich wird nur mit wenigen Parametern selbst im Script aufgerufen: Natürlich einem Empfänger, einem Betreff, ggf. zusätzlichen Headern (die man aber selbst als Zeichenkette zusammenbauen und übergeben muss) und dem „body“ der Email selbst. Kontrollmechanismen wie beispielsweise ob der Server eine Anmeldung mit Usernamen und Passwort benötigt kann dagegen nicht übergeben werden. In der Standardkonfiguration arbeitet mail() so, dass eine Anmeldung am Mailserver nicht stattfindet. Auf der anderen Seite bedeutet dies, dass der Mailserver so konfiguriert sein muss, dass ein Mailversand vom „localhost“ ohne Anmeldung möglich ist. Dies ist nicht der absolut beste Weg, aber solang man weiß was man tut und vor allem Zugriff auf den eigenen Mailserver und dessen Einstellungen hat, ist das umsetzbar.
Schwierig wird es, wenn der Mailserver – und das sollte er zur Sicherheit eigentlich immer – auch bei Nachrichten, die vom localhost her versendet werden, eine Authentifizierung verlangt. Das geht mit mail() auch – dazu muss man aber entsprechende Parameter in der php.ini setzen. Dies erfordert den Zugriff auf die php.ini direkt auf dem Server – also in der Regel einen root-Zugang zum Server.
Hat man dies alles nicht und der Provider stellt die Sicherheitsanforderungen des Mailservers hoch – geht auf einmal das Mailversenden nicht mehr. Man bekommt bestenfalls eine Fehlermeldung und geht auf Suche im entsprechenden Script. Da dies aber nicht geändert wurde, findet sich der Fehler einfach nicht an!
Auswertung der Mailserver – Logfiles
Spätestens wenn man also überhaupt keinen Ansatzpunkt im Script selbst findet, lohnt sich ein Blick in die Logfiles des Mailservers. Auf einigen (guten) Webspaces hat man auf diese auch Zugriff, wenn es kein eigener vServer oder Root-Server ist. Sonst hilft hier nur eine Anfrage beim Support des Providers. Das Logfile gibt in der Regel zumindest einen Ansatzpunkt, ob der Mailversand an sich erst mal sauber durchgelaufen ist. In diesem Fall lief der Mailversandprozess sauber an, endete aber mit einem Hinweis:
554 Transaction failed Reject due to policy restrictions.
Das klingt natürlich erst mal sehr kryptisch. Heißt aber im Klartext nicht viel Anderes, als dass die Mailservereinstellungen an sich und das, was mail() da gerad versucht, nicht zueinander passen. Nimmt man an, das Mailversenden hat bisher problemlos funktioniert, ist es naheliegend, dass der Provider (oder Systemadministrator) Änderungen vorgenommen hat. Diese Änderungen beeinflussen jetzt den Versand über die mail()-Funktion von PHP. Am wahrscheinlichsten wird nun auch für das Senden von localhost eine Authentifizierung benötigt.
Lösungsansatz
Wie bereits beschrieben, gibt es für mail() Einstellungen über die php.ini, die eine Authentifizierung auch für diese PHP-eigene Funktion ermöglichen. Dumm nur, wenn man eben nicht an die php.ini herankommt. Zwar besagt das Handbuch zu php, dass die Einstellungen auch über ini_set() gesetzt werden können – hat hier aber auch nicht funktioniert. Allerhöchstwahrscheinlich ist dies auch aus Sicherheitsgründen untersagt. An und für sich also eine gute Einstellung, aber leider nicht hilfreich zur Problemlösung!
Die zweite Option ist also, weg von der mail() Funktion zu gehen und mithilfe anderer Mail-Routinen eine entsprechende Authentifizierung zu ermöglichen. Generell habe ich als Entwickler bisher noch nie die mail() Funktion genutzt sondern nutze schon immer eigentlich das Paket phpmailer. Vorteil: Es stehen viele verschiedene Einstellungsmöglichen (HTML-Mails mit alternativem Body oder Dateianhänge) zur Verfügung. Die Einbindung ist problemlos möglich.
Es gab allerdings ein Problem: Natürlich stand die Emailversendung nicht losgelöst, sondern war nur der letzte Schritt, nachdem die Email als solches entsprechend vorbereitet war (insbesondere der Inhalt der Email). Wie also sollte hier am besten vorgegangen werden, um möglichst rasch und effizient das Mailen wieder zu ermöglichen und dabei auf die veränderten Umstände am Server und dem unveränderten Code in der jeweiligen Datei entgegen zu kommen?
Implementierung einer neuen Mailfunktionalität
Es gab eine Datei, die in allen Mailscripten gleichermaßen eingebunden ist.. Dort wurde dann eine neue Funktion hinterlegt, die soweit möglich dieselbe Aufrufstruktur wie mail() hatte, aber dann das eigentliche mailen über die phpmailer-Klasse abwickelte. Anschließend änderten wir noch in allen Mailscripten diese Aufrufe entsprechend ab. Alle Mailscripte wurden im Tagesverlauf ausgebessert. Die Auslösung und Zustellung der unterschiedlichen Mails über die jeweiligen Scripte funktioniert wieder.
Bewertung der Lösung
Mit Sicherheit ist die Lösung nicht absolut optimal. Man hätte hier auch gleich das Mailen an sich von Grund auf überarbeiten können. Es ist aber eine gelungene Mischung aus „es geht wieder und das relativ schnell“, „wenig Aufwand“ und dennoch zugleich insofern zukunftssicher, als das ein Mailserver immer das Versenden von Emails nach Authentifizierung zulassen wird. Der Mailversand funktioniert weiter. Auch wenn der Provider die Mailservereinstellungen nochmals optimiert/anpasst.
Was können wir für Sie tun?
Sie haben ähnliche Probleme mit Ihrer Mailfunktionalität? Oder möchten sich gern bereits rüsten, damit es im Zweifelsfall gar nicht erst zu einem Ausfall kommt? Nehmen Sie gern Kontakt auf und wir schauen gemeinsam, wie dies für Ihre Situation bestmöglich umgesetzt werden kann!
Excellent article, thank you. Dacey Ellerey Skeie
Você tem um fabuloso blog de graças. Karissa Edmund Halley
I able to find good information from this article. Laurel Berk Ansilma