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:
- Perl
- Perl DBI (Perl Database Interface)
- MySQL
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):
- sendmail-wrapper.pl
- cleanup.pl
- report.pl
- sendmail-wrapper.sql (used for database setup)
























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 [...]
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
Boris said
am July 8 2009 @ 1:34 pm
Problem fixed
Pointed to sendmail.orig and now it runs. Thanks
have inside the script the path to sendmail directed to sendmail. Simply a Bad idea
Boris
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 [...]