diff mbox

Silence resolver logging for DNAME records when DNSSEC is enabled

Message ID 20150219190506.GA20188@spoyarek.pnq.redhat.com
State New
Headers show

Commit Message

Siddhesh Poyarekar Feb. 19, 2015, 7:05 p.m. UTC
DNAME records are a convenient way to set up RRSIG for an entire
subtree of a domain name tree instead of signing each of those
records.  Querying on such domains result in messages about a mismatch
in the query type and returned record type.  This patch disables the
logging of this message for DNAME records if the DO bit is set.

Tested on x86_64.

	* resolv/gethnamaddr.c (getanswer): Don't log about record
	type mismatch for DNAME if DNSSEC is requested.
	* resolv/nss_dns/dns-host.c (getanswer_r): Likewise.
---
 resolv/gethnamaddr.c      | 14 +++++++++++---
 resolv/nss_dns/dns-host.c | 11 ++++++++---
 2 files changed, 19 insertions(+), 6 deletions(-)

Comments

Carlos O'Donell Feb. 19, 2015, 11:45 p.m. UTC | #1
On 02/19/2015 02:05 PM, Siddhesh Poyarekar wrote:
> DNAME records are a convenient way to set up RRSIG for an entire
> subtree of a domain name tree instead of signing each of those
> records.  Querying on such domains result in messages about a mismatch
> in the query type and returned record type.  This patch disables the
> logging of this message for DNAME records if the DO bit is set.

Makes perfect sense.

> Tested on x86_64.
> 
> 	* resolv/gethnamaddr.c (getanswer): Don't log about record
> 	type mismatch for DNAME if DNSSEC is requested.
> 	* resolv/nss_dns/dns-host.c (getanswer_r): Likewise.

One nit in terms of readability.

If you disagree with me, feel free to commit as is.

> ---
>  resolv/gethnamaddr.c      | 14 +++++++++++---
>  resolv/nss_dns/dns-host.c | 11 ++++++++---
>  2 files changed, 19 insertions(+), 6 deletions(-)
> 
> diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c
> index 9e0c498..ae55fac 100644
> --- a/resolv/gethnamaddr.c
> +++ b/resolv/gethnamaddr.c
> @@ -349,10 +349,18 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype)
>  			continue;
>  		}
>  		if (type != qtype) {
> -			syslog(LOG_NOTICE|LOG_AUTH,
> +			/* Skip logging if we received a DNAME when we have set
> +			 * the DO bit.  DNAME records are a convenient way to
> +			 * set up DNSSEC records and such setups can make this
> +			 * log message needlessly noisy.
> +			 */
> +			if ((_res.options & RES_USE_DNSSEC) == 0
> +			    || type != T_DNAME) {

I find it clearer to write:

if (!((_res.options & RES_USE_DNSSEC)
      && type == T_DNAME)) {

i.e. invert the boolean to get an easier to understand "&&".

Which reads straightforwardly as:

If you request DNSSEC and you got a T_DNAME record type, don't log it.

While the present conditional reads as:

If it's not a T_DNAME, log it.
If we didn't request DNSSEC, log it.
Implies: If we requested DNSSEC, and it is a T_DNAME, don't log it.

> +				syslog(LOG_NOTICE|LOG_AUTH,
>  	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
> -			       qname, p_class(C_IN), p_type(qtype),
> -			       p_type(type));
> +					qname, p_class(C_IN), p_type(qtype),
> +					p_type(type));
> +			}
>  			cp += n;
>  			continue;		/* XXX - had_error++ ? */
>  		}
> diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
> index b10c94e..510d388 100644
> --- a/resolv/nss_dns/dns-host.c
> +++ b/resolv/nss_dns/dns-host.c
> @@ -844,9 +844,14 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
>  	have_to_map = 1;
>        else if (__glibc_unlikely (type != qtype))
>  	{
> -	  syslog (LOG_NOTICE | LOG_AUTH,
> -	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
> -		  qname, p_class (C_IN), p_type (qtype), p_type (type));
> +	  /* Skip logging if we received a DNAME when we have set the DO bit.
> +	     DNAME records are a convenient way to set up DNSSEC records and
> +	     such setups can make this log message needlessly noisy.  */
> +	  if ((_res.options & RES_USE_DNSSEC) == 0 || type != T_DNAME)

Likewise with the conditional.

Otherwise it's fine.

> +	    syslog (LOG_NOTICE | LOG_AUTH,
> +		    "gethostby*.getanswer: asked for \"%s %s %s\", "
> +		    "got type \"%s\"",
> +		    qname, p_class (C_IN), p_type (qtype), p_type (type));
>  	  cp += n;
>  	  continue;			/* XXX - had_error++ ? */
>  	}
> 

Cheers,
Carlos.
Florian Weimer Feb. 20, 2015, 8:10 a.m. UTC | #2
On 02/19/2015 08:05 PM, Siddhesh Poyarekar wrote:
> DNAME records are a convenient way to set up RRSIG for an entire 
> subtree of a domain name tree instead of signing each of those 
> records.  Querying on such domains result in messages about a
> mismatch in the query type and returned record type.  This patch
> disables the logging of this message for DNAME records if the DO
> bit is set.

Can we remove the logging altogether?  Or at least for the
RES_USE_DNSSEC case?

The DO bit essentially means, “I'm fine with receiving unknown RR
types”, it's not really related to DNSSEC.  The reason for that is the
fact that the DNSSEC protocol was changed twice (once for DNSSECbis,
which is completely unrecognizable to the previous implementation, and
once for NSEC3), and the flag was reused.

So unless there is a compelling reason for logging this information,
I'd say just remove it.
Carlos O'Donell Feb. 20, 2015, 6:35 p.m. UTC | #3
On 02/20/2015 03:10 AM, Florian Weimer wrote:
> On 02/19/2015 08:05 PM, Siddhesh Poyarekar wrote:
>> DNAME records are a convenient way to set up RRSIG for an entire 
>> subtree of a domain name tree instead of signing each of those 
>> records.  Querying on such domains result in messages about a
>> mismatch in the query type and returned record type.  This patch
>> disables the logging of this message for DNAME records if the DO
>> bit is set.
> 
> Can we remove the logging altogether?  Or at least for the
> RES_USE_DNSSEC case?

Sure.

> The DO bit essentially means, “I'm fine with receiving unknown RR
> types”, it's not really related to DNSSEC.  The reason for that is the
> fact that the DNSSEC protocol was changed twice (once for DNSSECbis,
> which is completely unrecognizable to the previous implementation, and
> once for NSEC3), and the flag was reused.

I would like to clarify this a bit for anyone reading, and please
correct me if I'm wrong.

DNSSECbis is the working draft of a new version of DNSSEC, the
"bis" is 2nd in latin. IETF has informal rules for naming things
"bis" as "coming after the RFC." The DNSSECbis documents also
update NSEC3. They are not a distinct independent implementation.

My understanding was that DNSSEC would remain the umbrella name for
what can be deployed as supporting NSEC and/or NSEC3 (still flawed)
and/or NSEC5 (requires online hashing) [1]

Whether the implementation of NSEC3 or NSEC5 support the DO-bit is
what might be in question. Though DNSSEC as the original implemetnation
does support it.

In all of these cases the use of the DO-bit remains. No further RFC
removes the use of the DO-bit from the client side protocol. None
that I am aware of.
 
> So unless there is a compelling reason for logging this information,
> I'd say just remove it.

Sounds good to me.

Cheers,
Carlos.

[1] https://www.cs.bu.edu/~goldbe/papers/nsec5.pdf
Florian Weimer Feb. 23, 2015, 10:21 a.m. UTC | #4
On 02/20/2015 07:35 PM, Carlos O'Donell wrote:

> DNSSECbis is the working draft of a new version of DNSSEC, the
> "bis" is 2nd in latin. IETF has informal rules for naming things
> "bis" as "coming after the RFC." The DNSSECbis documents also
> update NSEC3. They are not a distinct independent implementation.

DNSSECbis is the current version of DNSSEC.  The first version had
shipping code but was never deployed widely, even less than the current
attempt.  It used the SIG/KEY/NXT record types previously referenced in
the glibc sources.  The current version (DNSSECbis) uses
RRSIG/DNSKEY/NSEC instead  (or NSEC3 instead of NSEC, which is not
backwards-compatible and could be argued to be a new version).

> My understanding was that DNSSEC would remain the umbrella name for
> what can be deployed as supporting NSEC and/or NSEC3 (still flawed)
> and/or NSEC5 (requires online hashing) [1]

I don't think NSEC5 is really a thing, it's more like IPv7.

> Whether the implementation of NSEC3 or NSEC5 support the DO-bit is
> what might be in question. Though DNSSEC as the original implemetnation
> does support it.

Sorry, I don't understand.

> In all of these cases the use of the DO-bit remains. No further RFC
> removes the use of the DO-bit from the client side protocol. None
> that I am aware of.

The DO bit was introduced early because it was noticed that some clients
would choke on the unknown (to them) resource records sent along with
DNSSEC responses, so some mechanism was needed to suppress the record to
enable name resolution for those older implementations.
Carlos O'Donell Feb. 23, 2015, 3 p.m. UTC | #5
On 02/23/2015 05:21 AM, Florian Weimer wrote:
>> In all of these cases the use of the DO-bit remains. No further RFC
>> removes the use of the DO-bit from the client side protocol. None
>> that I am aware of.
> 
> The DO bit was introduced early because it was noticed that some clients
> would choke on the unknown (to them) resource records sent along with
> DNSSEC responses, so some mechanism was needed to suppress the record to
> enable name resolution for those older implementations.

You wrote earlier in this thread that the DO bit is not related to DNSSEC.

I argue that it *is* related to DNSSEC, and continues to be related.

Am I wrong?

If I am wrong, by what mechanism (if any is required) should the stub
resolver indicate that it is OK to send back DNSSEC RR's? Regardless of
the fact that those RR's are changing as we redefine DNSSEC.

Cheers,
Carlos.
Florian Weimer Feb. 23, 2015, 3:03 p.m. UTC | #6
On 02/23/2015 04:00 PM, Carlos O'Donell wrote:
> On 02/23/2015 05:21 AM, Florian Weimer wrote:
>>> In all of these cases the use of the DO-bit remains. No further RFC
>>> removes the use of the DO-bit from the client side protocol. None
>>> that I am aware of.
>>
>> The DO bit was introduced early because it was noticed that some clients
>> would choke on the unknown (to them) resource records sent along with
>> DNSSEC responses, so some mechanism was needed to suppress the record to
>> enable name resolution for those older implementations.
> 
> You wrote earlier in this thread that the DO bit is not related to DNSSEC.
> 
> I argue that it *is* related to DNSSEC, and continues to be related.
> 
> Am I wrong?

It was introduced to a specific failure case spotted with the first
installment of DNSSEC.

But the same bit was reused for the second installment of DNSSEC, which
was totally unrecognizable to implementations of the earlier DNSSEC
variant.  From their point of view, it could have been something else
entirely, they wouldn't know that it was still called DNSSEC.

DO is generally thought of as “DNSSEC supported”, so you are right, but
in practice, it just means, “you can send me properly formatted resource
records along with the answer which bear no relationship to the query,
and I will still pick out those records I'm interested in”.
Carlos O'Donell Feb. 23, 2015, 3:30 p.m. UTC | #7
On 02/23/2015 10:03 AM, Florian Weimer wrote:
> It was introduced to a specific failure case spotted with the first
> installment of DNSSEC.
> 
> But the same bit was reused for the second installment of DNSSEC, which
> was totally unrecognizable to implementations of the earlier DNSSEC
> variant.  From their point of view, it could have been something else
> entirely, they wouldn't know that it was still called DNSSEC.
> 
> DO is generally thought of as “DNSSEC supported”, so you are right, but
> in practice, it just means, “you can send me properly formatted resource
> records along with the answer which bear no relationship to the query,
> and I will still pick out those records I'm interested in”.

Just to be clear, you mean to say:

* The DO bit was reused in DNSSECbis.

* DNSSECbis itself is changed significantly from DNSSEC.

	- Uses new RRs.
	- Should not confuse NSEC3-unaware resolvers.
	- Should not cause NSEC-aware resolvers to mark
	  NSEC3-aware systems from being marked as invalid
	  signatures.

* The semantics of the DO bit remain roughly the same.

* The DO bit can continue to be used as expected.

I agree with all of those points. Perhaps my confusion was that you 
wrote "totally unrecognizable" which I interpreted to mean that you
were saying the DO bit had somehow changed semantics.

Cheers,
Carlos.
Florian Weimer Feb. 23, 2015, 3:36 p.m. UTC | #8
On 02/23/2015 04:30 PM, Carlos O'Donell wrote:
> Just to be clear, you mean to say:
> 
> * The DO bit was reused in DNSSECbis.

Yes.

> * DNSSECbis itself is changed significantly from DNSSEC.
> 
> 	- Uses new RRs.

Right.

> 	- Should not confuse NSEC3-unaware resolvers.

That would be “old DNSSEC-aware resolvers” (NSEC3 came later).

> 	- Should not cause NSEC-aware resolvers to mark
> 	  NSEC3-aware systems from being marked as invalid
> 	  signatures.

In DNSSEC terminology, DNSSECbis-signed zones should be marked as
Insecure (unsigned) by DNSSEC-gold (the original standard)-aware
resolvers.  I.e., they would still return data to clients, but wouldn't
indicate it is signed.  The other implementation choice would have been
claim there has been an attack and not return any data.  (In practice,
there were bugs here, same thing happened with NSEC3.)

> * The semantics of the DO bit remain roughly the same.

That depends what the semantics are.  If “DO” means “DNSSEC OK”, then
the semantics did change significantly.  If it means “you can send along
random garbage, and I will cope”, semantics remained unchanged.

> * The DO bit can continue to be used as expected.

Yes, this mostly worked.  The interop failure (Insecure vs Bogus) was
not caused by DO interpretation conflicts.
Carlos O'Donell Feb. 23, 2015, 3:41 p.m. UTC | #9
On 02/23/2015 10:36 AM, Florian Weimer wrote:
>> 	- Should not cause NSEC-aware resolvers to mark
>> 	  NSEC3-aware systems from being marked as invalid
>> 	  signatures.
> 
> In DNSSEC terminology, DNSSECbis-signed zones should be marked as
> Insecure (unsigned) by DNSSEC-gold (the original standard)-aware
> resolvers.  I.e., they would still return data to clients, but wouldn't
> indicate it is signed.  The other implementation choice would have been
> claim there has been an attack and not return any data.  (In practice,
> there were bugs here, same thing happened with NSEC3.)

OK.
 
>> * The semantics of the DO bit remain roughly the same.
> 
> That depends what the semantics are.  If “DO” means “DNSSEC OK”, then
> the semantics did change significantly.  If it means “you can send along
> random garbage, and I will cope”, semantics remained unchanged.

Why? The original RFC says simply that the DO bit means "can accept DNSSEC
security RRs" but says nothing about needing to understand them.

>> * The DO bit can continue to be used as expected.
> 
> Yes, this mostly worked.  The interop failure (Insecure vs Bogus) was
> not caused by DO interpretation conflicts.

Right.

Cheers,
Carlos.
Florian Weimer Feb. 23, 2015, 3:44 p.m. UTC | #10
On 02/23/2015 04:41 PM, Carlos O'Donell wrote:
>>> * The semantics of the DO bit remain roughly the same.
>>
>> That depends what the semantics are.  If “DO” means “DNSSEC OK”, then
>> the semantics did change significantly.  If it means “you can send along
>> random garbage, and I will cope”, semantics remained unchanged.
> 
> Why? The original RFC says simply that the DO bit means "can accept DNSSEC
> security RRs" but says nothing about needing to understand them.

The original RFC probably meant to restrict the effect to the record
types known at the time (SIG and NXT, KEY is not relevant in this
context).  glibc reflected this in its logging decision, the few DNS
implementations which sent the DO bit by default apparently did not,
which is why the flag was reused.
Carlos O'Donell Feb. 23, 2015, 3:47 p.m. UTC | #11
On 02/23/2015 10:44 AM, Florian Weimer wrote:
> On 02/23/2015 04:41 PM, Carlos O'Donell wrote:
>>>> * The semantics of the DO bit remain roughly the same.
>>>
>>> That depends what the semantics are.  If “DO” means “DNSSEC OK”, then
>>> the semantics did change significantly.  If it means “you can send along
>>> random garbage, and I will cope”, semantics remained unchanged.
>>
>> Why? The original RFC says simply that the DO bit means "can accept DNSSEC
>> security RRs" but says nothing about needing to understand them.
> 
> The original RFC probably meant to restrict the effect to the record
> types known at the time (SIG and NXT, KEY is not relevant in this
> context).  glibc reflected this in its logging decision, the few DNS
> implementations which sent the DO bit by default apparently did not,
> which is why the flag was reused.

OK, we are on the same page. Thanks. We will continue to use the DO bit
to mean "We are OK with receiving additional unrelated records 
and will attempt to parse them to the best of our ability, or ignore
them." Which is all you can do if you don't understand the new RRs.

Cheers,
Carlos.
diff mbox

Patch

diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c
index 9e0c498..ae55fac 100644
--- a/resolv/gethnamaddr.c
+++ b/resolv/gethnamaddr.c
@@ -349,10 +349,18 @@  getanswer (const querybuf *answer, int anslen, const char *qname, int qtype)
 			continue;
 		}
 		if (type != qtype) {
-			syslog(LOG_NOTICE|LOG_AUTH,
+			/* Skip logging if we received a DNAME when we have set
+			 * the DO bit.  DNAME records are a convenient way to
+			 * set up DNSSEC records and such setups can make this
+			 * log message needlessly noisy.
+			 */
+			if ((_res.options & RES_USE_DNSSEC) == 0
+			    || type != T_DNAME) {
+				syslog(LOG_NOTICE|LOG_AUTH,
 	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
-			       qname, p_class(C_IN), p_type(qtype),
-			       p_type(type));
+					qname, p_class(C_IN), p_type(qtype),
+					p_type(type));
+			}
 			cp += n;
 			continue;		/* XXX - had_error++ ? */
 		}
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index b10c94e..510d388 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -844,9 +844,14 @@  getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
 	have_to_map = 1;
       else if (__glibc_unlikely (type != qtype))
 	{
-	  syslog (LOG_NOTICE | LOG_AUTH,
-	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
-		  qname, p_class (C_IN), p_type (qtype), p_type (type));
+	  /* Skip logging if we received a DNAME when we have set the DO bit.
+	     DNAME records are a convenient way to set up DNSSEC records and
+	     such setups can make this log message needlessly noisy.  */
+	  if ((_res.options & RES_USE_DNSSEC) == 0 || type != T_DNAME)
+	    syslog (LOG_NOTICE | LOG_AUTH,
+		    "gethostby*.getanswer: asked for \"%s %s %s\", "
+		    "got type \"%s\"",
+		    qname, p_class (C_IN), p_type (qtype), p_type (type));
 	  cp += n;
 	  continue;			/* XXX - had_error++ ? */
 	}