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:
1 2 3 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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/
):
1 2 3 4 5 |
# 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.:
1 2 3 4 |
[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)
Jul 08, 2009 - 01: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
Jul 08, 2009 - 01: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
Feb 04, 2011 - 08:52 PM
You should update your installer script. If you are running with Postfix this may destroy the newaliases tool. Just relink it to the orig sendmail:
rm /usr/bin/newaliases; ln -s /usr/sbin/sendmail.orig /usr/bin/newaliases
This could avoid unusual side effects.
Cheers.
Nov 29, 2013 - 09:40 AM
Hi,
After the installation on my Server Debian 6.0.7 with Plesk 11.5.30 an Roundcube 0.8.6, Roundcube is not working anymore…
It pops up with an error: An error occured, sending of message failed..
Do you have a idea why.. or did anybody had the same problem..
thanks for help