We have a server CentOS server setup which hosts our websites and email server (using POSTFIX). We manage the system using Virtualmin and Webmin respectively.

In general for every site that we setup we provide the customer with an email account on our system. One customer in particular has decided it a good idea to send out literally thousands of email in bulk. When this happens the mail server will become unresponsive and mail for other customers will go down whilst the queue is processed.

Is there a way we can limit the rate of email is sent for one particular user of the system rather than everyone? Is there also a setting we should change so that nothing a user can do can cause the mail server to start failing for other users?



Postfix-Policyd is a great help for that among other things.


It strikes me that all other answers to this old question are link-only. So I am going to describe in few words how to implement my favorite solution for this job.

The link that @84104 has suggested, although very useful, cannot be used to properly implement rate per sender. smtpd_client limits are not for traffic control but rather to help with client software: "Measures against clients that make too many connections". Although one can find recommendations such as this one that it surely may help. As @E. Yazici has suggested, an addon for postfix is required. Personally I find policyd as recommended by @Janne Pikkarainen rather cumbersome although it is considered a standard.

My favorite addon is postfwd because it is light and easy. It is also worth noting that this works very easily with Plesk or other similar, without affecting Plesk's complicated set of configuration files. Email rate limit in Plesk has been only implemented in version 12 but still the policy features are limited.

First download the latest addon from the site above. I believe there is no rpm for CentOS, in contrast to Ubuntu and Debian. Nevertheless, it is advised that the latest version is used. More specifically, version 1.32 (which is present in eg. Ubuntu 14.04LTS repos) has a nasty bug that prevents it from functioning appropriately. Version 1.35 sorts this out.

Make sure that these PERL modules are present. If using Debian or Ubuntu you can install from repos so that all dependencies get automatically sorted out and then replace /usr/sbin/postfwd with the latest version.

Then create the ruleset. Create a file such as /etc/postfwd.cf or /etc/postfix/postfwd.cf and add:

id=R001; sender=~/.*/; action=rate(sender/100/86400/REJECT only 100 messages per day for $$sender)
id=R002; sender=~/.*/; action=rate(sender/50/3600/REJECT only 50 messages per hour for $$sender)

The above ruleset has obviously two rules that evaluate for all senders. The syntax of the rate action is:

rate (<item>/<max>/<time in sec>/<action>)

Other rate examples can be found here. Reference to the syntax can be found on the documentation. Similar discussion can be found here. If SASL is implemented (eg dovecot) you can safely replace sender with sasl_username. You can test the validity of the ruleset with the -C option:

postfwd -f /etc/postfwd.cf -C

Afterwards, you can optionally create a dedicated user and group postfwd under which postfwd will run and launch it:

postfwd --daemon -f /etc/postfwd.cf -u postfwd -g postfwd 

In case of having it installed from apt (Debian, Ubuntu etc), there should also be a configuration file under /etc/default/postfwd and you could start the service properly, eg sudo service postfwd start.

Then take a look at the log to verify that postfwd is listening. Postfwd uses the same log as postfix (eg /var/log/mail or /usr/local/psa/var/log/maillog etc) and a line as postfwd 1.35 ready for input should be in place.

Then, let postfix know to use postfwd. Edit the postfix conf file (usually /etc/postfix/main.cf) and in the line:

smtpd_recipient_restrictions = permit_mynetworks,...

add check_policy_service inet: Please consider that the order where you put this within smtpd_recipient_restrictions has great importance and you could end up spending a great deal of time diagnosing what could be wrong. As explained in this question, if one check returns OK or REJECT then postfix does not continue to the next one, so you should probably place this high.

Last, to check that this works you can either specify a very small limit such as 1 or even add a rule as id=DEFAULT; action=dunno. Any rule hit gets logged anyway. Please also note that the rate limit per sender does not distinguish between mulitple emails with a single recipient or a single email with multiple recipients.

Then send an email from an account (in that server) and look at the log:

grep "RULES" /var/log/mail

Other links: postfwd quickstart.

  • 1
    a blast from the past this question! thank you for taking the time to provide such a well thought out answer. I am impressed!
    – WarpKid
    Nov 6 '15 at 17:04
  • 1
    my version of postfix barfs on any smtpd_recipient_restrictions entry with a space in it, so I had to define postfwd_ratelimit = check_policy_service inet: in /etc/postfix/main.cf and then reference it in /etc/postfix/master.cf as smtpd_recipient_restrictions=...,$postfwd_ratelimit,... Mar 6 '16 at 6:01
  • To restart postfix in Ubuntu: sudo postfwd -f /etc/postfix/postfwd.cf --pidfile=/var/run/postfwd.pid --reload
    – Wtower
    May 3 '17 at 15:09
  • Using Ubuntu 16.04 at least, I found that I needed to change the wildcard in the rules to use .+ (at least 1) rather than .* (at least 0) so that rules don't match absent fields. Jun 13 '19 at 18:28

What you need is a policy addon for Postfix. There are a dozen of policy addon for Postfix, some of them have rate limiting feature. You can find a list of Postfix policy addons here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.