Re: Comments on IM2000

Brian Candler <[email protected]> Fri, 6 May 2005 09:02:23 +0100
Newsgroups gmane.mail.im2000
Message-ID <[email protected]>
On Thu, May 05, 2005 at 11:27:33PM -0000, James Craig Burley wrote:
> >> On the SMTP side, it's not all *that* hard to prioritize incoming
> >> messages based on a recipient's perception of the trustability of
> >> upstream relays, including whether SMTP AUTH was used.  (But in cases
> >> where use of AUTH isn't reliably reported in "Received:" headers,
> >> either the relay in question always requires AUTH and thus acquires,
> >> over time, lots of trust, or will have to find other ways to be sure
> >> it avoids the problem of being a mixed source of UBE and desireable
> >> email and, thus, untrusted.)
> >
> >The trouble is you can't rely on the sender *telling* you that the message
> >was submitted via SMTP AUTH, and that therefore you should trust it. If so,
> >spammers would just make their mail systems make the same declaration.
> >
> >With SMTP, you need to verify independently whether the mail server in
> >question is actually trustworthy - for example by having trusted agents on
> >that ISP's network performing the testing for you. Ick.
> 
> I'm saying, why care whether a third-party relay uses AUTH or any
> other *particular* mechanism?
> 
> All you *really* care about is whether that relay is well-run enough
> to avoid accepting more UBE, likely destined for your system, than you
> feel comfortable with.

OK, sure. But then the question is - how do you *evaluate* that?

It's kind-of done now, but it works best for objective tests which can be
made from outside - e.g. "is this mail server an open relay?" If the test
fails you blacklist them, and if the IP owners wants to be removed, you can
easily re-test.

Things like "does this mail server owner manage their users properly?" is a
lot more woolly. Some blacklists will just blacklist any IP even if only one
or two pieces of spam are seen from it (regardless of whether millions of
non-spams are sent). But establishing "well run" involves either talking to
the users of that ISP, or going to that ISP and performing tests, or talking
to the ISP themselves, or otherwise gathering indirect evidence and weighing
up the probabilities.

The sort of things we're talking about are:

1. The mailserver operator knows the customer identity of every piece of
mail submitted into the system.

[I'm fine that it's either SMTP AUTH or some other mechanism, although the
most reliable one with dynamic IP will be SMTP AUTH]

2. This customer identity is carried forward *in the SMTP session* when
relaying to another host (e.g. as AUTH= parameter)

[That's to allow blacklists to operate on (relay,customerID) rather than
just relay address, in the case where the relay is trustworthy. Clearly it
can be tested whether this information is provided or not; whether or not
it's trustworthy information depends on whether the relay itself is
trustworthy. The same judgement would have to be made about IM2000 messages
stores]

3. The mailserver limits customers to sending a small number of messages per
day, unless the customer has established themselves as a bona fide sender of
large amounts of mail. [Same here; both SMTP and IM2000 could be extended to
indicate the number of messages sent recently by the same customer]

4. The ISP takes measures to limit the number of free signups [same]

Looking at this list, I think you're right that most of these weigh
similarly for IM2000 as for SMTP.

> So, let the sender track *all* those messages, as you suggest.  Now
> they're expending much more, in the way of their resources, per
> *important* outgoing message than the typical sender of legitimate
> email, *both* of whom get to shovel the *content* across the wire the
> first time they try.

I still don't much buy "expending _much_ more"

I thought a bit more about this last night. In order to bypass 4xx
greylisting systems, I only need to store one *bit* of information for each
recipient!

Let's say a spam sending program accepts as its input a gzipped stream of
E-mail addresses. As it unzips this stream, it tries to send mail to each
recipient (handing them out to a pool of parallel processes of course).

Now, all I need to do is allocate one bit of memory for each recipient, and
set it to zero, as I unpack. When a successful delivery occurs, or a
definite failure, I set it to one. There's no indexing or hashing required;
the N'th E-mail address in the gzip file is associated with the N'th bit in
my bitmap.

When I'm finished, I rewind my gzip file and repeat the operation, but only
send mail to each recipient which still has a zero bit. Rinse and repeat.

I could handle resends for 100M recipients with just under 12MB of RAM, and
a trivial modification to my existing spam-sending program.

I don't even have to send identical copies of mail, with identical envelope
senders. All I need is a 'callback function' which synthesises, for a
particular recipient, an envelope sender and message body for that
recipient. The only requirement is that the callback function gives the same
results for the same recipient, such that when I rewind and retry, each
recipient sees an identical replay. (Greylisting systems tend to greylist
[sender,IP] tuples rather than just [IP])

With a little more care I could arrange for my resends to occur at set
intervals which more accurately mimick a real mailserver (e.g. spend 15
minutes delivering messages, then rewind and attempt to re-deliver the
failed ones from the first block, before moving on). It would then become
very difficult to 'fingerprint' a spam sending program based on its retry
intervals.

> With IM2000, if that email has not actually read by a real person, it
> cannot be read at all, as the sender has moved on.  Once a few MUAs
> detect that, they can notify the "collective" that *all* pending
> notifications from that source are suspect.  Here, responsibility has
> not been accepted, but it's not clear whether false positives are
> involved (the "moving on" might have been a legit laptop sending legit
> email being disconnected or given a new IP address), so there's a
> problem with the fact that the messages aren't actually available to
> the reader (or a content-analysis engine).

Yes, this is a problem with IM2000, and it quite strongly discourages the
use of mailstores on dynamic IP addresses. It could be achieved with dynamic
DNS, but that's unlikely to be a reliable solution. IM2000 mailstores *need*
to be online whenever someone tries to fetch mail from them, in the same way
that currently a POP3 server *needs* to be online when someone tries to read
their mail from it.

But it would be hard to infer from the non-availability of a mailstore that
it's not legitimate. There are plenty of legitimate but poorly-run
mailservers and networks out there already.

> With my system, until that email is *fully* delivered, the sender
> retains responsibility for it.  "Moving on" can therefore be
> legitimately interpreted as no longer demonstrating interest in it.

I think that's the same. If you care about your message, you'll deposit it
in a well-connected mail relay on a fixed IP address.

> In the extreme (but likely frequent, in today's world) case, if an MTA
> simply decides to drop *all* pending email from a given source, it can
> do so in a fashion that either lets the sender discover the fact by
> issuing new tracking requests (which either fail or yield "discarded
> by server") or resending (which the MTA might /dev/null but not
> disclose accordingly).  Such mail is never "lost", however, since it
> was never truly *sent*, in that responsibility was never
> *transferred*, in the first place.

That means the recipient can see status as:
( ) Not transferred
(*) Transferred but not accepted (yet)
( ) Rejected
( ) Accepted

Effectively in SMTP, you have 1 (your SMTP relay may send you a warning if
the message is still on its queue), 3 (a bounce), and 4 (successful
delivery). State 2 is new, and a bit more woolly. The message contents have
been transferred - but if I'm genuinely interested in delivery, should I
attempt to transfer them again? Or is it sufficient just to keep polling for
status given a tracking ID?

If the majority of mail ends up in this state, then under your proposal the
sender of the mail will need to keep polling, just to prove that they are
'still interested'. That will be a big workload increase for all legitimate
mail, but spammers can easily match the raised bar too. I might need to
allocate *two* bits in my memory bitmap to properly record the state of each
message! However, if I have to remember a tracking-ID which was allocated by
the recipient, then that's some more work. I might end up keeping a spool
file on disk containing the state of each message. At 100 bytes each, my
100M messages might require 10GB of disk space to track (but only if they
all end up in this state; not-yet-transferred, rejected and accepted
messages don't require it)

And if I send my 100M messages using a network of 1000 0wned machines, then
the resources required per machine are cut down by a factor of 1000.

That does however suggest a sort of super-greylisting: instead of sending
back a tracking ID, if the recipient is suspect I send them back a huge
cookie (say 4KB of random data) and ask them to retry at least 2 hours
later. When they retry, they must return the same cookie. I don't waste
storage, because I just keep a cryptographic hash of the data, but the
sender is required to hold on to 4KB of crud for that period.

It's still not expensive enough though - 4KB times 1M recipients is only
4GB - and yet the extra sending and receiving of 4KB of data is costly to
the recipient as well as the sender.

"Hash cash" type challenges would be more effective; I send you a
cryptographic puzzle of known complexity, and won't deliver the message
until you send back the answer. This has the advantage of not requiring the
message to be delayed for a fixed amount of time; it is only delayed
depending on how quickly you solve the puzzle.

Hash-cash is currently difficult to deploy because either (a) all *clients*
need to implement it, or (b) all *mail relays* implement it, which is very
difficult because of the [intentionally] very high computation overhead when
sending large amounts of mail.

Also, to avoid expending hash-cash work except where necessary, you need a
reliable way to whitelist people you've communicated with before. In my
opinion, envelope-sender is not really good enough in the long term for
this, since it's trivially forgeable. Spammers *can* infer information about
who you communicate with, especially for people who use mailing lists.

But something like DomainKeys plus Hash Cash might work.

> There are difficult aspects to my proposal.  With a new, clean design,
> the challenges are mostly coming up with a design that won't have
> aggravating aspects down the road; with SMTP, it'd be annoying to have
> to take into account problematic aspects of that infrastructure,
> including a biggie, the difficulty of uniquely identifying any message
> *transmission* regardless of the *path* that message takes to reach a
> given MTA.

You can get the recipient to allocate a unique ID, which is unique locally
to them, such that [recipient,ID] is globally unique. When the message is
relayed you'll get another pair; the sender then has to associate the
recipient's ID with their own ID, potentially forming a chain. This would be
what happened if you received a packet by FedEx and resent it using DHL :-)

Or you can just get senders to allocate IDs, so that [sender,ID] is a fixed
unique key. That's what Message-ID: is supposed to do, although guaranteeing
uniqueness is hard. <Message-ID:, submitter-IP-address, submitter-identity>
should be enough, and if kept in this form, would give useful information
for evaluating the source too.

Regards,

Brian.