per-user usage metering

2011-06-08 Thread Ricardo Signes

Hi, Postfix.  Long-time fan, first time poster.

I need to keep track of per-user use of our SASL-authenticated outbound relay,
and to reject mail from users who are exceeding their allowed usage.  The
records of their usage need to be accessible to me elsewhere over extended
durations, although their specific format isn't a huge concern.

There is an existing system in place for this, but it's got a serious race
condition in it, and I'm not 100% sure that my idea to deal with the problem is
a great one.

Right now, users authenticate with SASL, and that's fine.

The mail then goes through a unix socket policy service via
smtpd_sender_restrictions.  This looks up the account (based on the
sasl_username) and then checks their recent usage in a usage database.  If they
are over usage, it returns a 450.  If they are not over usage, it signals
success by prepending a header.  Mail with that header is routed to another
transport by header_checks.

This other transport is responsible for performing a content spam check.  If
the message is spam, it is sent to an uninteresting destination.  If it is not,
the message (size, recipients, spam-check score, etc.) is recorded in the usage
database and the message is re-injected to its final destination.

The race condition is simple:  the smtpd can accept a lot of mail before the
logging transport can write to the usage database, meaning users can bypass the
usage limits.

My first moronic attempt to fix this was to move some of the logging to the
policy service, and to communicate the record id via the added header to the
logging transport, so it could update the record with the spam check score.  I
had forgotten that the policy service was being queried once *per recipient*,
which the obvious problem that each message was logged multiple times.  I
didn't want to try coordinating based on instance id (incrementing the
recipient count each time, etc.) -- and anyway, there is another problem:  the
mail might pass all the recipient restrictions and then fail during DATA.

My current thinking is this:

  1. a fast, idempotent policy service will check usage at rcpt time so that
 we can avoid accepting DATA if the user is over quota; it will signal
 acceptance with "OK"

  2. an end_of_data_restriction will log the recipient count, size, etc; it
 will signal acceptance by PREPENDing the record identifier

  3. the logging transport will still exist, and will do the content checks
 and update the record with the spam score

I'm not sure whether I am worried about the logging done by end_of_data
resulting in logging messages that for some reason do not reach the logging
transport.  In that case, I may mark the records as "pending," with the logging
transport marking them "accepted," and another job purging pending records
regularly.

Does this make sense?  Is it a terrible idea?  Is this all already covered by
some simple interface I have yet to discover?

-- 
rjbs


ignoring bogux MX entries

2011-06-20 Thread Ricardo Signes

So, every once in a while, this crops up:

  $ dig -t mx bollygroup.com

  ; <<>> DiG 9.4.2-P1 <<>> -t mx bollygroup.com
  ;; global options:  printcmd
  ;; Got answer:
  ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 996
  ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

  ;; QUESTION SECTION:
  ;bollygroup.com.IN  MX

  ;; ANSWER SECTION:
  bollygroup.com. 3600IN  MX  0 mail.
  bollygroup.com. 3600IN  MX  10 mail.vishalverma.com.

These guys have set up "mail." as their lowest distance MX, and Postfix tries
to deliver there.  It looks up "mail" and finds it under the resolver's search
prefix (even though, as far as I understand it, the DNS response is fully
qualified to begin with and should not be qualified by the search prefix).

This leads to the mail getting stuck in the queue, because the box handling
this mail is "mail.prefix.com," and Postfix reports "mail for bollygroup.com
loops back to myself"

...but it only does this if you (a) use the bogus "mail." record and (b)
qualify "mail." with the search prefix.

Is there a way to avoid this problem *without* special casing each domain that
has it?  That is, to say "don't qualify MX names" or "the MX name 'mail.' is
bogus and should be ignored" or anything else?

-- 
rjbs


using/logging client addr as part of SASL auth

2014-05-27 Thread Ricardo Signes
Hello!

I'm looking for a way to detect and distinguish different kinds of auth
failures.  Right now, I'm feeling a bit stuck by my inability to get all the
data I'd like in one place at the same time.

Right now, we're using SASL authentication with pwcheck.  pwcheck, of course,
only gets two data: username and password.  It can't take any action based on
the IP address of the remote.

Meanwhile, postfix's logs on failure don't appear to show me the username on
failed AUTH attempts.

I'd like to be able to distinguish the cases resulting from the intersections
of (one password over and over / many different passwords), (one username /
many usernames), (one IP address, many IP addresses).  With these data, I can
take better action to detect, classify, and react to bad actors.

I'm happy (I guess) to end up having to write code to make this happen, but I'm
not sure where I could do it.

-- 
rjbs


signature.asc
Description: Digital signature


Re: using/logging client addr as part of SASL auth

2014-05-27 Thread Ricardo Signes
* Wietse Venema  [2014-05-27T17:04:32]
> li...@rhsoft.net:
> > the problem ist that postfix has no idea of the SASL internals and should
> > not need to - in case of dovecot i asked a few days ago to log the username
> > because in case of using dovecot as SASL provider that's the only instance
> > which decodes the input and verify it against the user-db
> 
> Would not it be sufficient to trigger on repeated authentication
> failures, regardless of the login name?

It's not ideal.  Here are some scenarios:

  a.  one IP, the same username,   many different passwords
  b.  one IP, different usernames, many different passwords
  c.  many IPs, the same username, many different passwords
  d.  one IP, the same username,   the same (wrong) password repeatedly

Scenarios a,b,c are much more likely to be attacks than (d), which looks like
somebody just turned on their old laptop without fixing its fetchmail job.

Scenario a and b are single-IP bad actors trying to perform a dictionary
attack, targeted or not.

Scenario c is potentially someone with a botnet trying to get a single target.

Taking action based on "repeatedly failed auth from ip X" is a start, but it's
not great.

I definitely understand the point about not wanting to deal with the SASL
internals.  Putting aside that question, do you have any suggestions or
thoughts about improving the way in which potential attacks could be classified
with currently available data?

-- 
rjbs


signature.asc
Description: Digital signature


Re: using/logging client addr as part of SASL auth

2014-05-27 Thread Ricardo Signes
* Wietse Venema  [2014-05-27T17:48:03]
> Ricardo Signes:
> >   a.  one IP, the same username,   many different passwords
> >   d.  one IP, the same username,   the same (wrong) password repeatedly
> 
> I suppose that one would log a password hhas, just to be sure.

Yes, something like a truncated hash of the password salted with something
changed frequently and never stored.It only needs to detect
close-in-time "same password" with very low false positives.

> It is not practical to implement every SASL protocol in Postfix.
> Also, the more secure SASL protocols don't send a fixed password,
> instead they use challenge-response. In that case there is no way
> to find out whether you are looking at (a.) or (d.).

Indeed.  Fortunately (?) for me, I don't need to worry about that at this
point.

> Postfix could log the base64 blobs that the client sends.

Yes, I think that, as you suggest, this leads to a scary place.

> The general solution requires support in the authentication back-end,
> be it Dovecot or the SASL library.

I see now that libsasl v2's sasl_server_new takes a string in the form
"ipaddr:port" and that postfix's smtpd_sasl_activate seems to pass along the
actual remote client IP.  (Please tell me if I've grossly misread; I am not
familiar with Postfix's source.)  As long as we don't put an SMTP proxy in the
way, this suggests to me that I can probably do something *fairly* simple with
libsasl to get all the relevant data in one place.  I see a horrible, useful
hack in my future.

Thanks for your help.

-- 
rjbs


signature.asc
Description: Digital signature


more detail on lookup failures?

2014-09-04 Thread Ricardo Signes
Lately, I'm seeing a lot more of this from some servers:

  postfix/cleanup[20330]: [ID 947731 mail.warning]
warning: mysql:/etc/postfix/mysql_list_resend.cf lookup error for
"[...]"
  postfix/cleanup[20330]: [ID 947731 mail.warning]
warning: 6D0D222182: virtual_alias_maps map lookup problem for
[...] -- deferring delivery

This then reports "queue file write error", for reasons that seem explained by
the source.  I'm pretty sure that the problem will lie with "our stuff" and not
Postfix, but I'm trying to find out whether I can get more information on what
the lookup error was.

An incompetent skim over the source makes me think that if the MySQL query was
failing, I'd see log lines matching /mysql query failed/, which I am not
seeing.  (Actually, for the sake of full disclosure, I see it sometimes.  When
I see it, the failed lookup has been for an email address with a non-7-bit-safe
character, and makes sense.  It is the *other* failures that are baffling me.)

Is there something I can do to get more logging from postfix on this error,
before I switch to tracing?

-- 
rjbs


signature.asc
Description: Digital signature


Re: more detail on lookup failures?

2014-09-04 Thread Ricardo Signes
* Wietse Venema  [2014-09-04T15:55:07]
> Wietse Venema:
> > If there is no logfile record with:
> > 
> > warning: mysql query failed: [text from mysql_error() here]
> > 
> > then either your syslog daemon lost that record,
> 
> Yes.

Thanks.  I'll look harder, but this has happened many, many times.  The idea
that syslog is losing those records every time seems a bit hard to swallow, but
I can probably have dtrace watch the cleanup processes to see what's up for a
day or two.

-- 
rjbs


signature.asc
Description: Digital signature


Re: more detail on lookup failures?

2014-09-04 Thread Ricardo Signes
* Wietse Venema  [2014-09-04T15:55:07]
> No. All match_list errors are logged with the match_error() function.

First, let me note that I'm running 2.10.2.

Here are all the syslog entries for cleanup for the last half hour on one host
that's been having this problem.

tl;dr: 32 occurances of mysql map "lookup error"; 32 of "virtual_alias_maps
lookup problem"; 7 "query failed", each of which matches up with a
non-7-bit-safe recipient.

I'm going to go ahead with tracing in not too long, I hope.

-- 
rjbs
Sep  4 16:00:07 HOSTNAME postfix/cleanup[58636]: [ID 197553 mail.info] 
892EA14BEE: message-id=<>
Sep  4 16:00:08 HOSTNAME postfix/cleanup[58588]: [ID 197553 mail.info] 
1831814BEF: message-id=<[...]>
Sep  4 16:00:16 HOSTNAME postfix/cleanup[58636]: [ID 197553 mail.info] 
BD48814BF4: message-id=<[...]>
Sep  4 16:00:32 HOSTNAME postfix/cleanup[58588]: [ID 197553 mail.info] 
CC12B14BF5: message-id=<[...]>
Sep  4 16:00:35 HOSTNAME postfix/cleanup[58636]: [ID 197553 mail.info] 
8C41F14BF6: message-id=<[...]>
Sep  4 16:01:08 HOSTNAME postfix/cleanup[58588]: [ID 197553 mail.info] 
61DE314BFD: message-id=<>
Sep  4 16:02:06 HOSTNAME postfix/cleanup[58636]: [ID 197553 mail.info] 
AE39414C00: message-id=<>
Sep  4 16:02:44 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: mysql query failed: Illegal mix of collations for operation ' IN '
Sep  4 16:02:44 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: mysql:/etc/postfix/mysql_list_resend.cf lookup error for "[8BIT]"
Sep  4 16:02:44 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: 1D76114C01: virtual_alias_maps map lookup problem for [8BIT] -- 
deferring delivery
Sep  4 16:02:44 HOSTNAME postfix/cleanup[58636]: [ID 947731 mail.warning] 
warning: mysql query failed: Illegal mix of collations for operation ' IN '
Sep  4 16:02:44 HOSTNAME postfix/cleanup[58636]: [ID 947731 mail.warning] 
warning: mysql:/etc/postfix/mysql_list_resend.cf lookup error for "[8BIT]"
Sep  4 16:02:44 HOSTNAME postfix/cleanup[58636]: [ID 947731 mail.warning] 
warning: 258E514C02: virtual_alias_maps map lookup problem for [8BIT] -- 
deferring delivery
Sep  4 16:03:05 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: mysql:/etc/postfix/mysql_list_resend.cf lookup error for "[ADDR1]"
Sep  4 16:03:05 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: AA12214C05: virtual_alias_maps map lookup problem for [ADDR1] -- 
deferring delivery
Sep  4 16:03:06 HOSTNAME postfix/cleanup[58636]: [ID 947731 mail.warning] 
warning: mysql:/etc/postfix/mysql_list_resend.cf lookup error for "[ADDR3]"
Sep  4 16:03:06 HOSTNAME postfix/cleanup[58636]: [ID 947731 mail.warning] 
warning: 3C74014C06: virtual_alias_maps map lookup problem for [ADDR3] -- 
deferring delivery
Sep  4 16:03:17 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: mysql:/etc/postfix/mysql_list_resend.cf lookup error for "[ADDR6]"
Sep  4 16:03:17 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: 8E27214C07: virtual_alias_maps map lookup problem for [ADDR6] -- 
deferring delivery
Sep  4 16:03:19 HOSTNAME postfix/cleanup[58636]: [ID 947731 mail.warning] 
warning: mysql:/etc/postfix/mysql_list_resend.cf lookup error for "[ADDR3]"
Sep  4 16:03:19 HOSTNAME postfix/cleanup[58636]: [ID 947731 mail.warning] 
warning: 8B34F14C08: virtual_alias_maps map lookup problem for [ADDR3] -- 
deferring delivery
Sep  4 16:03:20 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: mysql:/etc/postfix/mysql_list_resend.cf lookup error for "[ADDR6]"
Sep  4 16:03:20 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: 9BA2314C09: virtual_alias_maps map lookup problem for [ADDR6] -- 
deferring delivery
Sep  4 16:03:22 HOSTNAME postfix/cleanup[58636]: [ID 947731 mail.warning] 
warning: mysql:/etc/postfix/mysql_list_resend.cf lookup error for "[ADDR3]"
Sep  4 16:03:22 HOSTNAME postfix/cleanup[58636]: [ID 947731 mail.warning] 
warning: 3F46A14C0A: virtual_alias_maps map lookup problem for [ADDR3] -- 
deferring delivery
Sep  4 16:03:33 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: mysql:/etc/postfix/mysql_list_resend.cf lookup error for "[ADDR7]"
Sep  4 16:03:33 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: B2CDA14C0B: virtual_alias_maps map lookup problem for [ADDR7] -- 
deferring delivery
Sep  4 16:03:34 HOSTNAME postfix/cleanup[58636]: [ID 947731 mail.warning] 
warning: mysql:/etc/postfix/mysql_list_resend.cf lookup error for "[ADDR8]"
Sep  4 16:03:34 HOSTNAME postfix/cleanup[58636]: [ID 947731 mail.warning] 
warning: 1C3A714C12: virtual_alias_maps map lookup problem for [ADDR8] -- 
deferring delivery
Sep  4 16:03:36 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: mysql:/etc/postfix/mysql_list_resend.cf lookup error for "[ADDR3]"
Sep  4 16:03:36 HOSTNAME postfix/cleanup[58588]: [ID 947731 mail.warning] 
warning: 702E914C13: virtual_alias_maps map lookup problem 

Yahoo!, DKIM, and Content-Length

2014-10-06 Thread Ricardo Signes
I've seen a number of messages about Yahoo! and DMARC failures, but none seem
to touch on what I think is the big problem right now.  If I missed this
happening, I apologize.

For some completely inexplicable reason, their DKIM signatures now (often, but
not always) look like this:

  DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048;
t=1412607024; bh=ZJ8Kpz6ZlqWM7sz40HW3fMAm5i4O9s27k2poen3h01U=;

h=Received:Received:Received:X-Yahoo-Newman-Property:X-Yahoo-Newman-Id:X-YMail-OSG:Date:From:Reply-To:To:Message-ID:Subject:MIME-Version:Content-Type:Content-Length:From:Subject;
 ...

Putting everything else aside, THEY SIGNED CONTENT-LENGTH.

Unless I am mistaken, cleanup(8) quite reasonably *deletes* Content-Length.
This means that any message that Yahoo! has sent with a DKIM signature
involving Content-Length is then broken.

This means that if Postfix forward mail from Yahoo! to (say) GMail, it will be
undeliverable due to DMARC.

I assume that I can regenerate Content-Length, if it's correct, but it would be
simpler if I could somehow:

  a) convince Yahoo! to get a grip
  b) convince cleanup to leave the header be

Is one of these possible?  Am I mistaken about something significant?

Thank you for your time, in advance.

-- 
rjbs


signature.asc
Description: Digital signature


Re: Yahoo!, DKIM, and Content-Length

2014-10-06 Thread Ricardo Signes
* Robert Schetterer  [2014-10-06T12:49:09]
> > involving Content-Length is then broken.
> 
> hm where in
> 
> http://www.postfix.org/cleanup.8.html
> is a delete action documented ?

It's documented in the release notes for v1.1.  It's mentioned that cleanup(8)
does this in the man page for header_checks(5).

It appears to be implemented in
src/cleanup/cleanup_message.c:cleanup_header_callback but I'm not extremely
well-versed in the Postfix source.

> gurus may ask this more exactly, but in general it not a good idea to
> use "traditional smtp forward" these days by tons of variations of
> dkim/spf/dmarc policies.

I am well aware of that, but "stop forwarding" is out of the question here.

-- 
rjbs


signature.asc
Description: Digital signature


Re: PATCH: Yahoo!, DKIM, and Content-Length

2014-10-06 Thread Ricardo Signes
* Wietse Venema  [2014-10-06T13:22:04]
> Good catch.  Unfortunately, this behavior is not configurable.
> Changing Postfix behavior requires either patching one bit in the
> executable file, or rebuilding Postfix from source.

Thanks for confirming my suspicion.

> By now, maybe is is better to keep this header?

I think it probably is, but I find it really frustrating that Yahoo! would not
only put it into outbound mail, but also *sign it*.  It's utter madness.  They
already sign a digest of the body!  I plan to complain, but I expect nothing to
come of it.

-- 
rjbs


signature.asc
Description: Digital signature


Re: Yahoo!, DKIM, and Content-Length

2014-10-06 Thread Ricardo Signes
* Viktor Dukhovni  [2014-10-06T13:40:52]
> It is also odd that they sign "Received" headers, I thought BCP
> was to avoid doing that:

Yes, you are correct.  The RFC goes on to show examples that use Received, and
various strictures about handling trace headers make it plausible that you
could use it.  I don't even think it's a very bad idea, but it's certainly
rare.

Note, too, that From and Subject appear in there twice, even though both
headers only appear once in the message.  Again, this is permissible and can be
verified properly, but... what?

-- 
rjbs


signature.asc
Description: Digital signature