Building

Configuring IPv6 Snooping and DHCPv6 Guard on Cisco IOS

Hi everyone,

Some of you may already know (the ones who are following Enno on Twitter) that Enno and I had our lab day in preparation for the IPv6 Security Summit at Troopers.  We had a brand new and shiny Cat4948E as our lab device to do some testing of the current generation of Cisco’s IPv6 First Hop Security (FHS) mechanisms. The Catalyst was running the latest image available (15.1(2)SG3).

In this small blog post, we will take a look at the configuration and behavior of IPv6 Snooping and DHCPv6 Guard. So let’s start with IPv6 Snooping:

IPv6 Snooping is not a security feature per se. It builds a database table of IPv6 neighbors connected to the device created from information sources such as NDP snooping or DHCPv6. This database, or binding table, is used by various IPv6 FHS features to validate the link-layer address (LLA), the IPv6 address, and the prefix binding of the neighbors to prevent spoofing and redirect attacks. This binding table will get automatically populated once IPv6 Snooping is enabled. The following output shows a sample content of this binding table:

Switch#show ipv6 neighbors binding
Binding Table has 4 entries, 4 dynamic
Codes: L - Local, S - Static, ND - Neighbor Discovery, DH - DHCP, PKT - Other Packet, API - API created
IPv6 address                            Link-Layer addr Interface vlan prlvl  age   state    Time left
ND  FE80::81E2:1562:E5A0:43EE               28D2.4448.E276  Gi1/15       1  0005    3mn REACHABLE  94 s
ND  FE80::3AEA:A7FF:FE85:C926               38EA.A785.C926  Gi1/2        1  0005   26mn STALE      86999 s
ND  FE80::10                                38EA.A785.C926  Gi1/2        1  0005   26mn STALE      85533 s
ND  FE80::1                                 E4C7.228B.F180  Gi1/7        1  0005   35s  REACHABLE  272 s

As we can see, the binding table has four entries beginning with “ND”, which means these associations were learned from snooping NDP packets. When a new entry gets into the database, the following log message is generated on the switch (when “IPv6 snooping logging” is enabled):

%SISF-6-ENTRY_CREATED: Entry created A=2001:DB8:1:0:C04D:ABA:A783:2FBE V=1 I=Gi1/15 P=0024 M=28D2.4448.E276

IPv6 Snooping can be enabled (either for a specific port or for a VLAN) with the following command:

Switch(config)#vlan configuration 1
Switch(config-vlan-config)#ipv6 snooping

We enabled IPv6 Snooping in the above example for VLAN 1.

Beware: Shortly after we activated IPv6 Snooping, we have seen several log messages indicating that all DHCPv6 server packets (Advertise and Reply) were filtered by the switch. So it is advised to not just activate IPv6 Snooping (without any additional configuration steps, see below) on production devices, as this can break IPv6 connectivity 😉

%SISF-4-PAK_DROP: Message dropped A=FE80::1 G=2001:DB8:1:0:1146:8DF:1E2F:E079 V=1 I=Gi1/1 
P=DHCPv6::ADV Reason=Packet not authorized on port

The same behavior was observed for the router advertisements from our (legitimate) router:

%SISF-4-PAK_DROP: Message dropped A=FE80::1 G=- V=1 I=Gi1/1 P=NDP::RA Reason=Packet not authorized on port

Unicast traffic between hosts connected to the switch was not affected and working as expected. At first it didn’t make much sense. Why does the Snooping feature (which should just build the binding table) filter the above types of packets?

After some discussion it became clear: IPv6 Snooping is tightly integrated in the various IPv6 guard features (e.g. DHCPv6 guard and RA guard) as explained above. In order to allow those packets, you have to configure e.g. DHCPv6 guard so that the switch knows these DHCPv6 packets are legitimate and must not be filtered. To prove our theory, we continued to configure DHCPv6 guard on the switch. The complete configuration for DHCPv6 guard is done with the following commands (if one wants to use DHCPv6 Guard _only_, without IPv6 Snooping, the config is much simpler. See a future blog post):

Switch(config)#ipv6 access-list dhcpv6_server
Switch(config-ipv6-acl)#permit host FE80::1 any
Switch(config)#ipv6 prefix-list dhcpv6_prefix permit 2001:DB8:1::/64 le 128
Switch(config)#ipv6 dhcp guard policy dhcpv6guard_pol
Switch(config-dhcp-guard)#device-role server
Switch(config-dhcp-guard)#match server access-list dhcpv6_server
Switch(config-dhcp-guard)#match reply prefix-list dhcpv6_prefix
Switch(config)#vlan configuration 1
Switch(config-vlan-config)#ipv6 dhcp guard attach-policy dhcpv6guard_pol

Essentially, the above configuration instructs the switch that DHCPv6 packets from FE80::1 (specified in the ACL) with a prefix of 2001:db8:1::/64 (specified in the prefix-list) shall not be dropped. We combine these “elements” in a DHCPv6 guard policy which is then bound to VLAN 1. After the configuration was done, DHCPv6 was working again as intended and the DHCPv6 addresses got populated in the binding table indicated by the following log message:

%SISF-6-ENTRY_CREATED: Entry created A=2001:DB8:1:0:BCC1:41C0:D904:E1B9 V=1 I=Gi1/15 P=0024 M=28D2.4448.E276

Looking into the binding table again, the (DHCPv6 originated) IPv6 address now appeared:

Switch#show ipv6 neighbors binding
Binding Table has 6 entries, 6 dynamic
Codes: L - Local, S - Static, ND - Neighbor Discovery, DH - DHCP, PKT - Other Packet, API - API created
Preflevel flags (prlvl):
0001:MAC and LLA match     0002:Orig trunk            0004:Orig access
0008:Orig trusted trunk    0010:Orig trusted access   0020:DHCP assigned
0040:Cga authenticated     0080:Cert authenticated    0100:Statically assigned
IPv6 address                            Link-Layer addr Interface vlan prlvl  age   state    Time left
ND  FE80::81E2:1562:E5A0:43EE               28D2.4448.E276  Gi1/15       1  0005    3mn REACHABLE  94 s
ND  FE80::3AEA:A7FF:FE85:C926               38EA.A785.C926  Gi1/2        1  0005   26mn STALE      86999 s
ND  FE80::10                                38EA.A785.C926  Gi1/2        1  0005   26mn STALE      85533 s
ND  FE80::1                                 E4C7.228B.F180  Gi1/7        1  0005   35s  REACHABLE  272 s
DH  2001:DB8:1:0:BCC1:41C0:D904:E1B9        28D2.4448.E276  Gi1/15       1  0024    3mn REACHABLE  87 s(166161s

We now see a new entry starting with “DH”, indicating that this binding was learned by snooping the DHCPv6 packet.

Now that DHCPv6 is working again, we have to configure a RA guard policy to allow the router advertisements of our legitimate router. To be fair, for this policy I took the lazy route and just configured that the port (where our router is connected) is a so called “trusted port” which means RAs are allowed regardless of the configuration in the policy and bound it to interface g1/1. More on the RA guard policies in a future blogpost.

Switch(config)#ipv6 nd raguard policy ra_pol
Switch(config-nd-raguard)#device-role router
Switch(config-nd-raguard)#trusted-port
Switch(config-nd-raguard)#exit
Switch(config)#int g1/1
Switch(config-if)#ipv6 nd raguard attach-policy ra_pol

After the configuration was applied to g1/1, RAs are not dropped anymore by the switch

That’s it for the time being. Today we will have a look at more of those features and will probably write another blog post about it. So stayed tuned!

What to know more about securing IPv6 networks?  Then you should definitely come to Heidelberg for the IPv6 Security Summit and Troopers with an awesome lineup of quality speaker and talks. Early Bird is available until 31st January. Looking forward to see in Heidelberg!

Have a great day everybody!

Cheers,

Chris

Comments

  1. Hello Chris,

    you wondered why activating IPv6 snooping causes DHCPv6 server messages and RA to be dropped, because your expectation was that IPv6 snooping should just build the bindung table.

    This seems not to be true: You activated IPv6 snooping in VLAN feature configuration mode for VLAN 1 by just using the command “ipv6 snooping” without specifying a specific policy (via the optional [attach-policy policy-name] part of the command). Hence, a default IPv6 snooping policy applies, which uses the default setting “security-level guard”, see for example http://www.cisco.com/c/en/us/td/docs/switches/lan/catalyst2960x/software/15-0_2_EX/security/configuration_guide/b_sec_152ex_2960-x_cg/b_sec_152ex_2960-x_cg_chapter_010011.html#task_7886681DE3FC4B79909F0E5968273AE2 for a detailed explanation.

    As you can see from the definition of “guard” (Gleans addresses and inspects messages. In addition, it rejects RA and DHCP server messages. This is the default option.), it explains the observed behaviour.

    You also stated: “IPv6 Snooping is tightly integrated in the various IPv6 guard features (e.g. DHCPv6 guard and RA guard) as explained above.” While this is true in general you unfortunately just picked the two exceptions from this general rule: For DHCPv6 guard and RA guard this is not true, because both features are operating independent from IPv6 snooping and don’t rely on the binding table, which is only needed for other IPv6 FHS features like source guard, destination guard, IPv6 device tracking or optimization features like RA throttler or ND multicast suppress.

    Andreas

Leave a Reply

Your email address will not be published.