It happens sometimes, a server you are responsible for seems to be sending out spammy emails, and its normally caused by legacy or insecure code. The mail log indicates there are plenty of potential spam messages going out that are originating locally but most Linux servers host a lot of sites. So the question then becomes, how do I find the script thats responsible for sending all of the emails?
The mail.log directive
One useful tool when tracing the origin of an email is the mail.log parameter which is available in PHP installs running version 5.3.0 and above. This parameter is simply set to the location of a log file and all calls to the PHP mail() function will be recorded. Including the originating script, line number, the destination address and the email headers used.
Getting it working
From the command line as root (NOTE: The examples below are based around a Debian server so the location and layout of your configuration files may vary with other distributions ) first create an empty log file for the calls to the PHP mail function to be logged to:
>/var/log/phpmail.log
NOTE: The mail log file needs to be writable by the PHP process. So in my case after creating the log file I then had to give ownership of the log to the www-data user to get it logging correctly.
Then create a global PHP mail config file containing the mail.log PHP directive:
echo “mail.log = /var/log/phpmail.log” > /etc/php5/conf.d/mail.ini
After making the change either restart Apache if PHP is running as an Apache module. Otherwise restart the PHP CGI process and then send an email from a PHP script on your server. Then use the cat command to output the contents of the PHP mail log file you just created:
cat /var/log/phpmail.log
Which should display you a record of your mail being sent and its particulars, something similar to:
mail() on [/var/www/testsite/www/wp-includes/class-phpmailer.php:769]: To: me@myemail.net — Headers: Date: Sun, 7 Jul 2013 03:39:42 +0000 Return-Path: test@testemail.net From: Jim Davis <test@testemail.net> Message-ID: <4b93ad6efbb68c59a33e5085647fdac1@testsite.com> X-Priority: 3 X-Mailer: PHPMailer 5.2.1 (http://code.google.com/a/apache-extras.org/p/phpmailer/) MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=”UTF-8″
The mail.add_x_header directive
A second way to gain some insight into the origin of emails being sent from PHP is the mail.add_x_header parameter. This adds a line to the header of the outbound emails, containing the UID of the web server or PHP process and the name of the script that sent the email i.e
X-PHP-Originating-Script: 33:mailer.php
To enable the feature place the mail.add_x_header directive or echo it into the global mail configuration created earlier when discussing the mail.log configuration option:
echo “mail.add_x_header = True” >> /etc/php5/conf.d/mail.ini
Then restart Apache or the PHP service for the change to take effect.
NOTE: This approach while useful for debugging emails being sent from a development or staging environment. This approach is not recommended for use in an production environment due to security considerations though. As it involves exposing information about your server and the scripts on it to potentially external parties. This feature also simply reports the script name without the path which also reduces its usefulness in environments hosting numerous sites.