Koozali.org: home of the SME Server

qpsmtpd & 'Require Resolvable from Host' issue

Offline smeghead

  • *
  • 563
  • +0/-0
qpsmtpd & 'Require Resolvable from Host' issue
« on: September 08, 2013, 06:43:15 PM »
Hi all

I have a client that deals a lot with a global courier company, that shall remain nameless.  This company sends my client emails from a non-resolvable address which means that the SME server rejects them, & rightly so.  I don't want to globally turn this feature off so I have come up with a hack/kuldge.

qpsmtpd is designed to use plugins to enhance & extend its basic functionality, the 'Require Resolvable from Host' feature is implemented as one of these plugins; the plugins are stored in /usr/share/qpsmtpd/plugins.

I had a dig through the plugin code & it seemed that the best section for a hack/kludge was the check_dns subroutine:

sub check_dns {
  my ($self, $host) = @_;
  my @host_answers;

  # for stuff where we can't even parse a hostname out of the address
  return 0 unless $host;

  return 1 if $host =~ m/^\[(\d{1,3}\.){3}\d{1,3}\]$/;

  ## Kludge for Courier
  return 1 if $host = /smtpex/;
  ## End Kludge

  my $res = new Net::DNS::Resolver(dnsrch => 0);
  $res->tcp_timeout(30);
  $res->udp_timeout(30);
  my @mx = mx($res, $host);
  foreach my $mx (@mx) {
    # if any MX is valid, then we consider the domain
    # resolvable
    return 1 if mx_valid($self, $mx->exchange, $host);
  }
  # if there are MX records, and we got here,
  # then none of them are valid
  return 0 if (@mx > 0);

  my $query = $res->search($host);
  if ($query) {
    foreach my $rrA ($query->answer) {
      push(@host_answers, $rrA);
    }
  }
  if ($has_ipv6) {
    my $query = $res->search($host, 'AAAA');
    if ($query) {
      foreach my $rrAAAA ($query->answer) {
        push(@host_answers, $rrAAAA);
      }
    }
  }
  if (@host_answers) {
    foreach my $rr (@host_answers) {
      return is_valid($rr->address) if $rr->type eq "A" or $rr->type eq "AAAA";
      return mx_valid($self, $rr->exchange, $host) if $rr->type eq "MX";
    }
  }
  else {
    $self->log(LOGWARN, "$$ query for $host failed: ", $res->errorstring)
      unless $res->errorstring eq "NXDOMAIN";
  }
  return 0;
}

If you read through the code you'll see my kludge in Orange.

The bad mail host, as identified in the email headers, uses the name smtpex so this is what I checked for, & then I set the return value for $host to 1 if this string is found as per the logic of the module itself.

It's basic but works, prob a lot of better ways to do it but this works for me, feel free to recommend & critique.

Remember to restart qpsmtpd if you make a change like this.

Obviously this change will get trashed if the file is upgraded by a new version of qpsmtpd so document.

For me this is intended to be a temporary fix until I can persuade the muppets in the IT dept that something needs fixing at their end.

Cheers
..................

Offline smeghead

  • *
  • 563
  • +0/-0
Re: qpsmtpd & 'Require Resolvable from Host' issue
« Reply #1 on: September 09, 2013, 08:16:38 AM »
Hmm, looks like this kludge has some unforeseen consequences, clients email reception stopped after about 5 hours eventhough when initially implemented everything worked fine.

I'll need to work out why this happens or come up with a different test.
..................

Offline mmccarn

  • *
  • 2,651
  • +10/-0
Re: qpsmtpd & 'Require Resolvable from Host' issue
« Reply #2 on: September 09, 2013, 12:45:01 PM »
What if you define the unresolvable sending domain as a local domain on your SME server?


[edit - another idea]
This may not work for a company with lots of outbound mail servers - but, you can force a remote IP to be handled using the plugins for the local network by creating a symlink for the IP to 'local' in /var/service/qpsmtpd/config/peers. That is, if the offending remote host is 68.232.130.32:
Code: [Select]
cd /var/service/qpsmtpd/config/peers
ln -s local 68.232.130.32
sv t qpsmtpd

You can configure an entire remote class C network by leaving off the last period and octet ("68.232.130" in the example).

Note: I have verified that signal-event email-update does not remove the custom symlink, but I don't know if there is another event that will remove it, or if it will be removed by updates.

« Last Edit: September 09, 2013, 01:04:13 PM by mmccarn »

Offline smeghead

  • *
  • 563
  • +0/-0
Re: qpsmtpd & 'Require Resolvable from Host' issue
« Reply #3 on: September 09, 2013, 01:14:13 PM »
.. thanks for the suggestion, I'll give it a try later in the week
..................

Offline smeghead

  • *
  • 563
  • +0/-0
Re: qpsmtpd & 'Require Resolvable from Host' issue
« Reply #4 on: September 15, 2013, 06:46:23 PM »
.. well as it turns out I was making my life way to hard, there's actually a simple & elegant solution to the problem.

I have found that the contrib smeserver-wbl.noarch.rpm that I've already installed (as I do on many servers) is the answer to my dilemma; the menu option (once installed) is Email WBL.

Within the contrib page there are options to manage either the blacklist or whitelist, choose the whitelist.

Once on the whitelist page you're presented with 4 locations to add whitelist info, for this purpose ignore the top two boxes & enter the non resolvable hostname into the bottom 2 boxes, qpsmtpd whitelistsenders, and spamassassin whitelist_from, save.  You prob only need to use the whitelistsenders option TBH; the full description of its function gives us why:

"Any envelope sender of a mail (@host or user@host) matching an entry in whitelistsenders will be exempted from further validation during the 'mail' stage."

That's it, all working.

HTH
..................