PHP mail() überwachen

Update: take a look here.

Es ist nicht ungewöhnlich, dass Shared-Hosting-Systeme irgendwann zum Spamversand mißbraucht werden. Ist ein schlampig programmiertes PHP-Script Schuld, ist dies aber nur relativ schwer zu Identifizieren. In den versendeten Mails bzw. in der Mail-Queue finden sich meist keine Hinweise darauf welches Script verantwortlich ist.


Unter Linux versendet PHP die Mails mittels /usr/sbin/sendmail. Das heißt aber nicht, dass zwangsläufig auch der sendmail-Server zum senden eingesetzt wird. Fast jeder Mailserver (so auch qmail) installiert dort einen Wrapper für das eigene Mail-Kommando.

Es muss also nur /usr/sbin/sendmail ausgetauscht werden um die Zugriffe zu loggen. Dazu wird zunächst das Original nach /usr/sbin/sendmail_original kopiert und das folgende Script als /usr/sbin/sendmail erzeugt:

#!/bin/sh
LOGFILE=/var/log/php_mail.log
 
if [ -n "$SCRIPT_FILENAME" ] ; then
        echo `date +"%D %T"` $REMOTE_ADDR $SCRIPT_FILENAME $HTTP_HOST >> $LOGFILE
else
        echo `date +"%D %T"` $PWD >> $LOGFILE
fi
 
/usr/sbin/sendmail_original $@ < /dev/stdin

Damit wird jetzt schon jeder Zugriff auf die mail() Funktion geloggt. Jedoch wird prinzipbedingt nur das aktuelle Verzeichnis (in welchem das sendende Script liegt) geloggt. Das Problem ist, dass das Log-Script nicht die Umgebungsvariablen vom Apache/CGI bekommt. Dafür gibt es einen Workaround:

Umgebungsvariablen hinzufügen

Der Trick besteht darin, bei jedem Aufruf eines PHP-Scripts ein weiteres Script vorher zu Includen, welches die Apache-Umgebungsvariablen in die PHP-Umgebung einfügt. Damit stehen sie dann auch dem Logging-Script zur Verfügung.

In der php.ini lässt sich über die Variable „auto_prepend_file“ eine beliebige PHP-Datei vor jedes Script einbinden. Folgendes Script fügt für die entsprechenden Variablen hinzu:

<?
putenv("QUERY_STRING=". $_SERVER['QUERY_STRING']);
putenv("HTTP_HOST=". $_SERVER['HTTP_HOST']);
putenv("SCRIPT_FILENAME=" . $_SERVER['SCRIPT_FILENAME']);
putenv("REMOTE_ADDR=" . $_SERVER['REMOTE_ADDR']);
?>

Achtung: Dieses Script wird im Kontext des jeweiligen Scriptes included und ausgeführt. Es greifen also Sicherheitseinstellungen von PHP (z.B. safe_mode oder open_basedir).

Schreibe einen Kommentar

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