Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"reject_unknown_reverse_client_hostname" bouncing mail when name

248 views
Skip to first unread message

Jordan Russell

unread,
Aug 23, 2006, 8:47:11 PM8/23/06
to
(Postfix 2.3.2, Red Hat Enterprise Linux 4)

In Postfix I'm using:

smtpd_recipient_restrictions = .. reject_unknown_reverse_client_hostname
unknown_client_reject_code = 554

BIND runs on the same machine. /etc/resolv.conf is set as follows:

nameserver 127.0.0.1

I have found that when I stop the "named" daemon, all incoming mail is
rejected with:

554 5.7.1 Client host rejected: cannot find your reverse hostname

Yet the manual states:

"The reply is always 450 in case the address->name lookup failed due to
a temporary problem."

Does an unreachable name server not count as a "temporary problem"?

Thanks,
Jordan Russell

Wietse Venema

unread,
Aug 23, 2006, 9:31:48 PM8/23/06
to
Jordan Russell:
[ Charset ISO-8859-1 unsupported, converting... ]

That depends entirely on what your SYSTEM library routines do.

Don't shoot Postfix. It is only the MESSENGER.

Wietse

Tony Earnshaw

unread,
Aug 24, 2006, 1:48:12 AM8/24/06
to
on den 23.08.2006 Klokka 19:47 (-0500) skreiv Jordan Russell:

> (Postfix 2.3.2, Red Hat Enterprise Linux 4)
>
> In Postfix I'm using:
>
> smtpd_recipient_restrictions = .. reject_unknown_reverse_client_hostname
> unknown_client_reject_code = 554
>
> BIND runs on the same machine. /etc/resolv.conf is set as follows:
>
> nameserver 127.0.0.1
>
> I have found that when I stop the "named" daemon, all incoming mail is
> rejected with:
>
> 554 5.7.1 Client host rejected: cannot find your reverse hostname

In addition to what Wietse wrote, enter a fallback nameserver (i.e. your
ISP's nameserver) below localhost in /etc/resolv.conf. We run the same
OS as you and it works for us (we run a split caching nameserver on our
mail server).

You could also try to see to it that your local nameserver does not fall
out for extended periods (yes, I know up2date can ruin custom settings,
been there, seen that, but make a backup of /var/named before you run
up2date).

> Yet the manual states:
>
> "The reply is always 450 in case the address->name lookup failed due to
> a temporary problem."
>
> Does an unreachable name server not count as a "temporary problem"?
>
> Thanks,
> Jordan Russell

--Tonni

--
Tony Earnshaw
reservebergenser :)

Tony Earnshaw

unread,
Aug 24, 2006, 2:19:57 AM8/24/06
to
to den 24.08.2006 Klokka 07:48 (+0200) skreiv Tony Earnshaw:

[...]

> nded periods (yes, I know up2date can ruin custom settings,
> been there, seen that, but make a backup of /var/named before you run
> up2date).

Oh yes, and make sure that named.conf, rndc.conf and rndc.key are
in /var/named (so that they get covered by the backup) and that the same
files in /etc are symlinks to these (means doing handwork after running
up2date)..

Jordan Russell

unread,
Aug 24, 2006, 2:41:15 AM8/24/06
to
Wietse Venema wrote:
> Jordan Russell:

>> Does an unreachable name server not count as a "temporary problem"?
>
> That depends entirely on what your SYSTEM library routines do.
>
> Don't shoot Postfix. It is only the MESSENGER.

Okay, I looked into this some more...

Postfix is expecting getnameinfo() to return EAI_AGAIN for temporary
failures. I took a look at the current getnameinfo() implementations in
glibc and FreeBSD's libc, and found that neither return EAI_AGAIN for
any reason. Rather, when they fail to retrieve a name, they return
EAI_NONAME regardless of whether the failure is permanent or temporary
in nature. See:

http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/inet/getnameinfo.c?rev=1.34&content-type=text/x-cvsweb-markup&cvsroot=glibc
and
http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/net/getnameinfo.c?rev=1.17.2.1&content-type=text/x-cvsweb-markup

Therefore, on Linux and BSD, failures to contact name servers during
reverse lookups are always treated as permanent failures by Postfix.

gethostbyaddr(), however, does return distinct codes for temporary and
permanent failures. I hacked sockaddr_to_hostname() in util/myaddrinfo.c
to always use the "EMULATE_IPV4_ADDRINFO" version, and
"reject_unknown_reverse_client_hostname" now returns a 450 response when
the name server is down.

Is there any real advantage to using getnameinfo() in place of
gethostbyaddr(), apart from the transparent IPv6 support?

--
Jordan Russell

Wietse Venema

unread,
Aug 24, 2006, 7:16:34 AM8/24/06
to
Jordan Russell:

> Wietse Venema wrote:
> > Jordan Russell:
> >> Does an unreachable name server not count as a "temporary problem"?
> >
> > That depends entirely on what your SYSTEM library routines do.
> >
> > Don't shoot Postfix. It is only the MESSENGER.
>
> Okay, I looked into this some more...
>
> Postfix is expecting getnameinfo() to return EAI_AGAIN for temporary
> failures. I took a look at the current getnameinfo() implementations in
> glibc and FreeBSD's libc, and found that neither return EAI_AGAIN for
> any reason. Rather, when they fail to retrieve a name, they return
> EAI_NONAME regardless of whether the failure is permanent or temporary
> in nature. See:

That would be a bug in the library. The solution is to send a bug
report and request that it be fixed.

Wietse

Jordan Russell

unread,
Aug 24, 2006, 12:21:46 PM8/24/06
to
Wietse Venema wrote:
> That would be a bug in the library. The solution is to send a bug
> report and request that it be fixed.

Supposing I did that, and both the Linux and BSD folks agreed that it
actually was a bug, I'd also have to convince the OS vendors to backport
the fix and put out updated libc packages for their existing releases.
That I don't really see happening.

If you don't believe that this should be addressed at the Postfix level
-- even if only as a temporary workaround until the OS vendors get their
act together -- then perhaps it would be wise to remove the claim in the
reject_unknown_reverse_client_hostname docs that 450 is "always"
returned for temporary problems, since what happens in the real world on
all existing releases of Linux and BSD is just the opposite.

In any event, I will run this by the glibc maintainers and see what they
have to say.

--
Jordan Russell

Wietse Venema

unread,
Aug 24, 2006, 1:08:02 PM8/24/06
to
Jordan Russell:

> Wietse Venema wrote:
> > That would be a bug in the library. The solution is to send a bug
> > report and request that it be fixed.
>
> Supposing I did that, and both the Linux and BSD folks agreed that it
> actually was a bug, I'd also have to convince the OS vendors to backport
> the fix and put out updated libc packages for their existing releases.
> That I don't really see happening.

This happens all the time. If users don't give feedback then bugs
won't be fixed.

> If you don't believe that this should be addressed at the Postfix level
> -- even if only as a temporary workaround until the OS vendors get their
> act together -- then perhaps it would be wise to remove the claim in the
> reject_unknown_reverse_client_hostname docs that 450 is "always"
> returned for temporary problems, since what happens in the real world on
> all existing releases of Linux and BSD is just the opposite.

I could spend the rest of my life adding disclaimers with "oh by
the way don't blame Postfix if the OS produces incorrect answers"
for every feature that Postfix implements.

> In any event, I will run this by the glibc maintainers and see what they
> have to say.

A dead name server must not be a treated as if it is a permanent
error condition, expecially when claiming that a name or address
does not exist. They made the same mistake with a dead name service
for /etc/passwd, which is another cause of mail getting rejected
for the wrong reason.

Wietse

Harvey Smith

unread,
Aug 24, 2006, 1:41:52 PM8/24/06
to
On Thu, Aug 24, 2006 at 11:21:46AM -0500, Jordan Russell wrote:
> Wietse Venema wrote:
> > That would be a bug in the library. The solution is to send a bug
> > report and request that it be fixed.
>
> Supposing I did that, and both the Linux and BSD folks agreed that it
> actually was a bug, I'd also have to convince the OS vendors to backport
> the fix and put out updated libc packages for their existing releases.
> That I don't really see happening.

Suppose instead you found all the packages for linux and BSD that used
libc's getnameinfo() and contacted all the maintainers to convince
them to implement a workaround for this bug in libc and then convinced
all the OS vendors to backport all the new packages?

--
Harvey

Jordan Russell

unread,
Aug 24, 2006, 2:54:51 PM8/24/06
to
Harvey Smith wrote:
> Suppose instead you found all the packages for linux and BSD that used
> libc's getnameinfo() and contacted all the maintainers to convince
> them to implement a workaround for this bug in libc and then convinced
> all the OS vendors to backport all the new packages?

Changing Postfix to use gethostbyaddr() instead of getnameinfo() seems
infinitely simpler than upgrading all of the world's "broken" libc
packages that have been shipping in every Linux and BSD release since 1999.

Besides, Postfix is probably one of the only programs that actually has
special handling for EAI_AGAIN. Generally, programs don't have two
separate code paths for temporary and permanent name resolution failures.

It appears that adding IPv6 support to the gethostbyaddr() code -- which
again is already there but hiding behind an #ifdef -- would require
fewer than 10 lines of code.

i.e. take this:

if ((hp = gethostbyaddr((char *) &(SOCK_ADDR_IN_ADDR(sa)),
sizeof(SOCK_ADDR_IN_ADDR(sa)),
AF_INET)) == 0)
return (h_errno == TRY_AGAIN ? EAI_AGAIN : EAI_NONAME);

and expand it to:

#ifdef HAS_IPV6
if (sa->sa_family == AF_INET6) {
if ((hp = gethostbyaddr((char *) &(SOCK_ADDR_IN6_ADDR(sa)),
sizeof(SOCK_ADDR_IN6_ADDR(sa)),
AF_INET6)) == 0)
return (h_errno == TRY_AGAIN ? EAI_AGAIN : EAI_NONAME);
} else
#endif
{
if ((hp = gethostbyaddr((char *) &(SOCK_ADDR_IN_ADDR(sa)),
sizeof(SOCK_ADDR_IN_ADDR(sa)),
AF_INET)) == 0)
return (h_errno == TRY_AGAIN ? EAI_AGAIN : EAI_NONAME);
}

Then the getnameinfo() stuff could just be removed.

Problem solved instantly for all past and present Linux and BSD releases.

Later, once all the broken libc's are eradicated from the face of the
earth, it could switch back to using getnameinfo() if need be.

--
Jordan Russell

Wietse Venema

unread,
Aug 24, 2006, 3:22:53 PM8/24/06
to
Jordan Russell:

> It appears that adding IPv6 support to the gethostbyaddr() code -- which
> again is already there but hiding behind an #ifdef -- would require
> fewer than 10 lines of code.
...

> #ifdef HAS_IPV6
> if (sa->sa_family == AF_INET6) {
> if ((hp = gethostbyaddr((char *) &(SOCK_ADDR_IN6_ADDR(sa)),
> sizeof(SOCK_ADDR_IN6_ADDR(sa)),
> AF_INET6)) == 0)
> return (h_errno == TRY_AGAIN ? EAI_AGAIN : EAI_NONAME);
> } else

Please cite the vendor-independent standards document that requires
that gethostbyaddr() supports IPv6, on IPv6 capable platforms.

If such a document does not exist, then the above code is non-portable,
that is, its behavior is undefined. With undefined behavior, different
systems may produce different results, if any result at all.

Wietse

Jordan Russell

unread,
Aug 24, 2006, 11:42:16 PM8/24/06
to
0 new messages