RFC 6583

Operational Neighbor Discovery Problems

πŸ“… published March 2012, from ietf

RFC 6583 πŸ’– Operational Neighbor Discovery Problems

okay bestie, here's the header tea 🫢 This one is RFC 6583, called Operational Neighbor Discovery Problems, and it was published by the IETF in March 2012.

It was written by I. Gashinsky (Yahoo!), J. Jaeggli (Zynga), and W. Kumari (Google, Inc.). It's Informational, which means it's published for information and is not an Internet Standards Track spec πŸ“š ISSN: 2070-1721.

Its title block doesn't list anything it obsoletes or updates, so it's not replacing or changing any other RFCs πŸ™ˆ


Abstract ✨

okay so in IPv4, subnets are usually tiny 🀏 they're sized to fit just the machines that are actually on them. IPv6 flips that. The default subnet is a /64, which is so huge it covers trillions of addresses, and basically all of them are empty 😭

that size difference makes simple Neighbor Discovery (ND) implementations vulnerable to denial of service (DoS). They try to do address resolution for a massive pile of addresses that don't exist, and it gets messy fast πŸ’€ An attacker can do this on purpose, or it can happen by accident because of normal operational tools. The result is that new devices can't "join" a network, new IPv6 flows might not be possible, and existing IPv6 transported flows can get interrupted.

This document breaks down the DoS problem in detail πŸ” It also suggests implementation improvements, plus operational mitigation techniques that can, in some cases, protect against these attacks or at least make the damage less bad 🌸


Status of This Memo πŸ“œ

This document is not an Internet Standards Track specification. It's published for informational purposes 🌈

It's a product of the Internet Engineering Task Force (IETF) and represents the consensus of the IETF community. It went through public review and got approved for publication by the Internet Engineering Steering Group (IESG). Not every IESG-approved document is a candidate for any level of Internet Standard, so check Section 2 of RFC 5741 if you're curious about that 🧐

For the current status, any errata, and how to give feedback, go to http://www.rfc-editor.org/info/rfc6583. ✨


Copyright (c) 2012 IETF Trust and the persons identified as the document authors. All rights reserved. πŸ’…

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they're in effect on the publication date. Please read these carefully, because they explain your rights and restrictions for this document πŸ“–

Code Components pulled out of this document must include the Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions. They come without warranty, as described in the Simplified BSD License πŸŽ€


Table of Contents πŸ“‹

   1. Introduction ....................................................3
      1.1. Applicability ..............................................3
   2. The Problem .....................................................3
   3. Terminology .....................................................4
   4. Background ......................................................5
   5. Neighbor Discovery Overview .....................................6
   6. Operational Mitigation Options ..................................7
      6.1. Filtering of Unused Address Space ..........................7
      6.2. Minimal Subnet Sizing ......................................7
      6.3. Routing Mitigation .........................................8
      6.4. Tuning of the NDP Queue Rate Limit .........................8
   7. Recommendations for Implementors ................................8
      7.1. Prioritize NDP Activities ..................................9
      7.2. Queue Tuning ..............................................10
   8. Security Considerations ........................................11
   9. Acknowledgements ...............................................11
   10. References ....................................................11
      10.1. Normative References .....................................11
      10.2. Informative References ...................................11

1. Introduction 🧚

this doc is about implementation problems in IPv6's Neighbor Discovery protocol that can lead to vulnerabilities when a network gets scanned πŸ‘€ The scanner could be an intruder, or it could be a normal tool doing network inventory, security audits, and so on. Think "nmap" πŸ”Ž

It explains the problem in detail, suggests possible implementation improvements, and lists operational mitigation techniques that, in some cases, can protect against these attacks πŸ›‘οΈ

Here's the big picture πŸ–ΌοΈ RFCs usually describe the behavior of a protocol, meaning the "what" of what a protocol does. They don't usually get into the exact "how" of implementing it. The exact "how" depends on the overall hardware and software architecture of a particular device, and it's (correctly) left up to implementors, as long as the implementation differences still produce proper on-the-wire behavior πŸ’–

Also, while you read this, keep in mind that talking about how things have been implemented beyond basic compliance with the specification is not in scope for the Neighbor Discovery RFCs πŸ™…β€β™€οΈ

1.1. Applicability

this document is mainly for operators of IPV6 networks and implementors of [RFC4861] πŸ§‘β€πŸ’» It offers some operational considerations, plus recommendations for making the Neighbor Discovery protocol more resilient 🌟


2. The Problem 😀

okay so in IPv4, subnets are usually small, sized just big enough to cover the actual number of machines on them. For example, an IPv4 /20 only has 4096 addresses 🀏 Now IPv6's default subnet is a /64, which is so enormous it covers literally billions of billions of addresses 🌌 The overwhelming majority of those will be unassigned.

Because of that, simple Neighbor Discovery implementations can fail to behave the way you want when they try to resolve addresses for huge numbers of unassigned addresses πŸ’€ These failures can be triggered on purpose, when an attacker launches a denial-of-service attack (DoS) [RFC4732] to exploit this weakness. They can also happen by accident, when legitimate operational tools that scan networks for inventory and other purposes are used πŸ₯² The results are the same: new devices may not be able to "join" a network, it may be impossible to establish new IPv6 flows, and existing IPv6 transport flows may get interrupted.

Network scans try to find and probe devices on a network πŸ”­ Usually they target a range of addresses, or every address on a particular subnet. When those probes go through a router, and the target addresses sit on a directly attached network, the router tries to do address resolution on a ton of destinations. That's some fraction of the 2^64 addresses on the subnet πŸ˜΅β€πŸ’« The router's process of checking whether neighbors exist (or don't) can cause a denial-of-service condition. The sheer number of Neighbor Discovery requests can overwhelm the implementation's capacity to handle them, use up all the available memory, and replace existing in-use mappings with incomplete entries that will never get completed 🫠 A directed DoS attack can aim to create similar conditions on purpose. The network disruption that follows can hit existing traffic, and devices joining the network may find their address resolution attempts failing. This DoS-as-a-side-effect-of-scanning was described earlier in [RFC5157] πŸ“

To lower the risk from this DoS threat, some router implementations have added ways to rate-limit how fast they process Neighbor Solicitations (NS) 🚦 These mitigations do help, but they don't fully fix the issue. They can also bring their own set of problems to the Neighbor Discovery process πŸ™ƒ


3. Terminology πŸ“š

okay here are the key terms you'll need, bestie 🫢

Address Resolution: Address resolution is the process where a node figures out the link-layer address of a neighbor, given only its IP address πŸ”— In IPv6, address resolution is done as part of Neighbor Discovery [RFC4861], Section 7.2.

Forwarding Plane: This is the part of a router that's responsible for forwarding packets πŸš€ In higher-end routers, the forwarding plane is usually built in specialized hardware that's optimized for performance ⚑ The forwarding process includes figuring out the correct outgoing interface for a packet, decrementing its Time To Live (TTL), verifying and updating the checksum, putting the correct link-layer header on the packet, and then forwarding it.

Control Plane: This is the part of the router implementation that maintains the data structures deciding where packets should go πŸ—ΊοΈ The control plane is usually a "slower" software process running on a general purpose processor 🐒 It handles things like communicating network status changes through routing protocols, maintaining the forwarding table, doing management, and resolving the correct link-layer address for adjacent neighbors. The control plane "controls" the forwarding plane by programming it with the info it needs to forward packets πŸ‘‘

Neighbor Cache: As [RFC4861] describes, this is the data structure that holds a cache of (among other things) IP address to link-layer address mappings for connected nodes πŸ—‚οΈ The forwarding plane needs the information in the Neighbor Cache every single time it forwards a packet, so it's usually implemented in an Application-specific Integrated Circuit (ASIC) πŸ”₯

Neighbor Discovery Process: The Neighbor Discovery Process (NDP) is the part of the control plane that actually implements the Neighbor Discovery protocol 🧠 NDP handles address resolution and maintains the Neighbor Cache. When the forwarding plane handles a packet and the matching Neighbor Cache Entry (NCE) is missing or incomplete, it tells NDP to take action, usually through a shared queue πŸ“¬ NDP picks up requests from that shared queue and does whatever discovery action is needed. In many implementations, NDP is also responsible for responding to router solicitation messages, Neighbor Unreachability Detection (NUD), and so on ✨

4. Background ✨

Okay so modern routers split their work into two lanes πŸ›£οΈ. The forwarding plane is the speedy hardware part that shoves packets along, and it's super optimized because it handles a ridiculous number of packets per second πŸ”₯. The control plane is the brain 🧠, and NDP lives there, mostly as software running on a general purpose processor πŸ’….

When a router needs to forward an IP packet, the forwarding plane does a longest match lookup to figure out where the packet should go and which outgoing interface to use πŸ¦‹. To get it to an adjacent node, the packet gets wrapped in a link-layer frame, and that frame has a header with the link-layer destination address πŸŽ€. Then the forwarding plane checks the Neighbor Cache to see if it already has a suitable link-layer destination. If it doesn't, it drops the request into a queue and signals the control plane (that's NDP) that it needs the link-layer address resolved 🫢.

Protecting NDP, and the control plane in general, from getting overwhelmed with these requests is a big deal, so appropriate steps must be taken 😭. For example, the size and fill rate of the queue might be limited. NDP running in the control plane dequeues the requests and does the address resolution (by sending a neighbor solicitation and listening for a neighbor advertisement) πŸ“¬. This process is usually also in charge of other stuff needed to maintain link-layer information, like Neighbor Unreachability Detection (NUD) πŸ”.

Now the scary part πŸ’€. By sending the right packets to addresses on a given subnet, an attacker can make the router queue up attempts to resolve so many addresses that it crowds out attempts to resolve "legitimate" addresses. In lots of cases, it even stops maintaining the existing Neighbor Cache entries and can't answer Neighbor Solicitation 😡. This can mean the router can't resolve new neighbors, and it loses reachability to neighbors that already have NCEs πŸ™ˆ. During testing, they found that four simultaneous nmap sessions from a low-end computer were enough to make a router's Neighbor Discovery process unusable, so forwarding became unavailable to the destination subnets πŸ’”.

The failure to keep NDP behaving properly while under attack has been seen across multiple platforms and implementations, including the largest modern router platforms available (at the inception of work on this document) πŸ‘‘.

5. Neighbor Discovery Overview πŸ—ΊοΈ

When a packet arrives at a router (or the router generates one) for a destination on an attached link, the router has to figure out the correct link-layer address to put in the destination field of the Layer 2 encapsulation πŸ“¦. It checks the Neighbor Cache for an existing Neighbor Cache Entry for the neighbor. If none exists, it invokes the address resolution parts of the IPv6 Neighbor Discovery [RFC4861] protocol to find the neighbor's link-layer address πŸ”Ž.

[RFC4861], Section 5.2, explains how this works. The quick version is that the device creates a new Neighbor Cache Entry for the neighbor, sets the state to INCOMPLETE, queues the packet, and kicks off the actual address resolution ✨. Then it sends out one or more Neighbor Solicitations. When it gets back a matching Neighbor Advertisement, it completes the Neighbor Cache Entry and sends the queued packet off πŸš€.

6. Operational Mitigation Options πŸ› οΈ

This section covers some feasible mitigation options that network operators can use today to protect network availability while vendors work on more effective protection πŸŽ€. Ngl, some of these are "kludges," and they can be operationally difficult to manage πŸ™ˆ. We're presenting them anyway because they're the options we currently have. It is each operator's responsibility to evaluate and understand how these changes affect their network 🫢.

6.1. Filtering of Unused Address Space 🧱

The DoS condition happens when a router is forced to try resolving addresses on the subnet at a high rate 😀. So if you carefully place machines into a small portion of a subnet (like the lowest numbered addresses), you can filter access to every address outside that assigned portion using Access Control Lists (ACLs) or null routing. Both are features available on most existing platforms πŸ’…. This stops the attacker from making the router try to resolve unused addresses. For example, if there are only 50 hosts connected to an interface, you may be able to filter any address above the first 64 addresses of that subnet. You can do that by null-routing the subnet with a more specific /122 route, or by applying ACLs on the WAN link to keep the attack traffic away from the vulnerable device πŸ›‘οΈ.

As mentioned at the start of this section, it's fully understood that this is ugly (and difficult to manage) 😩. But if nothing else works, it can be a useful technique, especially when you're responding to an attack πŸ†˜.

This solution requires that the hosts be statically or statefully addressed (as is often done in a datacenter). They may not play nicely with networks using [RFC4862] πŸ₯Ί.

6.2. Minimal Subnet Sizing πŸ“

If you size subnets to match the number of addresses actually in use, you can avoid the problem entirely 🌸. For example, [RFC6164] recommends sizing the subnets for inter-router links so they only have two addresses (a /127) πŸ”—. It's worth noting that this practice is common in IPv4 networks, partly to protect against the harmful effects of Address Resolution Protocol (ARP) request flooding πŸ™Œ.

Subnet prefixes longer than a /64 can't use stateless auto-configuration [RFC4862], so this approach isn't suitable for hosts that aren't statically configured 🚫.

6.3. Routing Mitigation πŸ›€οΈ

This one is very effective 😌. You route the subnet to a discard interface (most modern router platforms can discard traffic in hardware / the forwarding plane). Then individual hosts announce routes for their IP addresses into the network (or you use some method to inject much more specific addresses into the local routing domain) πŸ“‘. For example, the network 2001:db8:1:2:3::/64 could be routed to a discard interface on "border" routers, and then individual hosts could announce 2001:db8:1:2:3::10/128 and 2001:db8:1:2:3::66/128 into the IGP πŸ¦‹. Usually you do this by binding the IP address to a virtual interface on the host (for example, the loopback interface), enabling IP forwarding on the host, and having it run a routing daemon 🧚.

Obviously, host participation in the IGP makes a lot of operators uncomfortable 😬. But it can be a very powerful technique if you use it in a disciplined and controlled manner πŸ’ͺ. One way to ease those concerns is to have the hosts participate in a different IGP (or a different instance of the same IGP) and then carefully redistribute into the main IGP 🫢.

6.4. Tuning of the NDP Queue Rate Limit 🎚️

Lots of implementations let you control the rate at which unknown addresses get resolved, so tuning this rate might help 🌈. But as with most tuning knobs (especially the ones that deal with rate-limiting), the attack may actually finish faster because the threshold is lower 😳. And if you lower the rate too much, it can hurt how long the device takes to learn new addresses under normal conditions. That happens, for example, after clearing the Neighbor Cache or when the router first boots πŸ₯΄. Under attack, you might also end up unable to resolve "legitimate" addresses any sooner than if you'd just left the parameter alone πŸ’€.

It's worth noting that this technique is only worth investigating if the device has separate queues for resolving unknown addresses and for maintaining existing entries 🧐.

7. Recommendations for Implementors πŸ“

This section has some recommendations for implementors of IPv6 Neighbor Discovery πŸ§‘β€πŸ’».

At a high level, implementors should program defensively πŸ›‘οΈ. That means assuming attackers will try to exploit implementation weaknesses, and making sure implementations are robust against various attacks 😀. For Neighbor Discovery, the following general considerations apply:

  • Manage Resources Explicitly: Processor cycles, memory, etc. are never infinite, and with IPv6's large subnets it's really easy to make NDP generate huge numbers of address resolution requests for nonexistent destinations 😩. So implementations need to limit the resources they spend on Neighbor Discovery requests in a thoughtful way πŸ’….
  • Prioritize: Some NDP requests matter more than others πŸ‘‘. For example, when resources are tight, responding to Neighbor Solicitations for one's own address is more important than starting address resolution requests that create new entries 🫢. Likewise, performing Neighbor Unreachability Detection is more important than creating new entries for possibly nonexistent neighbors. NUD by definition only runs on destinations that are actively being used, so it's giving priority πŸ¦‹.

7.1. Prioritize NDP Activities πŸ’…

okay bestie, not all Neighbor Discovery activities are equally important 🫢. Honestly, the big problem is when a flood of address resolutions for Neighbor Cache Entries that don't even exist shows up and takes over. That should not come at the expense of looking after the entries that are actually in use and keeping them fresh ✨. So implementations should split their work into categories with different priorities. Here are some examples of different activities, ranked roughly from most to least important. If an implementation includes these, the operator should be able to configure how they operate and what priority they get πŸŽ€.

  1. It is critical to respond to Neighbor Solicitations for one's own address, especially for a router πŸ‘‘. Whether it's for address resolution or Neighbor Unreachability Detection, not answering Neighbor Solicitations causes immediate problems πŸ’€. If you skip NS requests that are part of NUD, neighbors can delete the NCE for that address, and they'll follow up with NS messages using multicast. Once an entry gets flushed, traffic for destinations using that entry can't be forwarded until address resolution completes successfully. So basically, not responding to NS messages makes the NDP load go up and breaks ongoing communication 😭.
  2. It is critical to revalidate one's own existing NCEs when they need a refresh πŸ”₯. As part of NUD, ND is required to revalidate existing, in-use entries pretty often. If that doesn't happen, the entry can get discarded. For in-use entries, discarding one almost certainly leads to a later request for address resolution on that entry, except this time it uses multicast πŸ¦‹.

Same as above: once the entry has been flushed, traffic for destinations using it can't be forwarded until address resolution completes successfully 🌸.

  1. To keep the control plane stable, Neighbor Discovery activity tied to traffic sourced by the router (as opposed to traffic the router is just forwarding) should get high priority 🧚. When the network is having problems, debugging and making other operational changes depends on being able to query and access the router. Also, routing protocols that rely on Neighbor Discovery for connectivity may start reacting (negatively) to connectivity problems they think they're seeing, which causes extra, unwanted ripple effects 🌈.
  2. Traffic to unknown addresses should get the lowest priority πŸ™ˆ. It can actually be useful to tell apart "never seen" addresses from addresses that have been seen before but no longer have a corresponding NCE ✨. The conceptual processing algorithm in IPv6 Neighbor Discovery [RFC4861] calls for deleting NCEs under certain conditions. Instead of deleting them completely, though, it might be helpful to at least keep track of the fact that an entry existed at some point. That way you can prioritize address resolution requests for those neighbors over neighbors that have never been seen before πŸ’œ.

7.2. Queue Tuning πŸ“

On implementations where NDP requests are submitted through a single queue, router vendors should give operators ways to control both the rate at which link-layer address resolution requests get placed into the queue and the size of the queue πŸŽ€. This lets operators tune Neighbor Discovery for their specific environment, which is so important πŸ’–. Being able to set per-interface or per-prefix queue limits at a rate lower than the global queue limit might keep the damage from an attack limited to the network it targets πŸ›‘οΈ.

Setting these values has to be a very careful balancing act πŸ€Ήβ€β™€οΈ. The lower the rate of entry into the queue, the less load there is on the ND process. But then it takes the router longer to learn legitimate destinations, so it's a trade-off 😬. Picture a datacenter with 6,000 hosts attached to a single router. If you set that value under 1000, resolving all of the addresses from an initial state (or after something that invalidates the address cache, like a Spanning Tree Protocol (STP) Topology Change Notification (TCN)) could take over 6 seconds ⏳. Similarly, the smaller the queue, the more likely an attack can knock out legitimate traffic. The upside is that it uses less memory on the router 🧠.

8. Security Considerations πŸ”

This document outlines mitigation options that operators can use to protect themselves from denial-of-service attacks πŸ›‘οΈ. Implementation advice to router vendors that aims to fix known problems carries the risk of previously unforeseen consequences, so be careful, bestie 😱. It is not believed that these mitigation techniques, or the implementation of finer-grained queuing of NDP activity, create additional security risks or DoS exposure ✨.

9. Acknowledgements 🫢

The authors would like to thank Ron Bonica, Troy Bonin, John Jason Brzozowski, Randy Bush, Vint Cerf, Tassos Chatzithomaoglou, Jason Fesler, Wes George, Erik Kline, Jared Mauch, Chris Morrow, and Suran De Silva πŸ’œ. Special thanks to Thomas Narten and Ray Hunter for detailed review and (even more so) for providing text! πŸ‘‘

Apologies to anyone we may have missed. It was not intentional πŸ₯Ί.

10. References πŸ“š

10.1. Normative References

[RFC4861]  Narten, T., Nordmark, E., Simpson, W., and H. Soliman,
           "Neighbor Discovery for IP version 6 (IPv6)", RFC 4861,
           September 2007.

[RFC4862]  Thomson, S., Narten, T., and T. Jinmei, "IPv6 Stateless
           Address Autoconfiguration", RFC 4862, September 2007.

[RFC6164]  Kohno, M., Nitzan, B., Bush, R., Matsuzaki, Y., Colitti,
           L., and T. Narten, "Using 127-Bit IPv6 Prefixes on Inter-
           Router Links", RFC 6164, April 2011.

10.2. Informative References

[RFC4732]  Handley, M., Rescorla, E., and IAB, "Internet Denial-of-
           Service Considerations", RFC 4732, December 2006.

[RFC5157]  Chown, T., "IPv6 Implications for Network Scanning",
           RFC 5157, March 2008.

Authors' Addresses πŸ¦‹

Igor Gashinsky
Yahoo!
45 W 18th St
New York, NY
USA

EMail: igor@yahoo-inc.com


Joel Jaeggli
Zynga
111 Evelyn
Sunnyvale, CA
USA

EMail: jjaeggli@zynga.com


Warren Kumari
Google, Inc.
1600 Amphitheatre Parkway
Mountain View, CA
USA

EMail: warren@kumari.net
πŸ“¦ where this page comes from