> From: Steve Devine
>
> We have been toying with the concept of ratelimiting for some time. We
> use it create log entries and in some cases we use the control=freeze
> option to stop outgoing spam.
> here is what I and my Director would like to be able
> to do.
>
> -- Identify likely spammers via ratelimiting
> -- Freeze these messages using control=freeze
> -- Allow them to be delivered very slowly. And this is where it gets
> ugly
Why allow them to be delivered? If your software detected a likely spammer,
the only way to distinguish a honest user from a spammer/spambot
is manual inspection of content of few frozen messages (using `exipick`).
If it's spam, you don't want it delivered even very slowly;
you want to shut the user down. What's the alternative?
A spambot will continue to fill your queue with frozen messages
faster than you send them out slowly; slow spam will cause you
blacklisted after a while even if you don't care about outgoing spam
otherwise.
I like the idea from this list to detect spammers/spambots not by rate
of sending of all mail, but by rate of attempts to send to nonexistent
recipients. Spammers and spambots send to huge lists of email addresses.
Large part of email addresses in such lists don't exist anymore or
never existed (Message-Ids and corrupted strings in memory taken by
address harvesters as email addresses).
My implementation:
LIM = 100
PERIOD = 1h
WARNTO = abuse@???
EXIMBINARY = /usr/local/sbin/exim -f root
SHELL = /bin/sh
...
begin acl
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
control = submission/domain=
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
control = submission/domain=
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
control = submission/domain=
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
control = submission/domain=
add_header = X-Authenticated-As: $acl_m_user
accept authenticated = *
control = submission/domain=