Extensive sendmail wrapper with sender throttling

In this tutorial I’d like to describe how to create an extensive sendmail wrapper for a web server to monitor all sent emails and throttle daily sent email volume by the senders original UID (user id). This is useful if you e.g. run PHP in CGI-mode with SuExec, that is: all customers run their scripts under their own UID. The wrapper described here is not just a PHP-only wrapper (as described in my Simple PHP mail wrapper tutorial) – it directly replaces /usr/sbin/sendmail so we are able track all sent email of the whole system.

requirements:

On a Debian/Ubuntu system, make sure you have the the following packages installed:

apt-get install libdbd-mysql-perl libdbi-perl libmailtools-perl

Now create the database sendmailwrapper and the one and only needed table throlltle in MySQL:

CREATE DATABASE IF NOT EXISTS sendmailwrapper;
GRANT ALL ON sendmailwrapper.* TO smwrapper@localhost IDENTIFIED BY 'yourPassword';
FLUSH PRIVILEGES;
 
USE sendmailwrapper;
 
CREATE TABLE `throttle` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `orig_uid` int(10) UNSIGNED NOT NULL DEFAULT '0',
  `count_max` mediumint(8) UNSIGNED NOT NULL DEFAULT '1000',
  `count_cur` mediumint(8) UNSIGNED NOT NULL DEFAULT '1',
  `last_request` datetime NOT NULL DEFAULT '1970-01-01 00:00:00',
  `reported` BOOL NOT NULL DEFAULT '0',
  UNIQUE KEY `orig_uid` (`orig_uid`),
  PRIMARY KEY (`id`)
) TYPE=InnoDB;

Let's now move the original /usr/sbin/sendmail and replace it with our wrapper script (download below and put it into e.g. /opt/sendmail-wrapper/). Make sure, we got a logfile where all web-users are allowed to write to and only root can read from:

if test ! -s /usr/sbin/sendmail.orig
then
    # create logfile
    mkdir /var/www/log
    chmod 777 /var/www/log
    touch /var/www/log/sendmail-wrapper.log
    chmod 622 /var/www/log/sendmail-wrapper.log
    # install wrapper script
    mv /usr/sbin/sendmail /usr/sbin/sendmail.orig
    ln -sf /opt/sendmail-wrapper/sendmail-wrapper.pl /usr/sbin/sendmail
    echo 'Installed sendmail-wrapper!'
fi

Install the following cronjobs for daily cleanup and reporting (download cleanup.pl and report.pl below and put them into /opt/sendmail-wrapper/):

# Sendmail-wrapper
05 5    * * *   root    /opt/sendmail-wrapper/cleanup.pl
01 *    * * *   root    /opt/sendmail-wrapper/report.pl

The script now throttles sent email to a limit of 1000/day and prints log output to /var/www/log/sendmail-wrapper.log, e.g.:

[Sat, 03 Jan 2009 14:58:15 +0100] 83.77.98.62 ran /test.php at www.onlime.ch (OK)
[Sat, 03 Jan 2009 14:58:21 +0100] 83.77.98.62 ran /send.php at www.iezzi.ch (OK)

This has been tested on a Debian Etch system running Perl 5.8.8 / MySQL 5.0.32 / exim4 (4.63). It works as well with Postfix but there are known problems with mailq and similar commands that pass parameters to /usr/sbin/sendmail.

Download needed wrapper files and don't forget to configure them properly (CONFIGURATION section):

4 Comments so far »

  1. Extensive sendmail wrapper with sender throttling | PHP-Blog.com said

    am January 3 2009 @ 9:47 pm

    [...] the rest here: Extensive sendmail wrapper with sender throttling Related ArticlesBookmarksTags Mail delivery failed: returning message to sender … com [...]

  2. Boris said

    am July 8 2009 @ 1:26 pm

    Hi,

    i have a Problem with it, if i install all described here, i start a mail.php

    and the wrapper starts to loop and try to send the message initiated from the php script till its maximum throttle count.

    So it looks like.
    If i have a look to top, i see that the scripts starts 100 sendmail processes, but dosnt send anything.

    If i disable logging, it starts only 1 process, but no message was sent.

    Can you help ?

    Best regards

    Boris

  3. Boris said

    am July 8 2009 @ 1:34 pm

    Problem fixed :-)
    have inside the script the path to sendmail directed to sendmail. Simply a Bad idea ;-) Pointed to sendmail.orig and now it runs. Thanks

    Boris

  4. PHPscript verstuurd spam - webhostingtalk.nl said

    am February 20 2010 @ 8:52 am

    [...] een tool die je kunt gebruiken zonder PHP opnieuw te installeren: http://www.iezzi.ch/archives/258 Je maakt hiermee een wrapper op sendmail die de mailtjes logt en vervolgens pas verstuurd. In de [...]

Comment RSS · TrackBack URI

Leave a comment

Name: (Required)

eMail: (Required)

Website:

Comment: