IPv6 Access Lists on IOS
By stretch | Wednesday, June 30, 2010 at 3:05 a.m. UTC
If you've worked with IPv4 access lists (ACLs) on Cisco IOS before, IPv6 ACLs will feel quite familiar to you. However, there are a few caveats you'll need to be aware of, which this article explores.
The following topology shows two subnets connected by a dual-stack router, configured to route both IPv4 and IPv6 traffic in parallel.
We'll work through several examples of common traffic filtering practices, first demonstrating how each is accomplished in IPv4, and then in IPv6.
Denying a Subnet
If we want to prevent subnet A from reaching subnet B over IPv4, we can define and apply a standard ACL on the router's FastEthernet0/1 interface in the outbound direction:
interface FastEthernet0/1 ip access-group Deny_Subnet_A_IPv4 out ! ip access-list standard Deny_Subnet_A_IPv4 deny 192.168.12.0 0.0.0.255 permit any
Here exists the first major difference we notice between IPv4 and IPv6 ACLs: IPv6 supports only extended ACLs. We cannot create a standard (source-only) IPv6 ACL. IPv6 also only supports named (versus numbered) ACLs.
Router(config)# ipv6 access-list ? WORD User selected string identifying this access list log-update Control access list log updates
Because IPv6 ACLs are supported in extended form only, remember that we'll always need to specify both a source and a destination in each entry (even if one or both are "any").
Now, you might assume that, because IPv6 addresses are so much longer than IPv4 addresses and because ACL wildcards are relatively confusing, defining an IPv6 ACL entry (ACE) must be a burden. Actually, it can be quite simpler than an IPv4 ACE. Here's our ACE to block subnet A for IPv6:
Router(config-ipv6-acl)# deny ipv6 2001:db8:0:12::/64 any
Here we notice a second substantial difference from IPv4: no wildcard masking. We can simply define our source IPv6 subnet in CIDR notation, and append a destination of "any". Because the logic of IPv6 ACLs remains unchanged from IPv4, don't forget to add a final entry,
permit ipv6 any any, to allow all unmatched traffic.
With our IPv6 ACL completed, we just need to apply it to an interface. There is a minor difference in syntax here: instead of using the command
ip access-group to apply our IPv6 ACL, we use the more aptly named command
ipv6 traffic-filter, followed by the ACL name and a direction (in this case, "out").
Our final IPv6 ACL configuration looks like this:
interface FastEthernet0/1 ipv6 traffic-filter Deny_Subnet_A_IPv6 out ! ipv6 access-list Deny_Subnet_A_IPv6 deny ipv6 2001:DB8:0:12::/64 any permit ipv6 any any
Denying Specific Hosts
Just as with IPv4, we can use the
host keyword to match specific IPv6 host addresses (effectively a /128 mask):
ip access-list extended Deny_Host_A_to_B_IPv4 deny ip host 192.168.12.77 host 192.168.23.203 permit ip any any
ipv6 access-list Deny_Host_A_to_B_IPv6 deny ipv6 host 2001:DB8:0:12::4D host 2001:DB8:0:23::CB permit ipv6 any any
Limiting Access to VTY Lines
A recommended security practice is to apply an ACL to your router's remote administration interfaces (e.g. VTY lines) and allow only authorized hosts to connect to the router. Under IPv4, this is performed under line configuration using the
access-class command followed by an IPv4 ACL number or name, and a direction (typically "in"). IPv6 uses the similar command
ipv6 access-class, followed by an IPv6 ACL name and a direction.
line vty 0 15 access-class Authorized_IPv4_Hosts in ipv6 access-class Authorized_IPv6_Hosts in
Matching Upper Layer Protocols
One detail that is important to remember about IPv6 is that IPsec's authentication header (AH) may be present even on non-encrypted packets. When AH is used, the router must look beyond it to find the next encapsulated protocol (e.g. TCP or UDP). IOS provides a simple feature called IPv6 ACL Extensions for IPsec Authentication Header to support this:
This feature provides the ability to match on the upper layer protocol (ULP) ... regardless of whether an authentication header (AH) is present or absent. TCP or UDP traffic can be matched to the upper-layer protocol (ULP) (for example, TCP, UDP, ICMP, SCTP) if an AH is present or absent. Before this feature was introduced, this function was only available if an AH was absent.
This feature introduces the keyword auth to the permit and deny commands. The auth keyword allows matching traffic against the presence of the authentication header in combination with the specified protocol; that is, TCP or UDP. IPv6 traffic can be matched to a ULP when an AH header is present. To perform this function, enter the ahp option for the protocol argument when using the permit or deny command.
Note that this feature is not available on all platforms; Cisco's Feature Navigator shows that it is available only on first-generation ISR routers and later. Be aware that on unsupported platforms, IPv6 ACLs cannot see beyond the AH header.
The syntax for matching an upper layer IPv6 protocol remains essentially the same as with IPv4:
ip access-list extended Deny_TCP_80_IPv4 deny tcp any any eq www permit ip any any
ipv6 access-list Deny_TCP_80_IPv6 deny tcp any any eq www permit ipv6 any any
There are undoubtedly more differences we haven't covered here, but these should be the most prominent. To review:
- IPv6 supports only named, extended access lists.
- IPv6 ACE addresses use CIDR notation instead of wildcard masks.
- IPv6 ACLs are applied to interfaces using the command
- IPv6 ACLs are applied to lines using the command
- Older routers may not be able to reliably match upper layer protocols in IPv6 packets containing an IPsec authentication header (AH).
Please feel free to contribute any noteworthy omissions in the comments.
Posted in IPv6
June 30, 2010 at 12:05 p.m. UTC
Thanks for sharing, great post on IPV6.
July 1, 2010 at 2:05 p.m. UTC
Very nice post about the migration between IpV4 and IPv6. Thanks for sharing.
July 2, 2010 at 5:35 p.m. UTC
Nice article as always, thanks.
One other gotcha with IPv6 ACLs on some platforms is that there may be restrictions on what address length can be matched in an ACL entry, caused by TCAM memory space limitations. This feature is called "IPv6 Address Compression", and sometimes the device can be (globally) configured for different modes depending on what you want.
Here's the documentation for 6500 platform SXH:
July 2, 2010 at 10:24 p.m. UTC
good article, In v4 we're all used to the 'deny any any' by default at the end of the acl. In v6 this becomes,
permit icmp any any nd-na permit icmp any any nd-ns deny ipv6 any any
(so says cisco's docs, I've never personally verified it. I assume they've done this because this icmp neighbor discovery traffic is so critical when using ipv6?)
July 5, 2010 at 3:22 p.m. UTC
Maybe slight off topic, but I have one question. What is the point of mask in ipv6 if host is always 64 bits? Can mask be bigger then 64?
July 6, 2010 at 8:57 a.m. UTC
Really kind of you to share this :o)
July 7, 2010 at 2:32 p.m. UTC
IPv6 masks can be longer than 64 bits. A common scenario is the equivalent of the IPv4 /30 "point to point" link, which some ISPs have as /112 or similar in IPv6.
You are probably most familiar with seeing 64 bit masks used with EUI-64 format IPv6 addresses but this is simply one common configuration, not a requirement.
July 13, 2010 at 2:33 p.m. UTC
@oliver thanks, i guess most i misunderstood docs I read. It is perfectly reasonable :)
March 17, 2011 at 6:07 p.m. UTC
We have a dual-stack interface and want to count L3 traffic separately (IPv4 and IPv6).
Is there a way to do this?
We thought about creating an access-list to permit any on v4 and any on v6, but we were not able to find a way to get the traffic count via SNMP.
November 28, 2011 at 8:04 p.m. UTC
Any support in IPv6 access-lists for re-sequencing line numbers?
March 27, 2013 at 7:27 a.m. UTC
thank you. it helped :)
July 14, 2014 at 12:00 p.m. UTC
Thank you so much, this is so useful. But I have one question that can I filter a network and it won't appear on ipv6 routing table by using ipv6 access-list and traffic-filter? I did an ipv6 filtering lab, I see after filtering, I couldn't ping the network I filtered but still found it on routing table.