I think the problem with naughty and blocking "mostly good" servers is fully 
solved. The naughty plugin has been reimplemented as karma.  

POD:  https://www.tnpi.net/internet/mail/karma.html
Code: https://github.com/msimerson/qpsmtpd/blob/karma/plugins/karma

Here's a sample connection with the 'reject connect' option set:

26945 Accepted connection 0/15 from 201.238.201.232 / exchange.mauiandsons.cl
26945 Connection from exchange.mauiandsons.cl [201.238.201.232]
26945 (connect) ident::geoip: CL, Chile
26945 (connect) ident::p0f: Windows XP
26945 (connect) karma: fail, 1 naughty, 0 nice, 158 connects
26945 550 You were naughty. You are penalized for 0.79 more days.
26945 click, disconnecting
26945 (post-connection) connection_time: 0.038 s.
24709 cleaning up after 26945

Of course, it supports the reaper plugin, so disconnecting can happen at later 
hooks as well.

Matt



On May 24, 2012, at 3:06 PM, Jared Johnson wrote:

> We do something not exactly similar to this, but which might be somewhat
> instructive.  We modified the banner delay plugin so that the amount of
> delay we apply to a server depends on its previous behavior with us.  The
> default delay is 15 seconds; if you send a message that we reject as spam
> or virus, we increase the delay by 5 seconds.  If you send us a message
> that we deliver as clean (whether that's because of spam scanners,
> whitelists, or whatever), we reduce the delay by 5 seconds.  We attached
> other values to some other rejections; for instance, if you try to send
> mail to an invalid user, the delay is increased by 1 or 2 seconds.  We do
> not increase the delay to more than around 300 seconds, so that at least
> some very RFC-compliant MTA's at least have a chance to deliver, even if
> they manage to get themselves horribly delayed.
> 
> What we've found is that the main strength of the banner delay for us is
> not that it exposes early talkers (it exposes some), but that it
> encourages early disconnectors :)  Some spambots give up after just 5
> seconds of delay; the one that wait out our 15 second delay will often try
> to send a few messages and get rejected, then once we make our way up to
> 20 or 30 seconds they start giving up on us altogether.
> 
> So after we implemented this we noticed that what we had on our hands was
> a rough score card for all connecting IP's indicating how well we know
> them and how "naughty" they have been.  From this we've been able to
> further reduce the number of transactions for which scanning is required;
> for instance, if a client gets the default delay (e.g. for all intents and
> purposes we haven't heard from them), we only let them have a single
> concurrent connection with us.  We can also be more lenient with clients
> that have won and maintained a banner delay of zero by sending us some
> good mail and not screwing it up with bad mail.  If your 'naughty' plugin
> is pretty successful, perhaps we could benefit from adding a 'penalty box'
> like this based on the delay -- clients that have earned, say, a 30 or 60
> second delay by trying to send us too much spam and not enough ham get
> sent to the penalty box and are therefore no longer able to increase our
> concurrency.  I had an idea similar to this a while ago (we haven't got
> around to implementing it), where we *randomly* disconnect at the outset a
> client that's earned an increased banner delay, and the frequency of
> disconnection depends on long high a banner delay they've earned.  This
> would allow us to throw away connections while, again, still giving good
> clients a chance to eventually connect to us and send legit mail, thereby
> decreasing their delay.
> 
> Others may or may not find it worthwhile to implement this sort of mucking
> with banner delays (I'll list a couple of problems with it below); but
> simply scoring clients might be an answer to the problem of legit clients
> being rejected.  Rather than putting a client in the penalty box at the
> first violation, give them a few chances, and let clean mail put them back
> into good graces.
> 
> For storage of these scores we have been using a table Postgres with three
> fields: IP, delay (aka score), and timestamp, with entries expired after a
> client has not talked to us at all for 24 hours.  We've talked about using
> Cache::FastMMap for this because there is not really any benefit to
> keeping it in the database (we don't even try to synchronize it across
> clusters, if your score is effectively reset because you started talking
> to a new node then so be it).  But honestly, we haven't seen any big
> bottlenecks with the DB, so we haven't bothered doing the coding and
> testing work to move it to obviously more efficient mechanisms.
> 
> For anyone considering the delay method itself, one big weakness with this
> method is that since it does not "get rid of naughty connections as
> quickly as possible", unless you're using the async daemon (we aren't), it
> can wind up taking up a lot of resources.  Obviously it will still save
> plenty of CPU on account of spammers giving up instead of giving us
> something to scan; but without async, the sharp increase in concurrency
> will hurt memory usage.  One thing we recently added which I think will
> really help in this area is that we do our RBL lookup before starting the
> delay, and if a server is RBL'd we skip the delay and go right to
> disconnecting them.  Since so many servers are RBL'd this should help
> concurrency a lot.  If the server is not RBL'd, we subtract the amount of
> time it took for us to do the RBL lookup (and anything else we might have
> done first) from their banner delay -- after all, we've already been
> delaying our banner for that amount of time.
> 
> Aside from that, simply doing a banner delay has caused problems for a few
> legit servers which give up before they even get to our default delay. 
> We've pretty much completely gotten around this by excluding all private
> IP's, and clients that are given relay permission by our IP-based rules,
> from any banner delay whatsoever.
> 
> HTH!
> 
> -Jared
> 
>> I have written a plugin that is currently named naughty.
>> 
>> The POD has a good description of what it does and how it works. You can
>> read the POD here:
>> 
>> https://www.tnpi.net/internet/mail/naughty.html
>> 
>> The plugin is very effective at blocking spam and it has reduced my CPU
>> load enough to be measurable on munin graphs (which aren't exactly
>> granular). Read the POD at the URL above to see how and why.
>> 
>> The plugin has one teensy tiny problem. Because it penalizes servers that
>> send spam, it occasionally penalizes a "mostly good" server.  In a week of
>> running, it has done this exactly twice, and the two servers it nabbed are
>> mx.develooper.com and mx2.freebsd.org.  Both are servers that send lots of
>> ham, and occasionally, some spam.
>> 
>> I see a couple options.
>> 
>> a)  Whitelist the "mostly good" servers that get penalized. While that
>> would be easy, it requires manual effort on the part of the sysadmin, and
>> users will likely lose valid mail.
>> 
>> b) Keep track of senders who send us ham. Then we have lots of options. We
>> can allow mail from "mostly good" senders, randomly defer their
>> connections with a "We like you, but you're sending spam" error, or any
>> number of other ways to deal with them.
>> 
>> c) Other?
>> 
>> The data store for naughty is currently a database of key/value pairs. The
>> key is the remote IP (in integer form) and the value is a timestamp.
>> That's all that's needed for naughty to function.
>> 
>> To track naughty and nice senders, I'm imagining the DB would need
>> counters to track of the number of ham and spam messages received from
>> that server. Or even a single signed integer, where anything above zero is
>> bad and below zero is good.
>> 
>> The only other thing needed is a reliable way to detect that incoming mail
>> is ham.  For my server, I'll use 'dspam reject agree', so that if SA &
>> dspam agree that it's ham, then the naughty plugin increments the nice
>> counter.  When new connection arrive, they would be blocked based on their
>> karma (the weighting of naughty -vs- nice emails) they send.
>> 
>> I'm fishing for other ideas, better ideas, or experience (we tried that,
>> and these are the results) you can share.
>> 
>> Thanks,
>> Matt


Reply via email to