0

In an effort to rate limit outgoing emails per recipient (all emails are sent by the same user), I've been doing some testing in a very simple environment:

                                         The Webs              

                                             ^                 
                                             |                 
+-------------------+   SMTP?         +--------+---------+       
|                   +---------------> | mail.example.com |       
| billyw.localhost  |                 |   (smarthost)    |       
|    (exim4)        |                 |                  |       
+-------------------+                 +------------------+       

billyw.localhost is a Debian machine. Using dpkg-reconfigure exim4-config, I set it up to use mail.example.com as a smarthost.

Currently, I'm rate limiting by adding an ACL to acl_not_smtp:

acl_not_smtp = acl_check_not_smtp

acl_check_not_smtp:

  # Rate limit based on the recipient address
  discard
    ratelimit = 7 / 1m / per_mail / $recipients
    log_message = Rate limit exceeded for $recipients: $sender_rate/$sender_rate_period (max $sender_rate_limit)

  accept

I'm testing this with the following command on billyw.localhost:

for i in {1..10}; do
  mail -s testing [email protected] <<< ''
  mail -s testing [email protected] <<< ''
done

This configuration seems to work as intended; it allows 7 emails through to each recipient and discards the final 3 per recipient.

However, if I try to use this same configuration in an SMTP-related ACL, such as:

  • acl_smtp_connect
  • acl_smtp_rcpt
  • acl_smtp_mail

Then the rate limiting entry of the ACL isn't hooked and all 10 messages are sent.

Why isn't the rate limiting being applied when it's put in an smtp-related ACL?

1 Answer 1

2

The acl_not_smtp is equivalent to acl_data for SMTP traffic. Try rate limiting in that ACL. SMTP connections give you more ACL options where you can place the message. (Note: discard is a blackhole variant of accept so you won't see reject messages.) Discarding is rather drastic, and I would use defer or deny for SMTP traffic.

Rate limiting is covered in chapter 42 section 38 of the Exim Specification. You can test with modified configuration so you can rate limit harder while testing than you would once you implement. Allow time for the test limits to clear before implementing.

Try adding the following to your acl_smtp_rcpt:

defer
  ratelimit = 7 / 1m / $recipients
  message = Rate limit exceeded for $recipients: \
            $sender_rate/$sender_rate_period (max $sender_rate_limit)

/usr/bin/mail runs the local sendmail program to deliver the mail rather than connecting over the network stack. In your case, exim4 is used as a drop-in replacement for sendmail. The mail will be treated as a non-smtp delivery. Rate limiting will need to be done using a non-smtp ACL.

4
  • Thanks for your response. I followed your recommendation, but acl_smtp_rcpt and acl_smtp_data aren't applying the rate limit to the outgoing messages. Which leads me to the question: Why do SMTP-related ACLs not apply to outbound emails sent to a smarthost via /usr/bin/mail? Is it actually sending batched SMTP instead of SMTP?
    – billyw
    Commented Jul 23, 2014 at 14:24
  • @billw /usr/bin/mail runs the local sendmail program to deliver the mail rather than connecting over the network stack. In your case, exim4 is used as a dropin replacement for sendmail. The mail will be treated as a non-smtp deliviry. Rate limiting will need to be done using a non-smtp ACL.
    – BillThor
    Commented Jul 24, 2014 at 0:29
  • Ah, that makes a lot more sense. This whole time I thought I was limiting outbound traffic to the smarthost, but I was actually limiting inbound traffic from /usr/bin/mail! If you word your comment into the main text of your answer, then I'll be happy to accept it.
    – billyw
    Commented Jul 25, 2014 at 16:50
  • @billyw I've added the sendmail process into the main answer.
    – BillThor
    Commented Jul 26, 2014 at 1:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .