IPv6 with Prefix Delegation on Fortigate

[Edit 2018-10-18] Make sure to use FortiOS 6.0.3 or later for this, as earlier versions of 6.0.x will force your interface to IPv6 “static” when you make any change to the interface from the GUI, including changes to its IPv4 configuration, such as a DHCP reservation. I have not tested 5.6.x but am assuming it has the same issue.

This post is meant to be a full description of how to enable IPv6 connectivity on an ISP link with Prefix Delegation, using a Fortigate firewall. I’ll use Comcast as an example, since that’s my ISP.

This post focuses on home / home office connections, though a small business that uses the Fortigate unit as the LAN router would work the same way. If you use an ISP link with Prefix Delegation but have an internal core router downstream from the Fortigate, you may need a static IPv6 prefix instead.

I am not covering how link failover / SDWAN would work with IPv6. It’s an interesting use case, and I lack the second link to test it.

There are three components to setting up IPv6 in this environment.

  • Receiving an external IP and a prefix using Prefix Delegation
  • Assigning subnets to Fortigate internal interfaces and assigning addresses to client devices
  • IPv6 firewall policy

This post pulls together information already available elsewhere. I have given references at the end of the post.

A quick IPv6 refresher

There are just a few things to remember for home / office use if you are coming from an IPv4 world. This post does not apply to Enterprise networks, though I mention Enterprise for reference here and there.

– Your “site” (home, office) will receive a /64 or /60 prefix from Comcast (residential), or as large as /56 (business). (A /48 is the typical Enterprise site prefix size.)

– All local networks (subnets) have a /64 prefix length. Subnetting further really isn’t a thing, with the exception of /127 point to point links, done for security reasons. You can have more than one /64 on one VLAN and clients can have more than one IPv6 address.

– There is no NAT. All your clients will have public addresses. (This might not be true in Enterprise networks where you may decide to either use public addresses or ULAs with NPT, Network Prefix Translation.)

– ICMPv6 is crucial to connection health. Just dropping all ICMP at the border won’t do the trick.

– In an IPv6 address, the first four fields are the network, the last four fields the device. Leading zeroes can be omitted, and a bunch of zeroes can be summarized as :: – with the caveat that there’s only one :: per address. For example, 2001:db8:3c4d:f40::/64 might be your subnet, and 2001:db8:3c4d:f40::1/64 is the address assigned to your Fortigate interface on that subnet.

– DHCPv6 cannot assign a next hop. Not all client operating systems can receive a DNS server without DHCPv6.

Receiving a prefix via Prefix Delegation

Before you get started, make sure that IPv6 is turned on in “System -> Feature Visibility”.

On a residential or business line, your ISP will assign you a prefix to use for your internal network(s). This prefix is received on your ISP-facing interface via DHCPv6 Prefix Delegation (PD), and can then be assigned dynamically to your internal interface(s).

Comcast will assign you a delegated /64 or /60 prefix on a residential line. A business line can receive up to a /56. These prefixes are dynamic and will change, just like a DHCPv4 address.

If you have a residential line and just one network internally, the default /64 will do fine.

If you have more than one network, you can give your ISP a “hint” that you’d like a /60 (16 networks) or /56 (256 networks, business line).

To clarify the underlying mechanics, DHCPv6 assigns a /128 address to your outside interface, and “delegates” a prefix that you can then use to assign /64s to your internal interface(s) as desired, or, indeed, delegate further inward to another router.

Here’s an example that’s requesting a /60 prefix. This example only shows the ipv6 portion of the configuration.

config system interface
  edit "wan1"
    config ipv6
      set ip6-mode dhcp
      set ip6-allowaccess ping
      set dhcp6-prefix-delegation enable
      set dhcp6-prefix-hint ::/60

If you don’t have more than one internal interface, you can leave the hint off. Comcast on a residential line will assign a /64 in that case, for example.

Assigning prefixes to internal interfaces and addresses to clients

I owe others for explaining how to do this, notably Myles and /u/iwanttoride . Without their explanations, I’d still be stuck thinking that FortiOS doesn’t support dynamic allocations. The examples given in the FortiOS handbook are brief and lack all explanation.

Before getting started, two decisions need to be made:

Which DNS servers will be used? Those of the ISP or others? If others, such as Cisco Umbrella / OpenDNS or CloudFlare’s privacy DNS, enter those servers, both IPv4 and IPv6, under Network -> DNS, and choose to “Specify” your own servers. I’m showing using specified DNS servers, and will mention the commands required to use the ISP’s DNS servers instead.

Will you assign addresses using DHCPv6, or use DHCPv6 for DNS assignment only? I am showing DNS only, DHCPv6-lite. I’ll mention the commands required if you want to use DHCPv6 address assignment, though I’m not sure what would be gained. DHCP monitor seems to show only IPv4.

Assigning addresses to clients is reasonably straightforward, though there are implementation differences. Some OSs will receive DNS via DHCPv6, others only through RDNSS. Some can receive addresses via DHCPv6, others, notably Android, can’t.

This means you’ll be presenting DNS via both DHCPv6 and RDNSS. Make sure the two match and deliver the same server(s). Likewise, if you use DHCPv6 for address assignment, make sure it matches the SLAAC assignment on the interface.

Here are the commands to use the first /64 of your delegated prefix on an internal interface. As before, I’m only showing the ipv6 portion of the configuration.

config system interface
  edit "lan"
    config ipv6
      set ip6-mode delegated
      set ip6-allowaccess ping https ssh
      set ip6-send-adv enable
      set ip6-other-flag enable
      set ip6-upstream-interface "wan1"
      set ip6-subnet ::1/64
      config ip6-delegated-prefix-list
        edit 1
          set upstream-interface "wan1"
          set autonomous-flag enable
          set onlink-flag enable
          set subnet ::/64
          set rdnss-service default

If you wanted to use DHCPv6 for address assignment, add “set ip6-managed-flag enable” to the “config ipv6” section. Because of OS implementation quirks, you should keep both the managed-flag and the other-flag in that case.

This may require a reboot. I am not sure of that, and it might depend on FortiOS version. I think FortiOS 6.0.1, where I tested that, just needs a couple minutes time to assign the interface its address, but I’m not 100% certain of that.

Keep in mind you can “get” the actual values on your interface once you are inside its configuration via “edit lan” or whatever your interface name is.

Let’s discuss these in some more detail.

We’re, obviously, in delegated mode, and we got a delegated prefix on our “ip6-upstream-interface”, in my case “wan1”.

ip6-allowaccess is for management access. If you have a FortiManager on this interface, or FortiAPs in tunnel mode, add the relevant services like you would in IPv4.

We’re sending RAs so that clients can learn an address and a next-hop, that’s ip6-send-adv. We’re telling clients they can get a DNS server (and if you feel like it, a dns-search-list) via DHCPv6, that’s “ip6-other-flag”.

The ip6-subnet is the part I didn’t understand for the past 2 years or so. This is a mask that is applied to the delegated prefix using a logical Boolean “AND” operation. In practice, you can think of this as just “adding” this value to the delegated prefix. “::1/64” means that we’ll take the delegated prefix as-is, and add “1” at the very right, then change the length to 64. This becomes the IPv6 address of this interface. Let’s say my delegated prefix is 2001:db8:3c4d:f40::/60, then the IPv6 address of my “lan” interface would become 2001:db8:3c4d:f40::1/64.

Now we need to hand out addresses to clients on this network. That’s what the “ip6-delegated-prefix-list” is for. I only need one subnet per interface, so “edit 1” it is. The “upstreams-interface” needs to be set, once more. “autonomous-flag” and “onlink-flag” tell the client that it can get an address via SLAAC here and that this interface has an address in that range, that is, can be routed to, respectively.

The “subnet” functions similarly to the “ip6-subnet” for the interface address. Here, we’d want to add to the network portion, not the host portion of the IPv6 address. Since I’m using the very first subnet in my allocation, there’s nothing to add. “::/64” combined with my 2001:db8:3c4d:f40::/60 prefix gives me 2001:db8:3c4d:f40::/64 to be used for client addresses on this interface.

Lastly, “rdnss-service default” will hand out my system DNS server(s) to clients on this link, if the client speaks RDNSS. That’s the belt and suspenders approach to DNS, discussed above. If you wanted to use the ISP’s servers instead, you’d configure “rdnss-service delegated”.

And here’s the DHCPv6 portion to hand out DNS.

config system dhcp6 server
  edit 1
    set dns-service default
    set interface "lan"

If you wanted to use the ISP’s DNS servers, that would become “set dns-service delegated”, and you’d add “set upstream-interface “wan1″”.

If you had DHCPv6 also hand out addresses, it’d look like this.

config system dhcp6 server
  edit 1
    set dns-service default
    set subnet ::/64
    set interface "lan"
    set upstream-interface "wan1"
    set ip-mode delegated

Now, let’s do this all over again for guest WiFi, assigning the second /64 subnet out of my /60 allocation.

config system interface
  edit "wifi"
    config ipv6
      set ip6-mode delegated
      set ip6-allowaccess ping
      set ip6-send-adv enable
      set ip6-other-flag enable
      set ip6-upstream-interface "wan1"
      set ip6-subnet ::1:0:0:0:1/64
      config ip6-delegated-prefix-list
        edit 1
          set upstream-interface "wan1"
          set autonomous-flag enable
          set onlink-flag enable
          set subnet 0:0:0:1::/64
          set rdnss-service default

Guests don’t need management access to my Fortigate, so “ip6-allowaccess ping” suffices here.

The ip6-subnet value of ::1:0:0:0:1/64 combines with my 2001:db8:3c4d:f40::/60 prefix to give this interface an IPv6 address of 2001:db8:3c4d:f41::1/64. Keep in mind that the left-most four fields of the address are the network, and the right-most four fields are the host.

For assigning addresses to clients, I’m matching this and set subnet to 0:0:0:1::/64. This is for the subnet, which means I care about the network portion only, hence the :: for the host fields. Combine that again with my delegated 2001:db8:3c4d:f40::/60 prefix and clients will receive addresses from 2001:db8:3c4d:f41::/64. That’s on-link to the interface address and they’ll be able to route.

Remember to create another DHCPv6 entry for DNS, and if you use DHCPv6 to give out addresses, make sure that entry’s subnet value matches the value here.

config system dhcp6 server
  edit 2
    set dns-service default
    set interface "wifi"

And with DHCPv6 handing out addresses:

config system dhcp6 server
  edit 1
    set dns-service default
    set subnet 0:0:0:1::/64
    set interface "wifi"
    set upstream-interface "wan1"
    set ip-mode delegated

Rinse repeat for any other interfaces you may have. A /60 delegated prefix gives you 16 available subnets, from 0 through f.

IPv6 firewall policy

Time for something simpler. All you need here is a policy allowing ICMPv6 in and out, and a policy for traffic out to the Internet or other subnets.

I have multiple interfaces so I enabled “Multiple Interface Policies” in “System -> Feature Visibility”, to make my life easier.

I’d like to follow RFC 4890 instead of allowing “all ICMPv6”. ICMPv6 is needed for session health, and I still want to be security-conscious.

config firewall service custom
  edit "ICMP6-DestUnreach"
    set category "General"
    set protocol ICMP6
    set icmptype 1
    unset icmpcode
  edit "ICMP6-PacketTooBig"
    set category "General"
    set protocol ICMP6
    set icmptype 2
    unset icmpcode
  edit "ICMP6-TimeExceeded0"
    set category "General"
    set protocol ICMP6
    set icmptype 3
    set icmpcode 0
  edit "ICMP6-TimeExceeded1"
    set category "General"
    set protocol ICMP6
    set icmptype 3
    set icmpcode 1
  edit "ICMP6-ParmProb0"
    set category "General"
    set protocol ICMP6
    set icmptype 4
    set icmpcode 0
  next  edit "ICMP6-ParmProb1"
    set category "General"
    set protocol ICMP6
    set icmptype 4
    set icmpcode 1
  edit "ICMP6-ParmProb2"
    set category "General"
    set protocol ICMP6
    set icmptype 4
    set icmpcode 2
  edit "ICMP6-EchoRequest
    set category "General"
    set protocol ICMP6
    set icmptype 128
    unset icmpcode
  edit "ICMP6-EchoResponse"
    set category "General"
    set protocol ICMP6
    set icmptype 129
    unset icmpcode
config firewall service group
  edit "ICMP6-allow"
    set member "ICMP6-DestUnreach" "ICMP6-EchoRequest" "ICMP6-EchoResponse" "ICMP6-PacketTooBig" "ICMP6-ParmProb0" "ICMP6-ParmProb1" "ICMP6-ParmProb2" "ICMP6-TimeExceeded0" "ICMP6-TimeExceeded1"
    set comment "ICMP6 services to be allowed as per RFC4890"

With that group created, you can now create your first three IPv6 policies.

Allow desired ICMPv6 and drop all other ICMPv6:

From “any” interface to “any” interface, source and destination “all”, schedule “always”, Service “ICMP6-allow”, action “Accept”, and no NAT. I turn logging off as well.

From “any” interface to “any” interface, source and destination “all”, schedule “always”, Service “ALL_ICMP6”, action “Deny”. I turn off logging.

Allow your interfaces out to the Internet:

From internal interface, say “lan”, to external interface, say “wan1”, source and destination “all”, NAT disabled, action “Accept”, and Schedule, Service, Security Profiles and Log as desired. Add additional “from” interfaces if they share the same policy.

Testing, References

IPv6 connectivity testing is available at ipv6-test and test-ipv6.

Myles documented prefix delegation in a way I could understand.

/u/iwanttoride explained an example configuration of PD on reddit.

Antonios Atlasis and Enno Rey lab-tested client implementation differences in receiving an address and DNS server.

James Sanders explained Android’s requirement for RDNSS.

E. Davies and J. Mohacsi wrote RFC 4890, a recommendation on how to filter ICMPv6 messages on a firewall while still allowing IPv6 to function.


Final IPv4 allocations; IPv6 readiness test; IPv6 world day

Final IPv4 allocations have been made today. Will this galvanize businesses to start moving to IPv6? We’ll see 🙂


If you’ve been following my “IPv6 at home” series, here’s a neat link to test your IPv6 readiness: http://test-ipv6.com/


Finally, “World IPv6 day” will be on June 8th 2011. Google, Facebook, Yahoo, Akamai and Limelight will turn on IPv6 for 24 hours. Results should be interesting to see. If you’d like to prepare for World IPv6 day today, go on over to their official site.


IPv6 at home or office, part 4.1: 6in4 tunnel on Juniper ScreenOS firewall

This blog post is part of a series on ipv6. Part 4.0 describes requesting a Hurricane Electric tunnel; this part explains how to configure a Juniper ScreenOS firewall – SSG, ISG or Netscreen – to work with such a tunnel.

Sample environment

I am going to give an example based on ScreenOS 6.0.0 or later syntax. ScreenOS 5.4 is reported to support IPv6 6in4 tunnels, as well, though it does not expose the configuration to the web interface.

These settings can (almost) all be configured through the web interface. In the interest of brevity, I am going to show CLI commands instead.

Here are the interface names and addresses used in this example. In this example, I use the IPv6 documentation prefix. When configuring this, you get the real addresses from the Tunnel Details page.

External interface name: ethernet0/0, Untrust zone

Internal interface name: bgroup0, Trust zone

Tunnel interface name: tunnel.1, Untrust zone

Server IPv4 address:

Server IPv6 address: 2001:0db8:1:223::1/64

Client IPv6 address: 2001:0db8:1:223::2/64

Routed /64: 2001:0db8:2:223::/64

Anycasted IPv6 Caching Nameserver: 2001:0db8:1234::2

Enabling IPv6

This is the one step you must do from command line. Enter:

set envar ipv6=yes

and reboot. This will enable IPv6 features on your ScreenOS device.

Setting up the tunnel

The first step is to set up a tunnel interface that will allow you to encapsulate IPv6 packets in IPv4 packets.

set interface “tunnel.1” zone “Untrust”
set interface “tunnel.1” ipv6 mode “host”
set interface “tunnel.1” ipv6 ip <Client IPv6 address>
set interface “tunnel.1” ipv6 enable
set interface tunnel.1 tunnel encap ip6in4 manual
set interface tunnel.1 tunnel local-if <External interface> dst-ip <Server IPv4 address>
set interface tunnel.1 mtu 1480
unset interface tunnel.1 ipv6 nd nud
set interface tunnel.1 ipv6 nd dad-count 0
set route ::/0 interface tunnel.1 gateway <Server IPv6 address>

We’re creating the tunnel.1 interface, assign it to the “Untrust” zone, and give it its IP address, the “Client IPv6 address”.

Next we’re creating the tunnel itself, terminating on the external interface on one side and the Server IPv4 address on the other side.

We restrict MTU to 1480 as that is the largest packet that can go through without fragmentation, and disable Neighbor Unreachable Detection for good measure. I haven’t had issues with nud on, but others have.

Finally, create a default IPv6 route through the tunnel.1 interface, so our IPv6 traffic has somewhere to go.

Setting up IPv6 for the local network

Next, we’ll use the “Routed /64” that HE gave us for our internal network.

set interface “bgroup0” ipv6 mode “router”
set interface “bgroup0” ipv6 ip 2001:0db8:2:223::1/64
set interface “bgroup0” ipv6 enable
unset interface bgroup0 ipv6 ra link-address
set interface bgroup0 ipv6 ra preference high
set interface bgroup0 ipv6 ra other
set interface bgroup0 ipv6 ra transmit
set interface bgroup0 ipv6 nd nud
set interface bgroup0 ipv6 nd dad-count 0
set interface bgroup0 dhcp6 server
set interface bgroup0 dhcp6 server options dns dns1 <HE IPv6 Name Server>
set interface bgroup0 dhcp6 server enable

Here, we are giving the LAN interface an IPv6 address from the “Routed /64” range – in the interest of simplicity, I chose “1”. We then enable Router Advertisement so that local machines can receive IPv6 addresses from this interface.

We’re also setting the RA “other” bit and enabling DHCPv6 to give out HE’s IPv6 DNS server. Those two steps are optional: It’ll mean that Google’s IPv6-enabled services will resolve with both an IPv4 and an IPv6 address – otherwise, Google will only be reachable by IPv4.

Setting up an IPv6 firewall policy

As an example, here is a very simple policy that allows all outgoing IPv6 traffic, and denies all incoming IPv6 traffic. Adjust as fits your environment.

set policy from “Trust” to “Untrust”  “Any-IPv6” “Any-IPv6” “ANY” permit
set policy from “Untrust” to “Trust”  “Any-IPv6” “Any-IPv6” “ANY” deny

IPv6 at home or office, part 4.0: tunnelbroker.net, IPv6 routers

This blog post is part of a series on ipv6. In part 1, I provided an overview of ipv6 and looked at Teredo, the technology built into Windows Vista; in part 2, I looked at AYIYA tunnels through aiccu, using sixxs net as a tunnel broker. Part 2.5 is a collection of useful ipv6 tidbits, and part 3 describes gogonet/freenet6 tunnels.

In part 4, I will describe the IPv6 tunnel I have been using all along since 2008: A Hurricane Electric 6in4 tunnel, typically terminating on a router, though it could be terminated on a PC, as well. I aim to break part 4 into chunks, each describing setup for a different make and model of router.

Provisioning of the tunnel

Make sure the router you will be using allows itself to be pinged from either “the Internet”, or at the least from HE’s server, currently66.220.2.74.

Sign up with Hurricane’s Electric tunnelbroker.net service.

Once signed in, under “user functions”, choose “Create Regular Tunnel”.

Enter the IPv4 endpoint, and hit “Submit”. If you are a home user, your IPv4 endpoint is the public IP your ISP assigned to you, see whatismyip.org.

And you are done. Helpfully, the tunnel details page also allows you to get sample configurations for a variety of PC and router operating systems, including Linux, Windows, Cisco IOS, Juniper JunOS and Juniper ScreenOS.

Updating your dynamic IPv4 address

If you are in a home environment, your public IPv4 address may change from time to time. You can update it from the tunnel details page, or you can use tunnelbroker.net’s ipv4 update page that is intended to be used from a script, for automatic updates.

Routers supporting 6in4 tunnels

Whether enterprise class or home router, here are some of the devices that support 6to4 with 6in4 tunnels today (February 2010). On the home router side, it’s clear that it is early days yet. Comcast’s ipv6 trials may change the competitive landscape here.


Any SSG or ISG firewall running ScreenOS 6.0.0 or later, as well as (with some limitations) Netscreen firewalls on ScreenOS 5.4.0. Part 4.1 describes the setup.

Any JunOS router – J-Series, M-Series, E-Series, T-Series, &c. All the way back to JunOS 9.1 if need be.

Any SRX firewall, with the caveat that SRX does not yet support ipv6 firewalling as of JunOS 10.1, though it does support ipv6 tunneling and routing.

EX switches do not support ipv6 tunnels yet, though the feature is road-mapped.


It’s the usual mess of IOS versions depending on model, paired with feature set. A very Cisco-savvy fellow over at the HE forums has an excellent breakdown. In a nutshell, IOS 12.4 or later should work, and you’ll need the right feature set.

Switch support for IPv6 is good. You’ll need to check model / IOS version / feature set here, too.


Apple Airport Extreme supports 6to4, and a one-click tunnel provisioning, too. This is the only home router that I’d be confident to use for IPv6 today, without needing to fear that a firmware update would break IPv6. Mainly because a firmware update did break IPv6, and Apple fixed it in v1.5. For this router, IPv6 is an officially supported feature.

[Update 2010-04-28] Comcast will use this router in their IPv6 dual-stack trials, as one of three choices.


Comcast will use the Netgear WNR3500 and Netgear WNR1000 in their IPv6 dual-stack trials. Whether these routers support 6in4 tunnels is unknown to me at this point.


[Update 2011-08-03: D-Link have updated their site with a list of devices supporting native IPv6] According to D-Link, the following router models support IPv6. Comcast are using the DIR-655 and DIR-825 in their native dualstack IPv6 trial.

D-Link IPv6 Certified Routers

  • DIR-601 Wireless N 150 Home Router (Hardware Revision A1)
  • DIR-615 Wireless N 300 Router (Hardware Revision E1)
  • DIR-632 Wireless N 8-Port Router (Hardware Revision A1)
  • DIR-655 Xtreme N Gigabit Router (Hardware Revision B1)
  • DIR-825 Xtreme N Dual Band Gigabit Router (Hardware Revision B1)
  • DHP-1320 Wireless N PowerLine Router (Hardware Revision A1)

Other IPv6 Certified Products

  • DHP-W306AV PowerLine AV Wireless N Extender (Hardware Revision A1)
  • DAP-1350 Wireless N Pocket Router and Access Point (Hardware Revision A1)
  • DAP-1360 Wireless N Range Extender (Hardware Revision B1)
  • DAP-2590 AirPremier N Dual Band PoE Access Point

D-Link state that their DSL modem routers, the DSL-2540B and DSL-2640B also support IPv6.

D-Link DGS-3200 and DGS-3600 switches officially support IPv6.


WRT610N, with reports that firmware updates break ipv6 support and that Linksys support is firm that ipv6 is not an officially supported feature. More testing is in order here, too.

[Update] A Linksys live chat operator tells me that native IPv6 is supported on the WRT610N, and that there is no official documentation for this. No word on tunnels. I have reached out to their press office to get details and will update if/when I get an answer.

[Update] The Comcast trial forums float the WRVS4400N as supporting tunneled and native IPv6.

Buffalo Technology

A “number of” their wireless products support ipv6. I have reached out to their press office to get details and will update if/when I get an answer.


FRITZ!Box 7270 (experimental “Labor” version)

I have reached out to their press office to get details and will update if/when I get an answer.

ipv6 at home: Comcast ipv6 trials

I’m admittedly late to the party with this, as it’s a January 27th announcement. Comcast is gearing up for public ipv6 trials starting in April, and they’re looking for guinea pigs trial users.

[Update 2010-02-26] I just received an email from Comcast. They’ll start ramping up 6RD trials nationwide. Dual-stack trials will be regionally limited. Trial users that do not have IPv6-ready equipment will receive equipment that is ready, including what Comcast calls a “gateway” (home router). They may start contacting volunteers in a month, and expect to start some of these trials within 3 months.

There’ll be four total phases to the trial:

Q2 2010

IPv6 tunneled over IPv4 using 6RD. If you’re using one of the tunnel methods I describe in this blog today, you’re familiar with this.

Native dual stack. You’ll have both an ipv4 address and ipv6 addressing natively. Your router will need to support ipv6.

Q3 2010

IPv4 tunneled over IPv6, dubbed “Dual Stack Lite”. You’ll have a private IPv4 address, and use a tunnel over IPv6 to share one public IPv4 address with several other subscribers. Interesting approach.

Business class dual stack

In other “late to the party” news, Google turned up ipv6 on youtube sometime in January. Full production, caused a big spike in v6 traffic, and it seems to be working just fine.

ipv6 addressing – there is no NAT, and “renumbering needs work”

Addressing is a big deal with ipv6. For people coming from ipv4, wrapping one’s head around ipv6 addressing can be hard.

This post is a response to the comments discussion in the Standalone Sysadmin blog post urging uptake of ipv6. In the comments, we see people concerned with the fact that ipv6 addressing gives a public, routable address to every last PC, server and printer – and suggestions that this could be resolved by deploying ULA (Unique Local IPv6 Unicast Addresses) per RFC4193 – it’ll be just like your current RFC1918 space!

Actually, it won’t. ULA is not the solution. Every machine that needs access to the Internet will be on a routable, public address. That’s only scary from a management perspective – and that’s the TL;DR. Read on for the justification of that statement.


ULA addressing is addressing per RFC4193. It is different from RFC1918 in some ways, and it shares a few characteristics with RFC1918.

ULA is different from RFC1918 in that the addresses are meant to be unique. This is achieved by using a Pseudo-Randomly derived “Global ID” as part of the site prefix. The RFC goes into detail – at length – as to how that PRNG generation is supposed to work. In practice, you still have a very small chance of collision. ULAs were never meant to be registered in any way – SixXS gives you a registration page anyway, just to avoid that small chance of overlap.

ULA is similar to RFC1918 in that ULA address space is “not expected to be routable on the global Internet”. This translates to a requirement to filter out ULA space at the BGP border router, and for all exterior routing protocols to “ignore receipt of and not advertise” ULA space. See section 4 of the RFC for details.

ULA is different from RFC1918 in that ipv6 does not offer NAT  (though arguments are being put forth that ipv6 NAT may be beneficial). Wait, I hear you say, how is that a difference between ULA and RFC1918? That’s a difference between ipv6 and ipv4! To which I say: True enough. That difference impacts how these addresses can be used, would be a better way to put it. You can put a PC on an RFC1918 address, and it can still get to the Internet, through a Many-to-One source NAT. You can put a server on an RFC1918 address, and it will still be reachable through a static one-to-one NAT. You cannot do any such thing with a machine that has only a ULA address. That machine will be unable to get to the Internet, and vice versa.

[Edit 2011-02-03: NAT is with us again, in the form of NAT66. Note that it is designed to translate one /48 prefix into another /48 prefix. I am still not a great fan of this idea, as the application challenges remain. If you’ve ever tried to NAT h.323 or sip and found that your firewall doesn’t _quite_ speak your version of that protocol, you know what I speak of. Designing an IPv6 network without the need for NAT66 is, in my opinion, far preferable]

That doesn’t mean that ULAs are useless. They are meant to allow local machines to communicate locally – combined with the idea of DHCP-PD, this can be a way to handling renumbering. RFC4864 was written specifically to address concerns about manageability of local IPv6 space.

Let me speak to this new ipv6 world where every machine has a routable public address from a few perspectives.

Application perspective

Doug Maxwell says:
1) It’s always routing
2) No NAT is good NAT
3) Sh^t don’t work

NAT is the bane of your applications. If you’ve ever tried getting SMB or VoIP through NAT, you know what I speak of. Any application that references an IP address in L7 – whether that’s a good idea or no, it happens – is going to be hurting. Many-to-one NAT will be hurting P2P applications, which ipv4 proposes to resolve by using port forwards, which don’t scale. It’s a nightmare.

Interestingly enough, the biggest boost to public (as opposed to governmental) ipv6 uptake has been from a popular p2p application starting to support ipv6. Go figure.

No NAT is a good thing from an application perspective. It also helps to make inter-partner VPNs so much easier to set up.

Security perspective

Repeat after me: NAT is not a security solution.

It may be fairer to say: The security gained by many-to-one source NAT is a side effect.

It is your firewalls’ (perimeter and internal, if you have any internally) job to control which traffic may reach your internal network. If your rulebase looks like this:

Internal-LAN to Any on http/https/ping : Allow
Any to Internal-LAN on Any : Deny

then your Internal-LAN is going to be just as secure on public space – ipv4 or ipv6 – as on private space. If you can’t get to it, you can’t get to it, no matter whether the address is routable.

You can also think about this from a server perspective: Say you have a web server on, and you NAT it to a public address. Your firewall rulebase will look like this:

Any to Public-WWW on http: Allow

Whether this Public-WWW address is now going to be NATed to, or just routed to the server, makes absolutely no difference from a security perspective.

Management perspective – “renumbering needs work”

Managing your address space needs considerably more forethought in ipv6 than in ipv4. ipv6 is new now, but it’ll be an “old hat” before you know it – and then you’ll be shopping around for the best deals on ISP connectivity, just as you do now with ipv4. The idea of needing to renumber absolutely everything when you switch ISPs is not pleasant. RFC4864 has a few suggestions on how to handle that – none of which may be really workable in your situation.

There is one “easy” solution to this mess: Get your own site address space(s) assigned to you by your local RIR, whether that’s ARIN or somebody else. Then use that space in perpetuity, regardless of the IPS(s) that provide your bandwidth. Unfortunately, the ipv6 early adopter days are over, and the ipv4-has-run-out days are not yet here. As a result of which, ipv6 eligibility is tied to ipv4 eligibility: You can get your own ipv6 address space if either a) you already own ipv4 space and can show that you use it efficiently or b) you are eligible to receive ipv4 space. As of early 2010 looking at ARIN rules, that means you’d have to be eligible for an ipv4 /22, and currently use a /23 worth of ipv4 public space efficiently. That’s a tough hurdle to jump over.

As a manager, you’ll want to have your people fight tooth and nail for that directly assigned space. It is the by far most cost-effective and most lasting solution to renumbering concerns.

If that is not an option, and you need ipv6, you need to pay a lot of attention to IP Address Management. The old “spreadsheet kept by the IT dept” method will no longer work. What you’re looking for is strong asset management – DHCP, DNS and ACLs populated by a backend asset database. The marketplace will create these solutions as ipv6 uptake gets under way. Infoblox is one company to watch in this space, though they do not tie into ACL generation.

The best advice I can give is to plan for a renumbering scenario if you cannot get your own address space. Evaluate IAM solutions and network management solutions. Have your people run through a dry-run of renumbering to uncover areas that may have been overlooked, such as application settings.

A few basic configuration choices will make renumbering easier:

– Use DHCPv6 to assign addresses to not just workstations, but also servers. Servers will have their address bound by MAC address – this is where your IAM comes in handy

– Use DNS in your configurations wherever possible – avoid the use of static addresses where feasible and where performance allows it

– Use a network management application that allows you to change the addressing and configuration of your routers and switches quickly and easily

I am not a big fan of DHCPv6 prefix delegation, outside of a provider-to-consumer relationship, that is. DHCPv6 prefix delegation is meant to work with stateless auto-configuration, for routers that have one upstream link and one LAN link. Great in a provider environment, not so great in an enterprise environment.

Lastly, let me share some useful resources: A draft RFC proposing a renumbering methodology without the “flag day”, and a whitepaper from January 2009 looking at IPv6 renumbering, the current challenges and options.

ipv6 at home, part 3: gogonet tunnels, freenet6

This blog post is part of a series on ipv6. In part 1, I provided an overview of ipv6 and looked at Teredo, the technology built into Windows Vista; in part 2, I looked at AYIYA tunnels through aiccu, using sixxs net as a tunnel broker. Part 2.5 is a collection of useful ipv6 tidbits, and this part 3 gets back to the original plan: Exploring ipv6 connectivity options – in this case, the tunnel offered by gogo6 (formerly Hexago) at go6.net. gogonet.

Tunnel overview

freenet6, the tunnel service offered by gogo6, uses TSP (Tunnel Setup Protocol) to determine the best tunnel type. It offers IPv6-in-IPv4 tunnels in Native mode (direct connection to a public ipv4 address, no NAT), IPv6-in-IPv4 tunnels in NAT traversal mode (also called IPv6-in-UDP-is-IPv4; this is what you’ll most likely use), and even IPv4-in-IPv6 tunnels (using DSTM, used to reach ipv4 resources if you have an ipv6 address but no ipv4 address – not a very likely scenario at this point in time).

The tunnel service is delivered through gateway6, an incredibly intuitive and easy-to-use client. Both anonymous and authenticated tunnels are available. An anonymous tunnel will provide ipv6 access for the machine the gateway6 client is installed on; an authenticated tunnel gives you a routable /56 network to hand out to the rest of your network.

Setting up an anonymous tunnel

Install the gateway6 client; launch it; leave everything at default; hit “Connect”.

Test your connection by browsing to ipv6.google.com.

In this mode, your assigned ipv6 address will change as your ipv4 address changes.

I should spruce this paragraph up by adding a screen shot of the gateway6 client with all default settings, but it feels gratuitous. This method of connection is hands-down the easiest way to get ipv6 connectivity that you are likely to find.

Setting up an authenticated tunnel

Sign up with go6.net. freenet6. This is separate from the gogonet account you need to even download the client.

Install the gateway6 client.

Change the “Gateway6 address” to be “authenticated.freenet6.net”.

Set the client to “Connect using the following credentials”, and enter your user name and password with go6.net.

On the off-chance that a tunnel endpoint would default to clear-text authentication, you can go to the “Advanced” tab and change your Tunnel Authentication Method to either PASS DSS 3DES1 or Digest MD5.

Hit “Connect” and test your connection by browsing to ipv6.google.com.

In this mode, your assigned ipv6 address will remain static, even if your ipv4 address changes.

Setting up routing to the rest of your network

go6.net will assign a /56 prefix to you on an authenticated tunnel, if you request it.

The simplest way to set this up is:

On the “Advanced” tab, check “Enable Routing Advertisements”. Choose the LAN interface that will serve the ipv6 prefix to the rest of your network. Leave the prefix length at /64.

Hit Connect, and check the “Status” tab – you’ll see your assigned /56 prefix. Of which you are currently using the first /64 – if you have further subnets, you can start assigning more /64s and routing them to the machine that runs the gateway6 client.

Advanced options – running on a router, reverse DNS delegation

Through changing the gw6c.conf file, you can use the gateway6 client to request configuration for a router; and you can request delegation of your ipv6 prefix to your own name server for RDNS (PTR) resolution.

RDNS delegation is set up by simply changing the “dns_server=” entry.

You can run the gateway6 client as a “proxy”, in which mode it will request configuration information for a router. This is described in the gogonet forums. You’d want to set the requested prefix length to /56, not /48 – otherwise, no changes should be necessary.

The provided template outputs configuration for a Cisco router. You can take the relevant information out of the Cisco config file and use it with a Juniper device, or DLink, Apple, any router that supports 6-in-4 (protocol 41) tunnels. You could also write your own template script to output the information in the format your router requires – it’s a simple batch file.

Final thoughts

If you want ipv6 connectivity, and you do not intend to gain it through your router, gogonet should be your first stop. The gateway6 client shows that gaining ipv6 connectivity, and setting up routing to everything else in your network, does not have to be complicated, or involve lengthy command-line sessions.

If you want to terminate your tunnel on a router, give Hurricane Electric a look. Their tunnel setup does not require a client running on a PC – on the other hand, that means it won’t present the router configuration commands to you on a silver platter, either. Consider also that freenet6 has a somewhat patchy record when it comes to reliably handing out your delegated prefix: In the past, prefix numbers would change, and that messes with your router setup and your RDNS.

I had, when I first started writing this series, deliberately placed go6.net behind Teredo and SixXS: I knew it was going to be far easier to set up than those other two, and wanted to progress from “complicated” to “easy” as the series went on. I had not counted on getting stuck quite so hard on routing with the SixXS aiccu setup. In hindsight, covering the easiest method first might have been cleverer.