Adventures in IPv6 – Cisco, Comcast, and Debian

September 3, 2014 | Comments Off

I recently got motivated to deploy IPv6 at home. I’ve been meaning to do this for a while but everytime I checked the Comcast documentation was vague as to whether it was available in my area. Finally, Comcast announced they had rolled out dual-stack IPv6 across the country and I couldn’t make excuses anymore. Unfortunately, in the meantime all of the Comcast IPv6 pages also happened to stop working. Nearly any Comcast page in the Google index relating to IPv6 details just redirected me to

Let’s just dig into the details. Here’s how I got mine to work, your mileage may vary.

Cisco Configuration

I run a Cisco 800-series router as my internet gateway. The Internet comes in on interface FastEthernet8. Here’s the configuration I have, along with some commentary on what why and how.

WAN (Comcast) interface

interface FastEthernet8
  description Comcast Cable Modem
  ip dhcp client client-id ascii whiteoak
  ip address dhcp
  ip flow ingress
  ip nat outside
  ip virtual-reassembly in
  duplex auto
  speed auto

! everything above this line was configure prior to ipv6
  ipv6 enable
  ipv6 address dhcp
  ipv6 nd ra suppress
! "default" was needed to install the IPv6 default-route into the router
  ipv6 address autoconfig default

! This requests a prefix-delegation, so we get our own prefix from which to assign addresses
! This part is tricky, in my case I named that prefix "comcast-ipv6" this is important because we'll use 
! this named prefix in other sections of the code
  ipv6 dhcp client pd comcast-ipv6 rapid-commit
  ipv6 dhcp client request vendor

! This is supposed to prevent source spoofing from the WAN, verifies that the 
! source address is reachable via that interface
  ipv6 verify unicast source reachable-via rx allow-default 

! These two traffic filters are to prevent traffic from reaching directly into the inside hosts,
! since they will have globally routable IPs
  ipv6 traffic-filter wan-in in
  ipv6 traffic-filter wan-out out

I initially did this without the traffic-filter on the interface, and I suggest you do the same. First get it working, then lock it down. This is just the final configuration I ended up with. I’ll expand on the access-list’s further down.

I also set these couple of parameters in the global scope:

ipv6 unicast-routing
ipv6 cef
ipv6 cef accounting per-prefix

With those options set, I started getting IPs and prefix’s from Comcast. Here’s an example of what “sh ipv6 dhcp int” returns:

FastEthernet8 is in client mode
  Prefix State is OPEN
  Renew will be sent in 15:29:49
  Address State is OPEN
  Renew for address will be sent in 15:29:50
  List of known servers:
    Reachable via address: FE80::201:5CFF:FE33:401
    DUID: 0001000117C5C79C14FEB5D78385
    Preference: 255
    Configuration parameters:
      IA PD: IA ID 0x00030001, T1 129598, T2 207357
        Prefix: 2601:abcd:abcd:25B::/64
                preferred lifetime 259197, valid lifetime 259197
                expires at Sep 06 2014 04:07 PM (228585 seconds)
      IA NA: IA ID 0x00030001, T1 172800, T2 276480
        Address: 2001:1234:1234:31:486:112A:BEEC:5A6F/128
                preferred lifetime 345600, valid lifetime 345600
                expires at Sep 06 2014 04:07 PM (228586 seconds)
      DNS server: 2001:558:FEED::1
      DNS server: 2001:558:FEED::2
      Information refresh time: 0
  Prefix name: comcast-ipv6
  Prefix Rapid-Commit: enabled
  Address Rapid-Commit: disabled

You can see the “IA PD” (prefix delegation)” and “IA NA” (non-temporary address).

LAN interface

The next step was to figure out the LAN side of the equation. On the Cisco I use Vlan1 for the Ethernet ports, but I issue DHCP (IPv4) from a Debian server. I started doing the research on this (See the link below) but  it turned out to be completely unnecessary. To my understanding, the router does a route announcement (RA) on the LAN (once configured on the Vlan1 interface) and everything auto-configured itself accordingly. Here’s what the Vlan1 interface looks like:

interface Vlan1
 description Main LAN
 ip address
 ip nat inside
 ip virtual-reassembly in
# Again, everything above this line was already configure prior to my IPv6 attempts

# This assigns ourselves a static IP from the delegated prefix we get form Comcast
# This comcast-ipv6 matches the dhcp option I used on FastEthernet8
 ipv6 address comcast-ipv6 ::1:0:0:5/64
# nd stands for "neighbor discovery"
 ipv6 nd autoconfig prefix
 ipv6 nd autoconfig default-route
 ipv6 nd other-config-flag

At this point in the configuration the Mac’s on my network started working automatically, which is pretty cool. By default, the Mac’s configure a permanent global address using the MAC address of the interface as a template, but they also create a daily temporary IPv6 address that they use for outgoing connections. This address gets rotated daily and kept for about 7 days.

Debian server

The Debian server similarly auto-assigned itself an IPv6 address based on it’s MAC address (this is called an EUI-64, by the way). That left me with two challenges:

  1. Like on the Cisco router, I wanted to assign the Debian box a “vanity” IPv6 address that would be more easily remembered
  2. I wanted the Debian box to also use temporary IPv6 addresses by default.

The gotcha with #1 is that it has to inherit the delegated prefix from the router. It correctly inherits the prefix for the automatic addresses, but I can’t figure out how to do the same for a static address. I haven’t found a solution to this problem yet.

As for the temporary address, a friendly SuperUser site member answered the question.

# echo "2" > /proc/sys/net/ipv6/conf/eth0/use_tempaddr

Security considerations

At this point the machines on my network had globally routable IPv6 addresses, which meant you could access them directly from the internet without having to do port mapping or static DNATs inbound. But of course that was very risky. Here is the Cisco ACLs I ended up with (applied on FastEthernet8 interface above):

ipv6 access-list wan-in
 permit icmp any any
 evaluate reflectout
# These two ports are opened for DHCP to work 
 permit udp any any eq 546
 permit udp any any eq 547
 permit tcp any host 2601:abcd:abcd:25B:1::5 eq 22
# These allow inbound ssh and http traffic to some of the previously NAT'd hosts
 permit tcp any host 2601:abcd:abcd:25B:DEAD:BEFF:FEEF:CAFE eq 22
 sequence 70 permit tcp any host 2601:abcd:abcd:25B:3E07:54FF:FE04:84FC eq www
# Outbound access-list is not so interesting.
ipv6 access-list wan-out
 permit icmp any any
 permit tcp any any reflect reflectout
 permit udp any any reflect reflectout

Finally to test all of this I used a shell account on a Digital Ocean VM ($0.007 per hour) because they support IPv6 natively. From there I was able to externally probe the network and make sure things were working as intended.

Additional resources

Resources I used along the way:

  1. Kyle Manna’s blog post was the first really useful link I found (more than Cisco deployment guide). It pointed me in the right direction for a lot of other research
  2. Cisco IPv6 deployment guide
  3. This DSLReports forum post gave a decent starting point for ACLs
  4. Hurricane Electric’s IPv6 certification was useful in helping me verify my progress and kept going to the next step.

Update 2016/08/03:

I found an issue with my configuration that breaks modern cablemodems (at least on Comcast). As a result I’ve update my configuration above with the fix. I also update the configuration to use “!” comments instead of “#” comments since that’s syntactically correct for Cisco configuration.

No Comments yet

Sorry, the comment form is closed at this time.