RFC 7113

Implementation Advice for IPv6 Router Advertisement Guard (RA-Guard)

πŸ“… published February 2014, from ietf

RFC 7113: Implementation Advice for IPv6 Router Advertisement Guard (RA-Guard) πŸŽ€

okay bestie, let's get into it! ✨ Here's the title block, so you know the basics:

  • Number and title: RFC 7113, Implementation Advice for IPv6 Router Advertisement Guard (RA-Guard) πŸ’–
  • Author: F. Gont, from Huawei Technologies πŸ¦‹
  • Date: February 2014 🌸
  • Category: Informational, so it's published for information and isn't a Standards Track spec πŸ“š
  • Updates: RFC 6105 πŸ”₯ (it formally updates that one)
  • ISSN: 2070-1721

Abstract πŸ’œ

okay so RA-Guard is a super common way to stop forged ICMPv6 Router Advertisement messages from causing chaos πŸ™ˆ. Lots of real IPv6 networks lean on it as their first line of defense πŸ›‘οΈ. BUT, and this is a big but, some RA-Guard implementations can be tricked by using IPv6 Extension Headers πŸ’€. This doc walks through those evasion techniques and formally updates RFC 6105 so these RA-Guard evasion vectors are shut down for good ✨. It's giving "fix the bug" energy πŸ’….

Status of This Memo 🌈

ngl this part is the official paperwork πŸ“œ It's not an Internet Standards Track spec, it's just published for info πŸ¦‹. It is a product of the IETF, it represents the consensus of the IETF community, got public review, and was approved by the IESG πŸ’–. Not every IESG-approved doc is a candidate for any level of Internet Standard, so check Section 2 of RFC 5741 if you want the details 🫢.

Want the current status, any errata, or a way to give feedback? Head to http://www.rfc-editor.org/info/rfc7113 πŸ”—

Copyright (c) 2014 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) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License. πŸ“

Table of Contents πŸ¦‹

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  2
2.  Evasion Techniques for Some RA-Guard Implementations . . . . .  3
  2.1.  Attack Vector Based on IPv6 Extension Headers  . . . . . .  3
  2.2.  Attack Vector Based on IPv6 Fragmentation  . . . . . . . .  4
3.  RA-Guard Implementation Advice . . . . . . . . . . . . . . . .  6
4.  Other Implications . . . . . . . . . . . . . . . . . . . . . .  9
5.  Security Considerations  . . . . . . . . . . . . . . . . . . .  9
6.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 10
7.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 10
  7.1.  Normative References . . . . . . . . . . . . . . . . . . . 10
  7.2.  Informative References . . . . . . . . . . . . . . . . . . 11
Appendix A.  Assessment Tools  . . . . . . . . . . . . . . . . . . 12

1. Introduction πŸ’…

okay so IPv6 Router Advertisement Guard (RA-Guard) is a mitigation technique for attack vectors based on ICMPv6 Router Advertisement [RFC4861] messages ✨. [RFC6104] describes the problem statement of "Rogue IPv6 Router Advertisements", and [RFC6105] specifies the "IPv6 Router Advertisement Guard" functionality πŸ“š.

The concept behind RA-Guard is that a Layer-2 (L2) device filters ICMPv6 Router Advertisement messages based on a bunch of different criteria 🧚. The most basic one is that Router Advertisement messages get discarded by the L2 device unless they show up on a specified port of that device πŸ”₯. So honestly, RA-Guard only works if the L2 device can actually spot ICMPv6 Router Advertisement messages in the first place πŸ‘‘.

Some popular RA-Guard implementations are easy to get around by using IPv6 Extension Headers [CPNI-IPv6] 😭. This doc describes those evasion techniques and gives advice to RA-Guard implementers so these evasion vectors can be eliminated πŸ’–.

It should be noted that these same techniques could also be used to dodge network monitoring tools like NDPMon [NDPMon], ramond [ramond], and rafixd [rafixd] πŸ™ˆ. They could probably also be used to pull off stealth DHCPv6 [RFC3315] attacks 🌸.

2. Evasion Techniques for Some RA-Guard Implementations πŸ¦‹

The following subsections describe two different vectors that have been found to work well for evading popular RA-Guard implementations πŸ”₯. Section 2.1 covers an attack vector that uses IPv6 Extension Headers with ICMPv6 Router Advertisement messages. It can be used to get past implementations that don't process the entire IPv6 header chain when trying to identify those messages πŸ™ˆ. Section 2.2 covers an attack method that uses IPv6 fragmentation, possibly together with IPv6 Extension Headers. This later vector has been found to work against all existing implementations of RA-Guard πŸ’€.

2.1. Attack Vector Based on IPv6 Extension Headers πŸŽ€

okay so there's currently no legit reason to put IPv6 Extension Headers on ICMPv6 Router Advertisement messages πŸ™…β€β™€οΈ. BUT Neighbor Discovery [RFC4861] implementations still let you include Extension Headers with these messages, because they just ignore the received options πŸ€·β€β™€οΈ. Some RA-Guard implementations try to spot ICMPv6 Router Advertisement messages by only looking at the "Next Header" field of the fixed IPv6 header, instead of following the whole header chain πŸ’€. So these implementations miss any ICMPv6 Router Advertisement message that has Extension Headers (like a Hop-by-Hop Options header, a Destination Options header, etc.), and that makes them super easy to circumvent 😭πŸ”₯.

Here's what an ICMPv6 Router Advertisement message using this evasion technique looks like πŸ‘€:

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |NH=60|       |NH=58|        |                                |
   +-+-+-+       +-+-+-+        +                                +
   | IPv6 Header |  Dst Opt Hdr |  ICMPv6 Router Advertisement   |
   +             +              +                                +
   |             |              |                                |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

see that NH=60 chain? the fixed header points at a Destination Options header, and that header points at ICMPv6 πŸ¦‹πŸ’œ

2.2. Attack Vector Based on IPv6 Fragmentation ✨

okay so this section is about a different attack vector, and it's giving main character energy πŸ’… It turns out it works against every implementation of RA-Guard 😭 The core trick: if the forged ICMPv6 Router Advertisement gets fragmented into at least two fragments, the L2 device running RA-Guard can't figure out what the packet is, so it doesn't block it πŸ™ˆ

The first variant is an original ICMPv6 Router Advertisement with a Destination Options header tucked in front of it, and that gets split into two fragments πŸŽ€ Here's the "original" attack packet before fragmentation, plus the two fragments that actually get sent:

    Original Packet:

       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |NH=60|       |NH=58|                           |           |
       +-+-+-+       +-+-+-+                           +           +
       | IPv6 Header |          Dst Opt Hdr            | ICMPv6 RA |
       +             +                                 +           +
       |             |                                 |           |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

       First Fragment:

       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |NH=44|       |NH=60|       |NH=58|                 |
       +-+-+-+       +-+-+-+       +-+-+-+                 +
       | IPv6 Header |   Frag Hdr  |      Dst Opt Hdr      |
       +             +             +                       +
       |             |             |                       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

       Second Fragment:

       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |NH=44|       |NH=60|       |             |           |
       +-+-+-+       +-+-+-+       +             +           +
       | IPv6 Header |   Frag Hdr  | Dst Opt Hdr | ICMPv6 RA |
       +             +             +             +           +
       |             |             |             |           |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

here's the catch πŸ‘€ the Hdr Ext Len field of the Destination Options header lives in the First Fragment (not the second). So a device that only looks at the second fragment has no idea how many bytes to "skip" to reach the next header after the Destination Options header, which means it can't find the ICMPv6 header sitting in there πŸ’€

so by combining the Fragment Header with the Destination Options header, the attacker can hide the type and contents of the ICMPv6 message he's sending (an ICMPv6 Router Advertisement, in this example) πŸ₯· Unless the L2 device does IPv6 fragment reassembly, it's literally impossible for it to tell what ICMPv6 type the message is.

An L2 device could still notice that some ICMPv6 message is being sent, though, because the Next Header field of the Destination Options header in the First Fragment is set to 58 (ICMPv6). πŸ‘€

and it gets even sneakier 😈 the attacker can make it impossible for the L2 device to even realize an ICMPv6 message is being sent at all. This works with an original ICMPv6 Router Advertisement preceded by two Destination Options headers, which again results in two fragments. Here's the "original" attack packet before fragmentation, and the two packets that actually get sent:

    Original Packet:

    +-+-+-+-+-+-+-+-+-+-+-+-//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |NH=60|         |NH=60|       |NH=58|       |           |
    +-+-+-+         +-+-+-+       +-+-+-+       +           +
    |  IPv6 header  | Dst Opt Hdr | Dst Opt Hdr | ICMPv6 RA |
    +               +             +             +           +
    |               |             |             |           |
    +-+-+-+-+-+-+-+-+-+-+-+-//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    First Fragment:

    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |NH=44|       |NH=60|       |NH=60|                   |
    +-+-+-+       +-+-+-+       +-+-+-+                   +
    | IPv6 header |   Frag Hdr  |       Dst Opt Hdr       |
    +             +             +                         +
    |             |             |                         |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    Second Fragment:

    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |NH=44|       |NH=60|       |           |NH=58|       |           |
    +-+-+-+       +-+-+-+       +           +-+-+-+       +           +
    | IPv6 header |   Frag Hdr  | Dst O Hdr | Dst Opt Hdr | ICMPv6 RA |
    +             +             +           +             +           +
    |             |             |           |             |           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

in this version the Next Header field of the Destination Options header in the First Fragment is set to 60 (Destination Options header) 🫣 So a device that only processes the First Fragment has no way to tell that an ICMPv6 message is being sent in the first place πŸ™ˆ

the second fragment has the same problem as the one in the previous variant. A device looking only at the second fragment can't locate the second Destination Options header (and therefore the ICMPv6 header), because the Hdr Ext Len field of the first Destination Options header is in the First Fragment instead 😭 it's a whole chain of hidden info, and I'm obsessed πŸ§šπŸ’œ

3. RA-Guard Implementation Advice ✨

okay so the following filtering rules MUST be implemented as part of an RA-Guard setup on ports facing interfaces that aren't allowed to send ICMPv6 Router Advertisement messages πŸ›‘οΈ. The goal is that the vulnerabilities in this doc get totally eliminated, no cap πŸ’…

  1. If the IPv6 Source Address of the packet is not a link-local address (fe80::/10), RA-Guard MUST pass the packet.

RATIONALE: this stops RA-Guard from wasting processing cycles on packets that came from off-net and that, even if they were RAs, the host wouldn't accept anyway πŸ™„ Section 6.1.2 of [RFC4861] says nodes have to discard Router Advertisement messages if their IPv6 Source Address isn't a link-local address.

  1. If the Hop Limit is not 255, RA-Guard MUST pass the packet.

RATIONALE: same energy as rule 1 🌸 It stops RA-Guard from burning cycles on off-net packets that the destination host would reject anyway if they were RAs. Section 6.1.2 of [RFC4861] says nodes have to discard Router Advertisement messages if their Hop Limit is not 255.

  1. RA-Guard MUST parse the entire IPv6 header chain present in the packet, so it can figure out whether the packet is a Router Advertisement message πŸ”

NOTE: RA-Guard implementations MUST NOT enforce a limit on how many bytes they inspect (counting from the start of the IPv6 packet). Why? Because that could cause false positives 😭 Legit packets could get dropped just because the device didn't parse the whole IPv6 header chain. An implementation that has a limit like that MUST NOT claim compliance with this spec, and it MUST pass the packet once that implementation-specific limit gets hit.

  1. When parsing the IPv6 header chain, if the packet is a First Fragment (basically a packet with a Fragment Header whose Fragment Offset is set to 0) and it doesn't contain the entire IPv6 header chain (all the headers from the IPv6 header up to and including the upper-layer header), RA-Guard MUST drop the packet and SHOULD log the packet drop event as a security fault, in an implementation-specific way 🚨

RATIONALE: [RFC7112] says the First Fragment (the one with Fragment Offset set to 0) MUST contain the entire IPv6 header chain, and it lets intermediate systems like routers drop packets that don't follow that rule πŸ’β€β™€οΈ

NOTE: this rule SHOULD only be applied to IPv6 fragments with a Fragment Offset of 0. Non-First Fragments can be safely passed, because they'll never reassemble into a complete datagram if they're part of a Router Advertisement received on a port where those packets aren't allowed πŸ¦‹

  1. When parsing the IPv6 header chain, if the packet is identified as an ICMPv6 Router Advertisement message, or the packet contains an unrecognized Next Header value [IANA-IP-PROTO], RA-Guard MUST drop the packet and SHOULD log the packet drop event as a security fault, in an implementation-specific way. RA-Guard MUST provide a configuration knob that controls whether packets with unrecognized Next Header values get dropped, and this configuration knob MUST default to "drop" ✨

RATIONALE: by definition, Router Advertisement messages are required to originate on-link, have a link-local IPv6 Source Address, and have a Hop Limit value of 255 [RFC4861]. [RFC7045] says nodes have to be configurable about whether packets with unrecognized headers get forwarded, and it allows the default to be that those packets get dropped 🌈

  1. In all other cases, RA-Guard MUST pass the packet as usual 🫢

NOTE: for enforcing the RA-Guard filtering policy, an Encapsulating Security Payload (ESP) header [RFC4303] SHOULD be considered an "upper-layer protocol" (meaning it should count as the last header in the IPv6 header chain). So packets using ESP get passed by the RA-Guard device on to the intended destination. If the destination host doesn't have a security association with the sender of that IPv6 packet, the packet gets dropped. Otherwise, if the packet is considered valid by the IPsec implementation on the receiving host and it encapsulates a Router Advertisement message, it's up to the receiving host what to do with it πŸ€·β€β™€οΈ

If a packet gets dropped because of this filtering policy, the packet drop event SHOULD be logged as a security fault, in an implementation-specific way. The logging mechanism SHOULD include a drop counter dedicated to RA-Guard packet drops πŸ“Š

To protect current end-node IPv6 implementations, Rule #4 is a default rule that drops packets which can't be positively identified as not being Router Advertisement (RA) messages, because they're fragments that don't include the entire IPv6 header chain πŸ›‘οΈ That means RA-Guard could, at least in theory, falsely block some legit non-RA packets that couldn't be positively identified as non-RA. To lower the odds of false positives, Rule #1 and Rule #2 say packets that would fail the required validation checks for RA messages (Section 6.1.2 of [RFC4861]) get passed without further inspection. Either way, as [RFC7112] notes, IPv6 packets that don't include the entire IPv6 header chain are basically impossible to police with stateless filters and firewalls, so they're unlikely to survive in real networks πŸ’€ [RFC7112] also requires that hosts using fragmentation include the entire IPv6 header chain in the First Fragment (the one with Fragment Offset set to 0), which gets rid of those false positives.

This filtering policy assumes that host implementations require the IPv6 Source Address of ICMPv6 Router Advertisement messages to be a link-local address, and that they discard the packet if that check fails, as the current IETF specs require [RFC4861]. It also assumes hosts require the Hop Limit of Neighbor Discovery messages to be 255, and that they discard those packets otherwise πŸŽ€

The rules above already handle fragmented packets implicitly: if the RA-Guard device can't identify the upper-layer protocol because of fragmentation, those packets get dropped 🧚

Last thing: IPv6 implementations that allow overlapping fragments (so they don't comply with [RFC5722]) might still be subject to RA-based attacks. However, a recent assessment of IPv6 implementations [SI6-FRAG] on their fragment reassembly policy seems to show that most current implementations do comply with [RFC5722] πŸ‘‘

4. Other Implications 🌷

A similar concept to RA-Guard has been implemented to protect against forged DHCPv6 messages. That protection can be evaded with the same techniques discussed in this document, and the countermeasures for that evasion attack are analogous to the ones described in Section 3 of this document πŸ¦‹

[DHCPv6-Shield] specifies a mechanism to protect against rogue DHCPv6 servers, while taking into consideration the evasion techniques discussed in this document πŸ’œ

5. Security Considerations 🚨

This document describes a number of techniques that have been found to be effective at circumventing popular RA-Guard implementations, and it gives advice to RA-Guard implementers so those evasion vulnerabilities get eliminated 😀

As noted in Section 3, IPv6 implementations that allow overlapping fragments (so they don't comply with [RFC5722]) might still be subject to RA-based attacks. However, most current implementations seem to comply with [RFC5722] 🌸

We note that if an attacker sends a fragmented ICMPv6 Router Advertisement message on a port that isn't allowed to send such packets, the First Fragment gets dropped while the rest of the fragments get passed. That means the victim node would tie up memory buffers for those fragments, which would never reassemble into a complete datagram 😱 If an attacker sent a large number of these packets, and the victim node didn't implement proper resource management for the IPv6 fragment reassembly buffer, this could lead to a Denial of Service (DoS). BUT this doesn't really introduce a new attack vector, since an attacker could always do the same thing by sending forged fragmented datagrams where at least one of the fragments is missing. [CPNI-IPv6] discusses some resource management strategies that could be implemented for the IPv6 fragment reassembly buffer 🧠

We note that the most effective and efficient mitigation for these attacks would rely on prohibiting the use of IPv6 fragmentation with Router Advertisement messages (as specified by [RFC6980]), which would make RA-Guard functionality easier to implement. However, since that mitigation would require an update to existing implementations, it can't be relied on in the short or near term πŸ₯²

Finally, we note that RA-Guard only mitigates attack vectors based on ICMPv6 Router advertisement messages. Protection against similar attacks based on other messages (such as DCHPv6) is considered out of scope for this document and is left to other documents (e.g., [DHCPv6-Shield]) πŸ’…

6. Acknowledgements 🫢

The author would like to thank Ran Atkinson, who provided very detailed comments and suggested text that got incorporated into this document πŸ’–

The author would like to thank Ran Atkinson, Karl Auer, Robert Downie, Washam Fan, David Farmer, Mike Heard, Marc Heuse, Nick Hilliard, Ray Hunter, Joel Jaeggli, Simon Perreault, Arturo Servin, Gunter van de Velde, James Woodyatt, and Bjoern A. Zeeb, for providing valuable comments on earlier versions of this document 🌈

The author would like to thank Arturo Servin, who presented this document at IETF 81 🎀

This document resulted from the project "Security Assessment of the Internet Protocol version 6 (IPv6)" [CPNI-IPv6], carried out by Fernando Gont on behalf of the UK Centre for the Protection of National Infrastructure (CPNI) ✨

7. References πŸ“š

7.1. Normative References ✨

okay bestie, these are the homework you NEED to have open before any of this makes sense πŸ“šπŸ«Ά

  • [RFC3315] Droms, R., Bound, J., Volz, B., Lemon, T., Perkins, C., and M. Carney, "Dynamic Host Configuration Protocol for IPv6 (DHCPv6)", RFC 3315, July 2003.
  • [RFC4303] Kent, S., "IP Encapsulating Security Payload (ESP)", RFC 4303, December 2005.
  • [RFC4861] Narten, T., Nordmark, E., Simpson, W., and H. Soliman, "Neighbor Discovery for IP version 6 (IPv6)", RFC 4861, September 2007.
  • [RFC5722] Krishnan, S., "Handling of Overlapping IPv6 Fragments", RFC 5722, December 2009.
  • [RFC6105] Levy-Abegnoli, E., Van de Velde, G., Popoviciu, C., and J. Mohacsi, "IPv6 Router Advertisement Guard", RFC 6105, February 2011.
  • [RFC6980] Gont, F., "Security Implications of IPv6 Fragmentation with IPv6 Neighbor Discovery", RFC 6980, August 2013.
  • [RFC7045] Carpenter, B. and S. Jiang, "Transmission and Processing of IPv6 Extension Headers", RFC 7045, December 2013.
  • [RFC7112] Gont, F., Manral, V., and R. Bonica, "Implications of Oversized IPv6 Header Chains", RFC 7112, January 2014.

7.2. Informative References 🧠

these ones are the extra reading for when you want the full tea β˜•πŸ’…

Appendix A. Assessment Tools 🧰

[SI6-IPv6] is a publicly available toolkit (for Linux, *BSD, and Mac OS) that puts the techniques from this document into practice. πŸ”₯

[THC-IPV6] is a publicly available toolkit (for Linux) that covers some of the techniques from this document. πŸ’œ

Author's Address πŸŽ€

Fernando Gont
Huawei Technologies
Evaristo Carriego 2644
Haedo, Provincia de Buenos Aires  1706
Argentina

Phone: +54 11 4650 8472
EMail: fgont@si6networks.com
πŸ“¦ where this page comes from