The Case for the /127 Subnet - Part III

When we left off in the previous post, we were discussing disabling NDP on Ethernet point-to-point links when using /127 prefixes. But there is another reason to disable NDP on Ethernet point-to-point links.

Neighbor Cache

If the link is a /64 subnet, an attacker can send a stream of packets onto the link with destination addresses that belong to the link’s subnet but which have unused Interface-IDs. For each address received, the router creates an INCOMPLETE entry in its neighbor cache and sends an NDP Neighbor Solicitation message onto the link to try to resolve the entry. By streaming enough different unused addresses, the attacker can cause the neighbor cache to fill up and the link to be congested with unanswered NS messages.

RFC 6164 cites this vulnerability as a reason for using /127s on your point-to-point links. While it’s true that this will stop this particular attack (because there are no unused addresses on the subnet), simply disabling NDP on your point-to-point links also eliminates the vulnerability. More importantly, the vulnerability exists on any subnet that supports NDP, and you can’t disable NDP on your LAN subnets. ICMPv6 rate limiting and intelligent edge filtering are needed to control the effects of a neighbor cache attack.

The more important reason cited by RFC 6164 for using /127s is the exposure to ping-pong attacks.

Ping-Pong

A ping-pong attack exploits a problem with older implementations of ICMPv6 compliant with RFC 2463. Here’s the problem:

  • You connect two routers, RA and RB, with a point-to-point link.
  • RA is given the address 2001:db8:1:2::1/64.
  • RB is given the address 2001:db8:1:2::2/64.
  • A packet arrives at RA with the destination address 2001:db8:1:2::3.
  • The destination is for the subnet of the point-to-point link, but it isn’t RA’s interface address. So RA forwards the packet into the link. Ping.
  • RB receives the packet.
  • The destination is for the subnet of the point-to-point link, but is not RB’s address, so RB forwards the packet back onto the link. Pong.
  • RA receives the packet, and the cycle repeats itself.

You can see how this could be exploited: An attacker floods packets with unused destination addresses onto the subnet, and the packets bounce back and forth between the two routers until their Hop Limit expires. Flood enough of these packets -- and a /64 provides a lot of unused addresses to hit -- and the capacitive effects bouncing packets effect will eat up bandwidth and router resources.

There are two things to observe about this behavior:

  • RA and RB cannot determine whether the destination address belongs to an existing device on the subnet, because there is no Neighbor Discovery on most point-to-point links.
  • A simple split-horizon rule would assume that if you receive a packet on a subnet that belongs on the subnet but does not belong to the receiving interface, there is no need to forward the packet back out the same interface. Presumably if the destination exists on the subnet, it already received the packet.

As it turns out, this vulnerability exists in IPv4 also; it’s just that there was never much risk exposure, because most everyone uses /30 or /31 subnets on IPv4 point-to-point links in order to conserve addresses.

RFC 4443 obsoletes RFC 2463, and in its Section 3.1 explicitly requires that a router receiving a packet whose destination address belongs to a subnet of the receiving interface but whose Interface-ID does not belong to the interface, must not send the packet back out the same interface. Problem solved.

Is Your Vendor Running Obsolete Code?

What gets my goat about this issue is that some vendors prefer to continue running the obsolete version of ICMPv6 rather than upgrading their code to RFC 4443-compliant ICMPv6. Their answer to the problem is to tell you to use /127s on your point-to-point links instead.

The IETF standards recommend using /64 subnets everywhere. The RIRs support your running /64 subnets everywhere. So are you going to disrupt the nice, consistent simplicity of your IPv6 address design in order to accommodate a router vendor who does not want to modernize their code? Or are you going to tell your vendors to stop using obsolete code?

You have a few options for dealing with this issue:

  • If you are running older, “pre-RFC 4443” Cisco IOS, upgrade to a newer version. Cisco supports RFC 4443.
  • Run IPv6 unnumbered on your point-to-point links. This isn’t a good solution for many operators, because it complicates monitoring and tracing. It also complicates running EBGP over the links.
  • Block access to point-to-point subnets from any untrusted zones. You probably don’t want the IP addresses of your point-to-point interfaces reachable from outside your network anyway.

Even if you take the “stand up to your vendors” approach I recommend, it’s going to take them some time to modernize. An interim solution, if you have concerns about the ping-pong vulnerability, is to assign /64 subnets to each point-to-point link, but select a /127 out of the /64 and configure that subnet on the link interfaces. This approach allows you to alleviate immediate concerns about security vulnerabilities, but also allows you with minimal network disruption to change your /127 subnets to their corresponding /64s when the time is right.

You’ll be living with your address design for a long time. Don’t let a vendor’s short-term laziness disrupt your long-term plans.

Note: This post originally appeared on Network World article titled “The Case for /127 Subnets.”