Subject: RDNSS sanity checks (was Re: 6MAN WG Adoption Call: draft-gont-6man-nd-opt-validation-01)

From: Fernando Gont <[email-masked]>
Date: Tue, 24 Feb 2015 21:33:05 -0300

Hi, Tomoyuki,

Please find my comments in-line...

On 12/16/2014 10:36 PM, Tomoyuki Sahara wrote:
> I support adoption and have a comment.
> 
> In Section 10 (about RDNSS option) of this document:
> 
>>    The Lifetime field specifies the maximum time in seconds that a node
>>    may use the IPv6 addresses included in the option for name
>>    resolution, with a value of 0 indicating that they can no longer be
>>    used.  If the Lifetime field is not equal to 0, it MUST be at least
>>    1800 (MinRtrAdvInterval) and at most 3600 (2*MaxRtrAdvInterval).  If
>>    the RDNSS option does does not pass this validation check, it MUST be
>>    ignored.  However, the rest of the ND message MAY be processed.
> 
> The maximum value of the lifetime field should be larger.
> 
> Although the description above is consistent with RFC6106 (says the value
> of lifetime field SHOULD be <= 2*MaxRtrAdvInterval in section 5.1), it is
> too short because only a few packet losses removes DNS server information
> from hosts on the subnet as described in
> draft-gont-6man-slaac-dns-config-issues-00.
> 
> The suggested "default" value in the draft is 5*MaxRtrAdvInterval.  The
> "maximum" value must be larger than it.  I don't have any good technical
> reason, but I propose 10*MaxRtrAdvInterval which is twice the default
> value.

The thing here is that since s document is all about validation of
incoming packets (as opposed to how you set the Lifetime for the packets
you send I'm not sure what we can do about this *in this document*). May
be this calls for resurrecting draft-gont-6man-slaac-dns-config-issues-00?

Thanks!

Best regards,
-- 
Fernando Gont
SI6 Networks
e-mail: [email-masked]
PGP Fingerprint: 6666 31C6 D484 63B2 8FB1 E3C4 AE25 0D55 1D4E 7492

---

From: Fernando Gont <[email-masked]>
Date: Wed, 25 Feb 2015 00:12:40 -0300

On 12/29/2014 06:48 PM, James Woodyatt wrote:
> Hmm. Yeah, I can see how Preferred Lifetime isn't important to Prefix
> Discovery, but I don't see how it could be beneficial to make validity
> check specification so complicated to permit processing invalid Prefix
> Information options, i.e. when Preferred Lifetime > Valid Lifetime but
> A=0.  I can see that implementations of the validity check might be a
> little simpler if A=0 entails a shortcut result before loading and
> comparing the Preferred and Valid Lifetime fields, but it comes at the
> cost of complicating the specification of the validity check.
> 
> It would seem very odd to me if we had a specification where Preferred
> Lifetime exceeding Valid Lifetime is only grounds for ignoring a Prefix
> Information option in prefix discovery in the case where A=1, when the A
> flag has nothing to do with prefix discovery.  Dealing with that issue
> would require having two validity checks, one for prefix discovery and
> one for global address auto-configuration.  Not sure that the function
> abstraction there is worth the savings provided by the associated
> shortcut, much less all the extra logic in the protocol requirement
> specification.
> 
> Seems better to just keep the current language in the draft.

FWIW, I share James' view. Please folks speak up if you feel otherwise.

Thanks!

Best regards,

---

From: Fernando Gont <[email-masked]>
Date: Wed, 25 Feb 2015 00:34:30 -0300

Hi, Jinmei,

We're working n a rev of this I-D. And we hope to incorporate as many of
the suggested changes as possible in the next rev (the rest could be
added in subsequent revs). Please find my comments in-line....

On 12/29/2014 04:02 PM, 神明達哉 wrote:
[....]
> I reviewed and commented on a previous version of this draft, but it
> has been quite some time since then, so I gave it a fresh read.  Here
> are my comments on the 01 version (some of them may be a duplicate of
> my previous comments; I don't remember all of them).
> 
> - Section 3
> 
>    In the spirit of "being liberal in what you receive", the first
>    action is always preferred.  However, when an option length attribute
>    is invalid, it is not possible to parse the rest of the ND message.
>    In these cases, subsequent ND options should be ignored.
> 
>   In general, I'd be opposed to restrictions of dropping the entire ND
>   message *just* because "an option length attribute is unexpected"; if
>   it's invalid so that it is REALLY not possible to parse the rest of
>   the ND message, then it makes sense. 

Let us consider a scenario in which a n ND option has a fixed length,
but the length in the received option differs from the length specified
in the corresponding standard. What would be the point of trying to
parse that option?  Either the ND message was corrupted (and hence maybe
even the option-type byte is wrong) or... dunno..the implementation has
some gross bug 8in which case, fix the iplementation!)..

(FWIW, rather than arguing against our comment, I'm trying to understand
your rationale).

[....]
>   My personal suggestion is:
>   - remove all of these specific rules and just revise this general
>     rule in Section 3 so that it includes the above two critical cases
>     (and any other if there is)
>   - state that an implementation SHOULD NOT discard the entire ND
>     message just because some option field does not make sense or is
>     unexpected according to the current specification; as long as the
>     subsequent options are parsable it SHOULD move to the next option
>     (whether to handle or ignore the current option) and continue the
>     process.

FWIW, these two are in our (potential) TODO list... just waiting for you
to elaborate abit (as noted above) and maybe for others to weigh in.

>   - also state that an implementation SHOULD NOT assume a particular
>     length of an option when it moves to the next option (whether it
>     handles or ignores the current option) and SHOULD always use
>     the length field of the option.  For example, an implementation
>     SHOULD NOT assume the option length of 32 octets for the prefix
>     information option but SHOULD refer to its length field.

Applied (*without* the example).

> - Section 4
> 
>    NS, RS, and RA messages MAY contain an SLLA Option.
> 
>   Why the RFC2119 keyword (i.e., "MAY") here?  If it's intentional,
>   the choice looks quite awkward since RFC4861 uses SHOULD for some of
>   these cases.

We just meant that it's okay if the SLLA is found in NS, RS, and RA
messages. We've rephrased the text as:

    The SLLA Option is employed with NS, RS, and RA messages. If any
    other ND message contains an SLLA Option, the SLLA Option MUST be
    ignored.

> - Sections 4 and 5
> 
>    o  an address belonging to the receiving node (see Appendix A for
>       rationale)
> 
>   I think I pointed this out before, but "the receiving node" is not
>   really accurate and cab be misleading.  To be very accurate at the
>   risk of being verbose, I suggest:
> 
>    o  an address belonging to any of the interfaces of the receiving
>       node that is attached to the link where the ND message is sent
>       (see Appendix A for rationale).  Note that this interface is
>       usually the receiving interface of the ND message, but can be
>       different if multiple interfaces are attached to the same link.
>       Note also that it is possible, though unlikely, that the
>       specified link-layer address happens to belong to an interface
>       to a different link of the receiving node.

Upon reading your suggested text, I have the following
comments/questions (i.e., request for feedback):

* This part of the proposed text:

       an address belonging to any of the interfaces of the receiving
       node that is attached to the link where the ND message is sent
       (see Appendix A for rationale).

seems problematic. Firstly, it assumes that an implementation can tell
whether two interfaces are attached to the same link. While you could
*infer this by means of heuristics (same advertised prefixes, same
default router(s)) there's no easy and straightforward way to do it.
Secondly, in principle the easy-to-detect problem is when the ND message
contains an {S,T}LLA option containing the MAC address of the interface
on which you're receiving the ND message.

Then there's the case of what you do if the ND message contains an
{S,T}LLA option with a link-layer address of your node, but that *is
not* the link-layer address of the interface on which you have received
the ND message. While one would be tempted to drop such messages, if you
have a multihomed node (whether host or router), two interfaces are
attached to the same link, and for some reason you want to communicate
between those two interfaces, then dropping the aforementioned packets
would could this communication to fail (NS/NA messages would be using
SLLA/TLLA options with your own addresses.... but it would be *your node
itself* the one sending those NS/NA messages).

One could probably say that in such a scenario, in practice the
corresponding packets would be routed through the loopback interface
rather than through the real interface (and hence would never hit the
wire). If we consider it feasible to assume this, then I guess one could
enforce the "Seeing your own link-layer addresses in any interface other
than loopback is a bad thing".... but I'm not sure about it.

Thoughts?

> - Section 6
> 
>    As stated in [RFC4861] the Preferred Lifetime MUST be less than or
>    equal to the Valid Lifetime.  If an incoming ND message does not pass
>    this validation check, the Prefix Information Option MUST be ignored.
>    However, the rest of the ND message MAY be processed.
> 
>   The preferred lifetime only matters for stateless address
>   autoconfiguration (so, when the A-flag is on).  And RFC4862 already
>   states the option be ignored (though without an RFC2119 keyword) if
>   preferred-LT > valid-LT.  So I would see this paragraph as redundant
>   (or unnecessarily strong) and my primary suggestion is to just
>   remove it.  If we still really want to say something about it
>   explicitly in this draft, I would suggest, e.g., something like
>   this:
> 
>    As stated in [RFC4861] the Preferred Lifetime MUST be less than or
>    equal to the Valid Lifetime.  If the Prefix Information Option of
>    an incoming ND message whose A-flag is on, this option will be
>    silently ignored as specified in [RFC4862].

Two comments/questions here:

1) (just me double-checking) so essentially what you're saying is that
if the PIO is not being employed for SLAAC, it doesn't make sense to
enforce this check?

2) For the "A-flag is on" (SLAAC) case, since there's no RFC2119 keyword
in RFC4862, I suggest that we include one. -- I think that's a more
clear signal to an implementer.

> - Section 10: I suggest removing this paragraph as I commented on a
>   different message:
> 
>    [...]
>   Same for Section 11.

Done.

> - Section 11: I believe I made comments on this, but to repeat them:
> 
>    The domain suffixes included in this option MUST be encoded with the
>    simple encoding specified in Section 3.1 of [RFC1035].  Therefore, if
>    any of the labels of a domain does not have the first two bits set to
>    zero, the corresponding DNSSL option MUST be ignored.
> 
>   This paragraph doesn't make much sense to me.  The first sentence is
>   just a subset of the corresponding description of RFC6106, and could
>   even be ambiguous about whether the names can be compressed (RFC6106
>   is very clear about it).  The second sentence awkwardly talks about
>   one very specific invalid case, while there can be other kinds of
>   broken representation (e.g., exceeding the 255-octet limit).  I
>   suggest instead:
> 
>    [RFC6106] specifies the valid format of domain suffixes.  If a
>    suffix is not validly encoded as specified, the corresponding DNSSL
>    option MUST be ignored.

Makes a lot of sense. Applied. Thanks!

> - Appendix A
> 
>    In Figure 10, an off-net attacker sends Router A a crafted ND
>    message.
> 
>   What does an "off-net" attacker mean?  An attacker connected to
>   Network 1?  If so, isn't "on-net" (or "on-link") a better term?
>   If it's an attacker in somewhere else, how could it send a crafted
>   ND message to (the interface to Network 1 of) Router A?

Yes, this should really be "on-link". Thanks!

> - Appendix A and B
> 
>   I think I said this before, but to repeat it: I'd like to see a
>   statement of whether this is a theoretical attack scenario that
>   could be annoying but its severity is unknown, or it's proved
>   critical with some actual router implementations (e.g., making them
>   unworkable).

Appendix A: real attack (test it with an oepn source OS acting as a
router). Impact is CPU-consumption, and depends on the subsequent packet
rate-

Appendix B: theoretical attack scenario that could be annoying but its
severity is unknown. (The implementations *I* have tested discard the
attack packets when they employ a broadcast/multicast link-layer address).

Thanks!

Best regards,
-- 
Fernando Gont
e-mail: [email-masked] || [email-masked]
PGP Fingerprint: 7809 84F5 322E 45C7 F1C9 3945 96EE A9EF D076 FFF1

---

From: 神明達哉 <[email-masked]>
Date: Wed, 25 Feb 2015 10:58:15 -0800

At Wed, 25 Feb 2015 00:34:30 -0300,

> some gross bug 8in which case, fix the iplementation!)..

For example, consider the prefix information option.  As of RFC4861
it's defined as a fixed length option whose length field is supposed
to be 4, but (in my understanding) nothing prevents us from extending
this by adding some new (optional) fields after the "Prefix" field.
This can be a completely backward-compatible extension if the receiver
doesn't assume the magic number of 4 for all PIOs, but the current
restriction will make it unworkable.

Maybe it's less likely that we actually see this type of extension,
but unless it's explicitly prohibited, IMO it's overkilling to remove
that possibility in documentation like this one (which is largely a
clarification in my understanding).

> default router(s)) there's no easy and straightforward way to do it.

If the implementation diligently supports the scope model as described
in RFC4007 (FreeBSD does, as far as I remember), it should be able to
*decide* it.  Admittedly, though, there is no reliable and automatic
way to determine the scope zone boundary so the administrator would
need to configure it correctly by hand.  I also admit the vast
majority of actual implementations are not as diligent as FreeBSD.

> on which you're receiving the ND message.

Right.  And, from a quick look at the latest kernel implementation of
FreeBSD, I guess this is probably good enough (at least for that
particular implementation, and maybe for others if they have a
compatible behavior).  The FreeBSD implementation first determines the
outgoing interface, then resolves the link-layer address for the next
hop, and then loops back the packet if the link-layer address is equal
to that of the outgoing interface.  So the loopback attack doesn't
seem to be feasible if the forged link-layer address is different from
the one on the outgoing interface for the next hop (which is the one
attached to "Network 1" in the scenario of appendix A).

If this observation makes sense, one possible resolution for the
document is to change:

to

   o  an address belonging to the receiving interface (see Appendix A
      for rationale)

This is safe and would be sufficient in practice.  We might want to
add some notes on the general case including two or more interfaces
belonging to the same link, but that may just make the discussion
unnecessarily verbose and complicated.

> if the PIO is not being employed for SLAAC, it doesn't make sense to

"doesn't make sense" may be too strong (I'd say something like
"unnecessarily restrictive), but, *essentially*, yes.

> clear signal to an implementer.

That's fine for me.

--
JINMEI, Tatuya

---

From: Mark ZZZ Smith <[email-masked]>
Date: Thu, 26 Feb 2015 01:42:53 +0000 (UTC)

So I think there is a problem with RFC6106, as it makes the RDNSS information lifetime rely on the RA Router Lifetime information. Yet RFC4861 says the following about the RA Router Lifetime:

"A
Lifetime of 0 indicates that the router is not a
default router and SHOULD NOT appear on the default

Narten, et al.              Standards Track                    [Page 20]
^L
RFC 4861               Neighbor Discovery in IPv6         September 2007

router list.  The Router Lifetime applies only to
the router's usefulness as a default router; it
does not apply to information contained in other
message fields or options.  Options that need time
limits for their information include their own
lifetime fields."

So RDNSS options are broken in the sense that the option should have included their own independent lifetime information.

Alternatively, if the RDNSS addresses were link-local addresses, link-local addresses have infinite lifetimes, and therefore a link-local DNS resolver address should only become invalid if NUD failed for the address (regardless of whether the DNS information was learned via RA RDNSS options or DHCPv6 DNS options). In other words, RDNSS options with link-local addresses would continue to be valid (assuming continued passing of NUD tests) even if the RA they were learned from isn't (perhaps because another router is issuing RAs instead).

----- Original Message -----
From: Fernando Gont <[email-masked]>
To: Tomoyuki Sahara <[email-masked]>; "[email-masked]" <[email-masked]>
Cc: 
Sent: Wednesday, 25 February 2015, 11:33
Subject: RDNSS sanity checks (was Re: 6MAN WG Adoption Call: draft-gont-6man-nd-opt-validation-01)

Hi, Tomoyuki,

Thanks!

Best regards,

--------------------------------------------------------------------
IETF IPv6 working group mailing list
[email-masked]
Administrative Requests: https://www.ietf.org/mailman/listinfo/ipv6
--------------------------------------------------------------------

---

From: Mark ZZZ Smith <[email-masked]>
Date: Thu, 26 Feb 2015 01:48:42 +0000 (UTC)

(In hind sight, to make this clearer, it might have been better to make default router and lifetime information also an "RA" option, and called RAs something less 'routery' e.g., "subnet configuration advertisements".)

----- Original Message -----
From: Mark ZZZ Smith <[email-masked]>
To: Fernando Gont <[email-masked]>; Tomoyuki Sahara <[email-masked]>; "[email-masked]" <[email-masked]>
Cc: 
Sent: Thursday, 26 February 2015, 12:42
Subject: Re: RDNSS sanity checks (was Re: 6MAN WG Adoption Call: draft-gont-6man-nd-opt-validation-01)

"A

----- Original Message -----
From: Fernando Gont <[email-masked]>
To: Tomoyuki Sahara <[email-masked]>; "[email-masked]" <[email-masked]>
Cc: 
Sent: Wednesday, 25 February 2015, 11:33
Subject: RDNSS sanity checks (was Re: 6MAN WG Adoption Call: draft-gont-6man-nd-opt-validation-01)

Hi, Tomoyuki,

Thanks!

Best regards,

---

From: Fernando Gont <[email-masked]>
Date: Thu, 26 Feb 2015 09:50:09 +0100

Hi, 神明達哉,

> clarification in my understanding).

mm... I see your point. Me, I'd never "extend" an option that way. If
anything, I'd include the additional option, or would essentially
specify a whole new option that includes everything (existing prefix
plus the new extension).

While there can certainly be difference between what one implements (at
times taking some ("shortcuts") and what one implements, I'd personally
flag an option with a longer (than expected) length as bogus.

Back to this question, I'll start a different thread on this topic,
since this is a meta issue -- and thus would like to hear from the wg
what they think. Me, I would enforce a specific length... but I do see
your point and can live with it.

> majority of actual implementations are not as diligent as FreeBSD.

(thinking out loud) So I guess that, in principle, one could say that a
node should:

* *not* accept an LLA option that includes the same MAC address as that
of the interface on which the packet has been received, and,

* should accept an LLA option that includes a MAC address of one of its
interfaces only if:
   + the MAC address corresponds to an interface different from that on
     which the packet has been received, *and*
   + the MAC address corresponds to an interface that is in the same
     zone [RFC4007] as the interface on which the packet has been
     received

Thoughts?

> only accept one of it's own addresses in a LLA option if
> 

mm.. not sure I understood.

I Appendix A you map the Host C address to the router's own link-layer
address. Using a FreeBSD box as a router, you do get the expected
behaviour: the packet is forwarded over and over again until the Hop
Limit is decremented to zero.

(Just me curious: does the link-layer address really affect the loopback
thing? Or is it really the IPv6 address of the next hop that matters?)

> unnecessarily verbose and complicated.

Please take a look at my proposal above. It includes the simple case,
and the "two interfaces on the same link" thing -- although we might
also add a note that, in practice, the zone think will now work
automagically.

Thanks!

Best regards,

---

From: 神明達哉 <[email-masked]>
Date: Thu, 26 Feb 2015 11:49:23 -0800

At Thu, 26 Feb 2015 09:50:09 +0100,

[...]
>      zone [RFC4007] as the interface on which the packet has been

I guess the second '+' bullet should be

    + the MAC address corresponds to an interface that is NOT in the same
      link zone [RFC4007] as the link zone of the interface on which
      the packet has been received

Note also that if this is what you actually meant, the first '+'
bullet will be redundant.  Also, combining all of these bullets, we
could just say:

  a node should (or MUST) not accept an LLA option that includes a MAC
  address that corresponds to an interface that is in the same link
  zone [RFC4007] as the link zone of the interface on which the packet
  has been received

And, to this end, this is essentially what I originally suggested:

    (Address MUST NOT be any of the following:)

> Limit is decremented to zero.

What I tried to say with the example of setup in Appendix A is:

  - The attacker sends a crafted ND message containing:
     o  A Target Address, set the IPv6 address of Host C
     o  A TLLA Option, set to link-layer address of Router A's
        left-hand side interface (to the network depicted as
    '...==', which is different from Network 1)
then
  - A packet is sent to Router A with the IPv6 Destination Address of
    Host C.
then
  - Router A will forward the packet to Network 1 with the destination
    link-layer address being the one told via the crafted
    TLLA option.  Since this link-layer address is not the one of
     Router A to Network 1, it won't be looped back, and just will be
     sent out to the wire.  It's most likely to be just dropped there.

BTW, if the network Network 1 and '...==' belong to the same link, it
may still be received by Router A (not by loopback but from the
physical link) and cause the loop.  That's the rarer case of the
general description above.  If an implementation just performs the
simple check of comparing told link-layer address with that of the
receiving interface, and yet allows the
multiple-interface-on-the-same-link configuration, it will still be
susceptible to the attack.

> thing? Or is it really the IPv6 address of the next hop that matters?)

If I understand the question and the FreeBSD implementation correctly,
it's the link-layer address that matters at least in the case of
FreeBSD.  Its ether_output() function has this code:

    /*
     * If a simplex interface, and the packet is being sent to our
     * Ethernet address or a broadcast address, loopback a copy.
     * XXX To make a simplex device behave exactly like a duplex
     * device, we should copy in the case of sending to our own
     * ethernet address (thus letting the original actually appear
     * on the wire). However, we don't do that here for security
     * reasons and compatibility with the original behavior.
     */
    if ((ifp->if_flags & IFF_SIMPLEX) && loop_copy &&
        ((t = pf_find_mtag(m)) == NULL || !t->routed)) {
        if (m->m_flags & M_BCAST) {
[...]
        } else if (bcmp(eh->ether_dhost, eh->ether_shost,
                ETHER_ADDR_LEN) == 0) {
            update_mbuf_csumflags(m, m);
            (void) if_simloop(ifp, m, dst->sa_family, hlen);
            return (0);    /* XXX */
        }
    }

'ether_shost' should be the link-layer address of the outgoing
interface.
'ether_dhost' should be the link-layer address told by the TLLA
option.

--
JINMEI, Tatuya

---

From: Tomoyuki Sahara <[email-masked]>
Date: Fri, 27 Feb 2015 15:30:40 +0900

> be this calls for resurrecting draft-gont-6man-slaac-dns-config-issues-00?

Yes.  I think the draft provides a reasonable and practical solution for an
operational problem caused by too short lifetime value in RFC6106.

And if the sentence "If the Lifetime field is not equal to 0, it MUST be ...
at most 3600 (2*MaxRtrAdvInterval)" remains unchanged in this document, it
will prevent operators configuring their routers to send RFC6106 options
with lifetime greater than 3600, because he expects client PCs will ignore
the options according to this validation rule.  So I suggested larger
maximum value here.  Or, the validation rule should be removed for now.

Thanks,
Tomoyuki