Re: [exim] Notification of ratelimits being exceeded?

Top Page
Delete this message
Reply to this message
Author: Lena
Date:  
To: exim-users
Subject: Re: [exim] Notification of ratelimits being exceeded?
> From: "Caines, Max"

> We're running rate-limiting based on sender address, which has been
> very effective in reducing the consequences of compromised accounts.
> Until now, I've been relying on some code on a server that's
> archiving Exim logs to recognise the blocking message, and email us
> once per sender, but it's not very reliable.


Below - automatic blocking of compromised accounts, with email notification.
Compromised accounts are used to send spam.
Lists of email addresses spammers send to
contain very many nonexistent email addresses.
The code below checks rate of sending to nonexistent recipients
and automatically blocks the account if rate exceeds limit.
Note that it's limit of nonexistent recipients, not total recipients.

LIM = 100
PERIOD = 1h
WARNTO = abuse@???
EXIMBINARY = /usr/local/sbin/exim -f root
SHELL = /bin/sh
local_from_check = false
...
acl_check_rcpt:
...
  accept hosts = !@[] : +relay_from_hosts
        set acl_m_user = $sender_host_address
             # or an userid from RADIUS
        condition = ${if exists{$spool_directory/blocked_relay_users}}
        condition = ${lookup{$acl_m_user}lsearch\
                    {$spool_directory/blocked_relay_users}{1}{0}}
        control = freeze/no_tell
        add_header = X-Relayed-From: $acl_m_user


  accept hosts = !@[] : +relay_from_hosts
        !verify = recipient/defer_ok/callout=10s,defer_ok,use_sender
        ratelimit = LIM / PERIOD / per_rcpt / relayuser-$acl_m_user
        continue = ${run{SHELL -c "echo $acl_m_user \
           >>$spool_directory/blocked_relay_users; \
           \N{\N echo Subject: relay user $acl_m_user blocked; echo; echo \
           because has sent mail to LIM invalid recipients during PERIOD.; \
           \N}\N | EXIMBINARY WARNTO"}}
        control = freeze/no_tell
        add_header = X-Relayed-From: $acl_m_user


  accept  hosts         = +relay_from_hosts
          control       = submission/domain=


  accept authenticated = *
        set acl_m_user = $authenticated_id
# in case of mailboxes in /var/mail: ${sg{$authenticated_id}{\N\W.*$\N}{}}
        condition = ${if exists{$spool_directory/blocked_authenticated_users}}
        condition = ${lookup{$acl_m_user}lsearch\
                    {$spool_directory/blocked_authenticated_users}{1}{0}}
        control = freeze/no_tell
        add_header = X-Authenticated-As: $acl_m_user


  accept authenticated = *
        !verify = recipient/defer_ok/callout=10s,defer_ok,use_sender
        ratelimit = LIM / PERIOD / per_rcpt / user-$acl_m_user
        continue = ${run{SHELL -c "echo $acl_m_user \
           >>$spool_directory/blocked_authenticated_users; \
           \N{\N echo Subject: user $acl_m_user blocked; echo; echo because \
           has sent mail to LIM invalid recipients during PERIOD.; \
           \N}\N | EXIMBINARY WARNTO"}}
        control = freeze/no_tell
        add_header = X-Authenticated-As: $acl_m_user


  accept authenticated = *
        control = submission/domain=


When you get a notification, examine content of frozen messages in the queue
using `exipick`. In unlikely case if it's not spam, delete the line
with the user ID from the $spool_directory/blocked_relay_users or
$spool_directory/blocked_authenticated_users file
(or you can delete the file if it contains only one line)
and unfreeze messages also using `exipick`.
If it's spam then change the user's password or otherwise block the user,
then fine the user according to contract and using frozen evidence.