Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a unique situation. I have a shared Debian Lenny server with 100+ vhosts for various customers. Recently I've noticed a surge in postfix activity within my Munin graphs. There appears to be a PHP script within one of the many vhosts on the server being used to send out email blasts. For one thing I understand that Postfix doesn't come bundled with any settings to help throttle outgoing email. I looked around and it appears that postfix-policyd is a viable solution. Here is what I'd like to do.

  1. install software to help me identify which vhost in particular is sending out the most emails
  2. which php script in particular is being exploited
share|improve this question

You have couple of options, depending on your setup.

Limiting at web server if suphp or similar is used

If your PHP scripts are run through suphp or similar mechanism which runs the scripts with the privileges of the user owning the script (instead of Apache), you can limit the amount of e-mail this single account can send during some time interval. Throttling can be done with qpsmtpd; many years ago wrote a plugin in Perl which stored the account name to MySQL and then checked out how many mails this user had sent recently. If the threshold was exceeded, mail was stored to temporary quarantine, an alert was raised and the admin team could check what was going on.

Same thing can be done with Postfix-policyd, in theory at least -- would be very easy if PHP would send authenticated mail, but since it usually won't do that, you'll have to be more creative while creating the limitation rules.

Limiting at web server if mod_php is used

If PHP scripts are run with plain mod_php (so each and every script gets run as Apache user), spotting the guilty script and rate limiting mail sending gets more difficult. Again, this can be done with a clever use of qpsmtpd.

Recent versions of PHP include an option to include X-PHP-Script header in each e-mail. That header, as the name hints, contains the path to PHP script. You can use that path information together with qpsmtpd, and take only the user part of the URL into account and do the throttling that way.

If you are stuck to some ancient PHP version, you can still patch PHP mail function by yourself. I wrote a small patch below back in 2005, have not used it recently so I have no idea if it still works. Still, the idea should be clear: get the path name, append it to every mail.

--- ext/standard/mail.c 2004-01-09 03:35:58.000000000 +0200
+++ ext/standard/mail.c 2005-03-14 13:33:33.069826225 +0200
@@ -180,0 +181 @@
+   char *runningscript = zend_get_executed_filename(TSRMLS_C);
@@ -229,0 +231,6 @@
+       if (runningscript != NULL) {
+           fprintf(sendmail, "X-PHP-Script-Path: %s\n", runningscript);
+       }
+       else {
+           fprintf(sendmail, "X-PHP-Script-Path: Unknown\n");
+       }

Finding the problems at the SMTP server

Since you are using Postfix, pfqueue is your friend when it comes to inspecting the mail queue. If you see lots of similar spam messages in the mail queue, just fire up pfqueue and inspect the headers of single message with it. Most of the time that's enough for revealing you the spammer; headers might contain the domain information, X-PHP-script header or some other clue.

share|improve this answer
ty for the response. – SoMoSparky Sep 23 '11 at 17:27

I think the quickest solution may be to run: cd /root/of/www ; grep -R 'mail(' * This should show you all the files that have in them string 'mail('. mail() is the function which PHP uses to send mail, so you may be able to identify vhost and script in one go.

share|improve this answer
Nice tip, ty for that. I actually pinned the guilty script down by sniffing, going through the Apache access logs, and then identifying the most active vhosts. From there I opened up the access logs for each and searched for all of the "POST" entries that looked funny. From here I compiled a list and did a mini audit. There has got to be a better way. Does anyone have any experience with postfix-policyd. Got a good default config I could review? – SoMoSparky Sep 23 '11 at 6:02

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.