Hi Tim,

On Wed, Mar 24, 2004 at 09:38:24PM +0000, Tim Meadowcroft wrote:
> I started off thinking that I'd suggest adding basic tar-pitting 
> (http://www.gordano.com/kb.htm?q=1112) to selected plugins (such as SPF) that 
> are detecting blatant abuse - the idea being that if a spammer has recruited 
> 5,000 trojan home-cable machines worldwide to send out his spam, us just 
> rejecting his connection at the start of a conversation might reduce our 
> personal spam, but it doesn't hurt the spammer - in fact it saves him time 
> (and therefore money) in that we've rejected him early and he's now free to 
> get on to the next person (the equivalent of slamming the phone down on a 
> tele-marketer, when what really costs them money is when they waste 10 
> minutes on the phone and then you slam the phone down).
> 
> So, I was going to modify selected plugins to not just return DENY, but to 
> waste a bit of his time too
> 
>   my ($result, $smtp_comment, $comment) = $query->result2($rcpt->address);
>   if ($result eq "fail" and $self->{_args}{spf_deny}) {
>     # added a delay (default 30 seconds) to tar-pit nasty joe-jobbers
>     sleep(  $self->qp->config("tarpittime") );
>     return (DENY, "SPF forgery: $smtp_comment");
>   }
> 
> And then I figured that this holds up his SMTP conversation with me, but 
> probably doesn't do much more if he's using multiple threads (well, it does, 
> but not an awful lot) so then I thought why not exploit the fact that if he's 
> recruited a lot of home machines on cable/DSL connections, they have 
> asymmetric connections and so very limited upload speeds, so we want to waste 
> his time/bandwidth transmitting the stuff, and thereby reduce the 
> effectiveness of his 5,000 machines to some fraction of that number...
> 
> So perhaps I could add a new plugin return code of "DENYEVENTUALLY", which 
> remembers that we're going to reject his message, but lets him transmit the 
> whole thing, DATA and all (discarding it all as I go, of course), before 
> rejecting it, but slows down reading the socket so that he still has to send 
> all the data, but it takes a long time - maybe long enough for someone to 
> notice.
> 
> I'd want to make sure that I don't end up doing a DoS on myself, so I'd 
> probably put a cap on how many of these I'm running simultaneously and how 
> much bandwidth they're using, but then I started getting all sorts of nasty 
> thoughts about closing my end of the socket but sending back raw packets to 
> leave his socket in the infamous FIN_WAIT2 state (where it chews up resources 
> but can't be cleaned up)... and that's when I thought I'd check what the 
> interested parties think of the idea - has it been tried, does it sound fun, 
> does it already exist, do you already do this using one of these tcpwrapper / 
> smtproute whatever mechanisms ??

I think this sounds fun, but I'd suggest not putting tarpitting code inside 
existing plugins. Better to factor it out altogether - what about something 
like this:

- add a 'tarpit' plugin, that tarpits based on ip address (or just DENYs in 
  the event your tarpit caps are hit). Load this up early in your plugins/conf,
  register for most hooks, and tarpit away

- add a 'tarpit_helper' plugin that records the ip address of the current host
  in your tarpit database (var/db/tarpit/$ip_address ?) if a tarpit note is 
  set, and then returns a DENYSOFT. Load this up late in your plugins/conf
  (but before check_relay), also registering for most hooks.

Then adding tarpit support to existing plugins just becomes:

  $self->transaction->notes('tarpit', 1) if $tarpit_condition;

tarpit_helper then records the ip address, denysofts, and tarpit picks it up
next time it tries and does its thing.

Cheers,
Gavin


Reply via email to