Postfix send rate limit per user/domain

I needed to limit the number of emails sent by users through your Postfix server, and store message quota in RDMS systems (maybe you have multiple MX).

I tried policyd or other policy daemons for Postfix;  but they all miss support for SQL storage.

With this piece of code you can setup a send rate per users or sender domain on daily/weekly/monthly basis and store data in MySQL (PostgreSQL,…).

To work with mqdaemon you only need a mysql table described like this one:

CREATE TABLE  `emails` (
`email` VARCHAR(65) NOT NULL,
`messagequota` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`messagetally` INT(10) UNSIGNED NOT NULL DEFAULT '0',

and setup configuration parameters (db_table, db_wherecol, db_messagequota, etc) inside the Perl script.

You must insert all rows for the emails you have to enforce! The script is configured to use a simple UPDATE.

Modify the postfix data restriction class “smtpd_data_restrictions” like the following:

smtpd_data_restrictions = check_policy_service inet:$IP:$PORT

To print the cache content with update statistics for username into log file just send a SIGHUP to the process PID using “kill -HUP $pid” or invoke the script with printshm paramenter (perl ./ printshm).

To enforce per-domain quota set the search key ($s_key_type parameter) to “domain”.

Start the daemon with “# ./” and kill it with “# pkill”.

Take care of using a port higher than 1024 to run the script as non-root.

This daemon caches the quota in memory, so you don’t need to worry about I/O operations.

GIT repository

3 Replies to “Postfix send rate limit per user/domain”

    1. Of course u can! Just u have to do only few edits to the code, it’s pretty old and buggy. consider it a proof of concept. For my production envs i had to change many lines of code, starting from the threading model; this online version suffer of memory leaks.

      For now this daemon limits only outgoing mails, if u need to limit incoming it’s an easy change to do.

Leave a Reply

Your email address will not be published. Required fields are marked *