[Mimedefang] MX ->

Jan Pieter Cornet johnpc at xs4all.nl
Tue Oct 11 18:21:39 EDT 2005

Sorry, I'm coming a little late to this discussions, but I have
a few hopefully useful suggestions.

On Tue, Oct 11, 2005 at 11:58:26AM -0400, Kevin A. McGrail wrote:
> We have added the check_primary_mx for senders to our filter with good
> success and I've added this feature to
> http://www.peregrinehw.com/downloads/MIMEDefang/mimedefang-filter-KAM
> To use this in your own filter, make sure you have use Net::DNS in a sub
> filter_initialize in your mimedefang filter.

Actually, "use Net::DNS;" should be at the top of your file, it doesn't need
to be in a subroutine (in fact, it's better not to). "use" is a compile-
time statement, not a runtime statement.

> Then, add the subroutines from
> http://www.peregrinehw.com/downloads/MIMEDefang/contrib/check_primary_mx_stub.pl
> to your filter.

We've been running with a check like this since about Februari this year,
with next to zero complaints. "We" in this case is xs4all.nl, a medium-
sized ISP in the Netherlands, handling about 5-10 million emails/day
(depending on how you count).

There are a couple of points that we included in the code, compared to
your version. First, I must emphasize that being a large ISP, we err
on the safe side here. If something feels more like incompetence than
malice, and if we're (if only barely) able to connect back to the
purported sending domain, we accept it. So for example, we don't reject
outright on private IP space in MX records, as long as there are
other reachable addresses too.

- in case there's no MX record, you can just take the domain itself
  as a degenerate form of MX host, and look for the A record of that.
  This behaviour is actually a backward-compatible form of mail sending
  from before MX records were invented. It's still used occasionally.

- sendmail (and possibly other MTAs) will actually understand this
  grossly wrong MX record:

example.com.     IN MX 10

  And use the "hostname" there as the IP address. (Of course, if you
  want your MTA to help fight for a better world, you'd probably want
  to RST your TCP connection to any loser mailing from such a domain
  with a christmas tree of death packet. But I digress...)

- you don't handle domains with mail exchanges only reachable via IPv6.

- if an MX record doesn't resolve at all, you can also consider it
  a malicious error (this one is quite common even).

- The domain could be in the form [], causing your MX lookup
  to fail (in which case you currently accept).

- The domain could even be [IPv6:2222::1234:5678:9abc:def0] (but we
  currently reject this, it's too obscure).

- This specific syntax:

example.com   IN MX 0 .

  is commonly understood to mean "this domain does not do email at all",
  so you can give an error of that kind. In your case, it will also get
  rejected as "." doesn't resolve, but it might be nice to code for this
  explicit case.

  However, we've already had issues with eNom.com (name-services.com)
  where their "smart" dynamic auto-load-balancing DNS servers
  occasionally issued such MX records erroneously among a set of other
  records for normal domains in common use by customers. So we currently
  only block on "MX 0 ." when it's the only MX record (or only one in
  a set of equal preferenced records).

- We explicitly test for lone hostnames and non-existing TLDs to give
  understandable error messages. These cases are usually due to
  incompetence, and the reject messages are actually read by users.

- We test the MX records per preference level, in order. The first set
  to return an "OK" status aborts the search. At the "most preferred"
  (lowest-numbered) level, we do allow for private IP space or
  non-existing hostnames, but the overall check will only succeed if
  there is another set of lower-preference MX records with valid IP

  The idea here is that this setup would "commonly work" and we're able
  to connect back to some MX records to deliver bounces, if any.

- Finally, we test inside filter_sender, HOWEVER we don't generate
  an error until filter_recipient, and we explicitly exclude a few
  recipients (like abuse@) just in case our logic is wrong or someone
  really feels they should be able to mail us from a domain with
  invalid MX records.

  Also, generating an error at RCPT To time is more likely to make it
  back to the sender, if the sending software is some type of MUA. Some
  software just doesn't understand errors at MAIL FROM time.

Some nice stats to top it off. On some random day last week we blocked:
38828 times a domain with unresolvable MX records.
20433 times a domain with MX Records pointing to localhost or localnet.
1946 times a domain with MX records in Private IP space (rfc1918)
1501 times a domain with MX records in BOGON IP space.
1472 times a domain with "." as the MX exchange
298 times a sender using a "lone hostname"
86 times a domain that doesn't resolve at all.
5 times a domain with MX records in class D or E (multicast IP space)
1 time a sender with an invalid TLD (foo.local or similar)

I'll ask if I can share our code, it might be useful.

#!perl -wpl # mmfppfmpmmpp mmpffm <pmmppfmfpppppfmmmf at fpffmm4mmmpmfpmf.ppppmf>
$_[2]}->(map{/p|f/i+/f/i}split//,$&)+97):qw(m p f)[map{((ord$&)%32-1)/$_%3}(9,
3,1)]),5,1)='`'lt$&;$f.eig;                                # Jan-Pieter Cornet

More information about the MIMEDefang mailing list