[Mimedefang] md_check_against_smtp_server

Kris Deugau kdeugau at webhart.net
Fri Dec 19 10:40:12 EST 2003


Jim McCullars wrote:
> On Thu, 18 Dec 2003, James Miller wrote:
> [Qs re: filter_recipient and md_check_against_smtp_server]
> > But the RHS of the @ can be about 30 different domains for us.. so
> > I'm not sure how to structure a if/then/else function for each of
> > our domains
> 
>    FWIW, the approach I would take would be a hash.  I would define
> something like this:
> 
> my %relaytable = qw(domain1.com relay.domain1.com
>                     domain2.com whatever.domain2.com);
> 
> Where the first value is the hash key (name of the domain) and the
> second value is the value for that key (relay for that domain).  Then
> strip off the domain part of the email address and look up the relay
> in your hash.

I've done something similar on our hosting server, execpt I use a
DB_File hash database instead.  I still seem to have to reload MD for
changes to take effect, but I don't have to modify the filter itself.

In the mimedefang-filter on that system, I have the following:
(I've removed some of the special cases that make it a lot stranger. 
Watch for wrapped lines.  :/  )

---------

# Tie the db hash required for user checking
require DB_File;
use Fcntl;
tie %validusers, "DB_File", "/etc/mail/validusers.db", O_RDONLY;
tie %hosteddomains, "DB_File", "/etc/mail/hosteddomains.db", O_RDONLY;

[... filter_recipient is a ways further down ...]

sub filter_recipient {
  my ($recip, $sender, $ip, $host, $first, $helo, $rcpt_mailer,
$rcpt_host, $rcpt_addr) = @_;

  ($user,$domain) = split /\@/, $recip;

  if ((exists $hosteddomains{$domain}) && ($hosteddomains{$domain} !~
/RELAY/)) {

    $checkaddr = $user.".".$domain;

    if ((exists $validusers{$checkaddr}) && ($validusers{$checkaddr} eq
"OK")) {
      return ('CONTINUE',"ok");
    } else {
      return ('REJECT', "$recip is not a valid recipient address");
    }
  } else {
    return ('CONTINUE',"$recip should be OK:  Can't check non-local
domain $domain");
  }
}

--------

I use a pair of hashes containing:

%hosteddomains ==>  Information about domains which are "local" to this
box, and those we are a backup MX for.  For now, it's basically "RELAY"
(for backup MX) or "AV,SPAM" (for 'local' hosted domains).  It can be
*very* easily extended for per-domain options if you're using
stream_by_domain().

%validusers ==>  Information about which users in the 'local' hosted
domains are valid.  This could be extended for per-user options if you
use stream_by_recipient() in the same way %hosteddomains can be for
per-domain options.

There are other checks in other MD functions, and in sendmail, to
control relaying based on the sender's IP.

>    This is what I would try for 30 or so domains.  If it were a lot
> more, or if the relays changed very much, I would consider using
> Net::DNS to look up the MX rather than a hash that you would have to
> keep updated.

Mmmm.  That might be about as dangerous as enabling the
sendmail.cf-level "relay based on MX" option.  It's *far* too easy for
someone to publich your system as the sole MX for their domain... and
then cause your server to get buried under the storm of connections
relating to a domain you don't have anything to do with.

>    Note that this is untested, off-the-top-of-my-head code.

My code is currently in production use.  <g>  (Minus the commented-out
debugging lines, and some of the other checks unrelated to this thread.)

Admittedly, this is NOT on a secondary MX- but I think if I were setting
up such a system I'd likely do almost exactly this, along with rsync to
keep the hash DBs up to date from the master MX. 
md_check_against_smtp_server() can be a problem on a backup MX because
it usually tries to check against the primary MX...  which means your
backup MX isn't spooling your mail for you if your primary goes down.

As an added bonus, I can use makemap to build the hash DBs from the text
flatfiles.  (This is why the .db files are in /etc/mail;  makemap
refuses to hash flatfiles anywhere else.  Most annoying...)

-kgd
-- 
"Sendmail administration is not black magic.  There are legitimate
technical reasons why it requires the sacrificing of a live chicken."
   - Unknown



More information about the MIMEDefang mailing list