exim4 - Why is rate limiting outbound mail to a smarthost only working with acl_not_smtp?
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.
Related videos on Youtube
billyw
Updated on September 18, 2022Comments
-
billyw almost 2 years
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. Usingdpkg-reconfigure exim4-config
, I set it up to usemail.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?
-
billyw almost 10 yearsThanks for your response. I followed your recommendation, but
acl_smtp_rcpt
andacl_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? -
BillThor almost 10 years@billw
/usr/bin/mail
runs the localsendmail
program to deliver the mail rather than connecting over the network stack. In your case,exim4
is used as a dropin replacement forsendmail
. The mail will be treated as a non-smtp deliviry. Rate limiting will need to be done using a non-smtp ACL. -
billyw almost 10 yearsAh, 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. -
BillThor almost 10 years@billyw I've added the sendmail process into the main answer.