php-secure-sendmail

Script for limiting no. of sent mail from PHP per domain

What is it good for

Imagine you run webserver with many virtual domains. But some bad customer writes a PHP script to send thousands of email messages in a loop (maybe it's his intention, maybe only bug which makes the loop never-ending, but that doesn't make a difference for us). Or customer has badly written scripts with security bugs and some spammer exploits this to send a lot of spam through your server.

Features of php-secure-sendmail

Requirements

Installation

  1. Unpack php-secure-sendmail.zip to some common directory (/usr/local/ for example)
  2. Set permissions of php-secure-sendmail directory to 711 (so that apache user can't see list of files here)
  3. Set permissions of secure_sendmail.py to 755 (so that apache user can execute and also read it - a must for scripts to be run)
  4. Edit secure_sendmail_mod.py to return your database password (simple return "myPassword" is enough, but it is relatively easily read by bad customer)
  5. Run python secure_sendmail_mod.py as root - this will create compiled version secure_sendmail_mod.pyc which is harder to read
  6. Delete original secure_sendmail_mod.py (or move to location where apache can't read it)
  7. Set configuration parameters in secure_sendmail_conf.py (should be self-explanatory)
  8. For every virtualhost set this in the <Virtualhost> section of httpd.conf:
    php_admin_value sendmail_path "/usr/local/php-secure-sendmail/secure_sendmail.py www.this_domain.com user1@this_domain.com" (The second parameter is optional)
    So no php compilation is needed, nor any change of customer php scripts - using mail() function in php will run our script instead of system sendmail binary
  9. Before :) you set it for every virtualhost, test it on only one :)
    Test if mail sent using mail() function gets delivered OK, if it contains headers added by our script, if the mail details are logged to MySQL and also test limits (set to low value like 3 for testing and watch for return value of mail() and warning in error.log)
    For few days watch for exceeded limits and alter configuration if any of your domains needs higher limit - this is not for limiting normal usage, but detecting when usage is too high compared to normal, so limits must be set correctly)

Download

You can download it here - php-secure-sendmail.zip.

Sample output in error.log

[Sun Apr 16 06:28:36 2006] [secure-sendmail] domain www.domainX.net: exceeded limit for 1 minutes (10)
[Mon May  1 14:54:02 2006] [secure-sendmail] GC was run (probability: 0.001; 656 rows older than 168 hours deleted)