IPv6 Address Planning

Often I find people are hesitant to implement IPv6 because they are intimidated by the subnet planning process and therefore find it hard to get started.  In this post, I will attempt to identify some different approaches to address planning, and when it’s best to use them, as well as some best practices for allocating networks.

First off, “… to reduce the likelihood of conflict and confusion when relating documented examples to deployed systems, an IPv6 unicast address prefix is reserved for use in examples in RFCs, books, documentation, and the like. Since site-local and link-local unicast addresses have special meaning in IPv6, these addresses cannot be used in many example situations.”  See RFC 3849 for further details. Following this RFC, we will be utilizing space within the 2001:DB8::/32 for this example.

Most small sites will be able to easily obtain a /48 IPv6 network from their regional registry or a tunnel broker such as Hurricane Electric.  In this example we’ll be using 2001:DB8:1::/48 as our base supernet.  When subnetting IPv6 address blocks, it’s best to do on the 4-bit (nibble) boundaries as it makes it easier for a human to identify, plus many router’s ASICs are optimized to forward traffic this way. Generally speaking, each VLAN should be assigned a /64 allocation.  This allows for StateLess Auto-Address Configuration (SLAAC) to automatically assign addresses and to advertise available routers on the network without the use of DHCPv6.  As your network grows, your VLAN will never run out of addresses again, ever.  Traditionally IPv4 point-to-point links would utilize a /30 or /31 IPv4 subnet to make more efficient use of the space.  In IPv6 land, conservation is not needed.  Point-to-points should have an entire /64 allocated, but be configured with a /126 or /127 mask for good measure.  This prevents SLAAC from accidentally occurring.  There are many debates and opinions on this matter but within the IPv6 community, the above is generally agreed upon as best practice. 

Depending on the site’s size and requirements, there are two main ways to develop an  addressing plan:

  • Routing table optimized:  Utilizes routing summarization to decrease the size of the routing table
  • Access list optimized:  Allocates blocks to individual groups/departments regardless of their logical location on the network

Let’s cover both of these methods with practical examples.    Suppose we have a campus with approximately 50-100 buildings that is broken up into several distinct areas separated by layer 3 boundaries.  Each area has 50-100 individual VLANs that may or may not span between buildings within that region.  Each area shares the same 3-digit VLAN IDs, even though they are separated by Layer 3, which allows for easier policy enforcement for network access.  This example assumes a mobile or disperse working environment, where a department may be staffed from various locations/buildings around the campus.

Routing Optimized

First we’ll look at the routing table optimized plan.  Our allocated block of 2001:db8:1::/48 can be subnetted into 16  x /52 subnets, each of which can have 4,096 x /64 networks.  This design allows for plenty of growth with up to 16 regions, while also making the addresses easier to identify by embedding the region number along with the VLAN ID into the address.  If you are using 4-digit VLANs, you’ll likely have a much larger network, in which case, a /48 may not be enough.  If this is a requirement, get a /32 and then use 16 bits of the address to embed your 4-digit base-10 VLAN ID.  Below is a sample plan for our 4-region network:

RegionVLAN
IPv6
North Area
2001:DB8:1:1000::/52
loopbacks2001:DB8:1:1000::/64

101
2001:DB8:1:1101::/64

102
2001:DB8:1:102::/64

1032001:DB8:1:1103::/64
9992001:DB8:1:1999::/64
South Area2001:DB8:1:2000::/52
loopbacks2001:DB8:1:2000::/64
1012001:DB8:1:2101::/64
1022001:DB8:1:2102::/64
1032001:DB8:1:2103::/64
9992001:DB8:1:2999::/64
East Area2001:DB8:1:3000::/52
loopbacks2001:DB8:1:3000::/64
1012001:DB8:1:3101::/64
1022001:DB8:1:3102::/64
1032001:DB8:1:3103::/64
9992001:DB8:1:3999::/64
West Area2001:DB8:1:4000::/52
loopbacks2001:DB8:1:4000::/64
1012001:DB8:1:4101::/64
1022001:DB8:1:4102::/64
1032001:DB8:1:4103::/64
9992001:DB8:1:4999::/64

ACL Optimized

Using the same campus scenario, we can build a plan that optimizes address allocation for Access Control Lists (ACLs) simplification.  This has the drawback of dramatically increasing the size of the routing table; however, we can greatly reduce the potential number of firewall policies by assigning blocks to an individual department.  Our allocated block of 2001:db8:1::/48 can be subnetted into 4,096 x /60 subnets, each of which can have 16 x /64 networks.  This allows each group or department to have a /60 dedicated to them, so firewall policies can be more easily built permitting/denying interdepartmental traffic.  Again, we are also making the addresses easier to identify by embedding the region number along with the VLAN ID into the address, only in a different order. Up to 16 different regions/areas could be allocated for each group/department, allowing this method to scale well passed our 4-region environment. 

DepartmentVLANRegionIPv6
12001:db8:1:1010::/60
101North2001:db8:1:1011::/64
101South2001:db8:1:1012::/64
101East2001:db8:1:1013::/64
101West2001:db8:1:1014::/64
22001:db8:1:1020::/60
102North2001:db8:1:1021::/64
102South2001:db8:1:1022::/64
102East2001:db8:1:1023::/64
102West2001:db8:1:1024::/64
3
2001:db8:1:1030::/60
103North2001:db8:1:1031::/64
103South2001:db8:1:1032::/64
103East2001:db8:1:1033::/64
103West2001:db8:1:1034::/64
1992001:db8:1:1990::/60
199North2001:db8:1:1991::/64
199South2001:db8:1:1992::/64
199East2001:db8:1:1993::/64
199West2001:db8:1:1994::/64

Infrastructure

Let’s not forget, all of your network infrastructure will also require allocations for loopbacks, point-to-points, and management.  I like to block off the first and last bunch of networks in each major allocation for this purpose.  You may have noticed, with our 2001:db8:1::/48, that we didn’t start using the first available addresses.  

Documentation

You know, that thing everyone wants but nobody does?  I still see people using  spreadsheets to keep track of address allocations.  Even something is better than nothing in this case; however, the open source software phpIPAM is an excellent address management tool and is very customizable to your environment.  It take a lot of the guess work out of subnetting and gives you a clearer picture on how your allocations are structured.  

Summary

While every network has its own individual business requirements, either method of designing an IPv6 addressing plan can be leveraged to get you started.  Hopefully you’ll be able to find this information useful in planning your IPv6 deployment!

IPv6 Only Network

A few years ago I toyed with the idea of having a network without legacy IPv4 connectivity for end devices.  I also happened to recall RFC 6586 from nearly 7 years ago which discusses experiences in this exact topic.  When I last tried this experiment back in 2015, there was only one application with which I encountered a problem: The Steam desktop client.  Scavenging their forums, this was apparently a known issue since at least 2014, and was an issue they clearly had no plan on resolving.  Let’s build an IPv6 only network and see if this is still the case and if there are any other applications that don’t work.  

To reach the non-IPv6 Internet from your IPv6 only host, you’ll need two main components to translate the network traffic back and forth.  The first is Network Address Translation (NAT) and the second is a specialized DNS server that synthesizes AAAA records.  Almost everyone that has a router connecting their home network to the Internet is using NAT in some manner in order to utilize a single globally routable IPv4 address.  Different but similar, NAT64 is a NAT mechanism that embeds an IPv4 addresses within an IPv6 address.  This allows your IPv6 only traffic to get translated to IPv4 at the gateway, and then traverse the legacy Internet as usual.  To clarify, an IPv6 only device will not be able to directly speak to an IPv4 address, it must use a special address, usually in the 64:ff9b::/96 range, that has an IPv4 address inside of it so that the NAT64 device understands how to interpret the proper destination.  The DNS64 component acts as the DNS server for the IPv6 only clients.  It intercepts A records containing an IPv4 address, and synthesizes a AAAA record with the IPv4 address embedded in an IPv6 address before passing the response back to the IPv6 only device. 

Configuration

In my post about my homelab network structure, you can see more details on the underlying infrastructure being used here.  I’m using a separate VDOM for this function because I also use the FortiGate as a DNS server for the rest of my network where I don’t necessarily want to synthesize records.  The configuration on the FortiGate is fairly straightforward.  Basically you just enable the NAT64 system service and create a NAT64 policy to match the traffic you want to translate.  

Enter the system configuration for NAT64 and set the status to enable.  Additionally, you’ll want to disable the always-synthesize-aaaa-record option otherwise, native IPv6 traffic will always be translated back to IPv4.  To me it seems silly this option is enabled by default.  Why wouldn’t you want a native IPv6 connection to use IPv6?

config sys nat64
set status enable
set always-synthesize-aaaa-record disable 
end

An IP pool can be configured for 1:1 NAT but I just simplified the configuration by using the outgoing interface IP for NAT overloading.

config firewall address6
edit "v6only-vlan61"
set ip6 2001:db8:1:6061::/64
next
end
config firewall policy64
edit 1
set srcintf "vlan61"
set dstintf "v6onlyVlink1"
set srcaddr "v6only-vlan61"
set dstaddr "all"
set action accept
set schedule "always"
set service "ALL"
next
end

The VLAN that connects my IPv6-only clients to the network (VLAN 61) and provides a gateway outside also has SLAAC configured for backwards compatibility.  

config system interface
edit "vlan61"
set vdom "v6only"
set alias "v6 Only Access"
set role lan
config ipv6
set ip6-address 2001:db8:1:6061::1/64
set ip6-allowaccess ping
set ip6-send-adv enable
set ip6-other-flag enable
config ip6-prefix-list
edit 2001:db8:1:6061::/64
set autonomous-flag enable
next
end
end
set interface "internal3"
set vlanid 61
next
end

Configuring DHCPv6 is pretty straight forward too.  Most client devices (with the exception of Android) have supported DHCPv6 for many years now.

config system dhcp6 server
edit 61
set subnet 2001:db8:1:6061::/64
set interface "vlan61"
config ip-range
edit 1
set start-ip 2001:db8:1:6061::1001
set end-ip 2001:db8:1:6061::1fff
next
end
set dns-server1 2001:db8:1::60
next
end

Optionally, you can enable the DNS service which will synthesize the AAAA records, on an interface accessible from the client VLAN.  I ended up enabling the DNS server on a loopback interface, so that I could keep my DHCPv6 server configuration consistent across VLANs.  One caveat here is that on the FortiGate, you also need to have DNS listening on the client VLAN otherwise the queries are dropped.  Alternatively, you can use Google’s public DNS64 servers (2001:4860:4860::6464 and 2001:4860:4860::64), which you would specify in your DHCPv6 scope above. 

config system dns-server
edit "v6onlyLoopback"
next
edit "vlan61"
next
end

Applications Tested

For the most part, every application I tested from the IPv6-only network worked flawlessly with, the exception of the Steam desktop client application.  Note that the Steam iOS app worked just fine.

iPad iOS 9.3.5 (13G36)

AppVersion
Youtube13.45.7
Amazon11.21.2
Safari9.3.5

iPhone OS 12.1 (16B92)

AppVersion
SmartThings (Classic)2.17.1
Steam2.0.10
Signal2.31.1
Firefox14.0
Safari12.1
Waze4.45

MacOS 10.14 (18A391)

AppVersion
Google Chrome70.0.3538.102 (Official Build) (64-bit)
Firefox63.0 (64-bit)
Safari12.0 (14606.1.36.1.9)
Mail12.0 (3445.100.39)
Messages12.0 (5500)
Maps2.1 (2132.20.2.5.92)
Google Earth7.3.2.5491 (64-bit)
SteamBuilt: Nov 9 2018, at 18:51:43
Origin10.5.30.15625 – 0
Slack3.3.3

Steam Desktop Client: Still Broken

So why is the Steam desktop client so different from any other application?  Packet captures show DNS queries being made for steam services, but there are only responses containing A records. 

Other applications querying DNS for IPv4-only services show two responses including both an A and synthesized AAAA records.  If you manually query an AAAA records for one of the Steam domain names, the synthesized record appears normally:

$  dig -t aaaa @2001:4860:4860::6464 cm2-iad1.cm.steampowered.com

; <<>> DiG 9.9.5-9+deb8u16-Debian <<>> -t aaaa @2001:4860:4860::6464 cm2-iad1.cm.steampowered.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36156
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;cm2-iad1.cm.steampowered.com. IN AAAA

;; ANSWER SECTION:
cm2-iad1.cm.steampowered.com. 10799 IN AAAA 64:ff9b::a2fe:c065

;; Query time: 77 msec
;; SERVER: 2001:4860:4860::6464#53(2001:4860:4860::6464)
;; WHEN: Sat Dec 01 08:53:50 EST 2018
;; MSG SIZE rcvd: 85

This behavior would lead me to believe that the Steam client is specifically only asking for an A record, and is not using the underlying operating system defaults for dual stack name resolution.  Why they’ve chosen to do this is unclear, as both Origin and GOG game platforms seem to work just fine.  

Summary

So it turns out, as long as you’re not a PC/Mac gamer tied to the Steam platform, you can ditch your legacy dual stack network.  I’ll be continuing to test various other devices on this network and will update the article with the results.  Other devices I plan on testing include: Xbox One, Apple TV gen 3, Amazon Alexa, Amazon Kindle Fire, and a Google Home.

Fortinet Home Lab

The most recent incarnation of my home lab began about a year and a half ago when I obtained a more powerful FortiGate firewall.  The entire network is quite literally centered around a FWF-61E running multiple virtual routers. In FortiLand these are referred to as Virtual Domains (VDOMs). Most people don’t really need a complicated home network setup, but I like to push technology to its limits and explore my options. Then again, most people don’t have over 60 devices on their home network.  Typically, having multiple Virtual LANs (VLANs) would suffice for traffic separation; however, utilizing VDOMs allows me to further compartmentalize network functions and gives me more flexibility for testing additional features.

To build out the configuration, I first had to decide how I wanted the network to be segregated by purpose and/or function. The main design consideration in this case involved a VDOM dedicated as a virtual transit router that would essentially be responsible for passing traffic between all other VDOMs and from those VDOMs out to the Internet.  This is accomplished using VDOM links between each VDOM and the Internet VDOM.

VDOM Structure:

  • Internet: Transit for all inter-VDOM traffic, NAT/PT, UTM
  • Home: Separate VLANs for different server networks, laptops, guests, etc.
  • Management: Administration of network equipment
  • IoT: Separate VLANs for thermostats, light bulbs, TVs, and sensors
  • VPN: Remote access and tunnels to other home networks
  • V6only: For testing DNS64/NAT64 functions and how applications handle the translation

Each VDOM is dual stack IPv4/IPv6, with the exception of the v6only VDOM, and has at least one dedicated physical interface.  Currently OSPF and OSPFv3 are being used to share routes across VDOMs.

homelab-vdoms

This configuration has allowed for greater flexibility when building test networks.  Unlike the FWF-60D, the 61E hasn’t run into any performance issues, even with all of the extra overhead.