I first started outlining some of the difficulties with Unique Local Addresses (ULA, RFC 4193) in the blog post ‘IPv6 ULA and NAT. Is It Better Than Global Unicast?’ back in January 2014.
As a refresher, ULA is the special reserved prefix of fc00::/7 that is further divided into fc00::/8 (which is not supposed to be used) and fd00::/8 (which is supposed to have randomly assigned /48 prefixes assigned out of it) and is not routable on the public IPv6 Internet.
Then Tom Coffeen started putting a clearer picture on some real structural and architectural problems with ULA in his two part blog post ‘3 Ways to Ruin Your Future Network with IPv6 Unique Local Addresses (Part 1 of 2) (Part 2 of 2)’, which covered:
- Why you shouldn’t reflexively deploy ULAs and NAT66.
- How failing to randomize ULA prefixes could cause problems (and cause you to end up DEAD:BEEF!).
- Understanding the differences between fc00::/7 vs. fc00::/8 vs. fd00::/8.
Scott Hogg provided some more clarification around NAT and IPv6 (and when it might be useful) in his recent blog post You Thought There Was No NAT for IPv6, But NAT Still Exists. He also clarifies that ULA isn’t a great architectural design decision when considering leveraging NAT, even if that is the first instinct for those coming from IPv4-only design backgrounds.
All of these are reasonable reasons and explanations of why to not use ULA. But it seems those arguments aren’t being accepted by some who are coming from an IPv4-only network design background. Many want a network design that matches ‘one for one’ in design and architecture to what they have deployed in IPv4 with NAT. There are a variety of reasons for this (that aren’t worth going into here — read RFC 4864) but let us just assume that NAT is what you want because you are comfortable with it. Because of that, you might overlook all the above arguments and simply declare that your design ‘requires’ ULA.
I want to go further (all the way, in fact) and assert unequivocally why ULA is fundamentally broken and why you should NOT use it at all in your enterprise network — especially not in the manner of matching what you are doing with IPv4-only — with the following statement:
ULA is functionally useless in any IPv6 deployment that has dual-stack operating anywhere.
Let that sink in. If you run dual-stack anywhere in your network as part of your IPv6 adoption, ULA will basically not work at all for you. So, unless you are one of the very few who are doing greenfield IPv6 deployments that will NEVER have IPv4 running on their networks, this means the above statement applies to YOU. In other words, you CAN’T use ULA unless you want broken IPv6 reachability. Let’s go through why this is the case:
- ULA per RFC 6724 is less preferred (the precedence value is lower) than all IPv4 (represented by ::ffff:0:0/96 in the table).
- Because of the lower precedence value, if you have IPv4 enabled on a host, it will use IPv4 before using ULA.
- Happy Eyeballs (RFC 8305) will not change the source address selection process on a host. It will only modify the destination sorting process.
- The client will source the traffic from the IPv4 address, meaning it will require a corresponding IPv4 destination address.
- Point 4 means that, even with A and AAAA DNS records, a client will choose the A record to get an IPv4 address for the destination
Congratulations, you have deployed IPv6 but by using ULA you have a network that only runs IPv4. In other words, ULA is set up and ‘working’ in your dual-stack network, and you think you have a working IPv6 network, but the result is that NO IPv6 traffic is going across the network. So why bother deploying ULA at all?!
Yes, it is theoretically possible to change the precedence value of ULA in the Prefix Policy Table on hosts. But you would have to do this on EVERY host in your network. Further, it might not be possible to even modify it on some devices in the network — think Internet of things (IoT), printers, video cameras, embedded devices, and so on. The effort to make that change versus just using Global Unicast Addresses (GUAs) is not worth it from a technical debt standpoint.
Let’s now move on to the use case of IPv6-only networks. With no IPv4 to preempt ULAs, it should be possible to use them successfully. If a ULA is the only address available on a host, it should source the traffic from that address every time, which means IPv6 should work as expected.
Here we arrive at all the same arguments we started with at the beginning of this post that Tom and Scott articulated in their blogs on ULA — namely, that the NAT66 + ULA design option is not gaining you any advantage. The pseudo-randomization of ULA Global IDs to form unique /48s (RFC 4193) will cause long-term scaling issues or, if ignored, potentially overlapping ULA space (something with private IPv4 we have been trying to fix from the very beginning by using IPv6).
All of these are serious pitfalls that arise when attempting to use ULA. The simple and more elegant answer is to simply leverage GUAs. This was their intended purpose, by design! IPv6 was architected and designed from the very beginning so that ALL hosts would have a GUA for the purpose of connecting to a given network. Trying to work around this fundamental assumption will only hurt your design and make your operational issues worse. Don’t take on the technical debt of using ULA in your network, as the cost will be several times higher than simply using GUA.
Don’t be one of those network architects who ruins your IPv6 deployment; stay away from ULA. It will cripple your IPv6 adoption as you move through dual-stack to IPv6-only and make the transition much harder. In addition, you won’t be able to run or test any IPv6 traffic where IPv4 is also running (most environments), which means you are gaining no operational experience using IPv6.
Also, for those running IPv6-only networks, you have additional considerations. There is one issue with IPv6-only (or IPv4-only networks) and Windows. Windows has a dual-IP layer design for its network stack.
For Windows, this means it is not possible to turn off IPv6 or IPv4 in the networking stack. For Windows, even in IPv6-only network deployments, the host will still have an IPv4 address. It will have one because it will leverage the Automatic Private IP Addressing (APIPA) address range of 169.254.0.0/16 and auto-provision an IPv4 address on the host interface. For Linux and MacOS, it is possible to turn off the IPv4 stack and run in a true IPv6-only setup. The result is that you could have some very inconsistent behaviour in some situations with Windows hosts during boot and initial setup. This could be very disruptive when trying to bring systems online.
The reverse is true also. In IPv4-only networks, the Windows host will automatically provision an IPv6 link-local address and start doing basic name discovery on the local link. This means Windows hosts will use Link Local Multicast Name Resolution (LLMNR) to discover other Windows hosts and will exchange information via IPv6. Remember, IPv6 is on by default and is preferred by all operating systems, not just Windows. So even in IPv4-only networks today, there is still a lot of link-local IPv6-related traffic happening — often unbeknownst to the technical team operating both the network and hosts! Therefore, it is critical to understand the default setting for the OS and how the network is set up.
Fire up a packet sniffer and see what IPv6 traffic you already have going on in your network. You might be surprised!
You can find me on twitter as @ehorley and remember…
IPv6 is the future, and the future is now!
Originally posted on the Infoblox IPv6 CoE Blog.
Note: Many of the points made in this post have now been formalized in an IETF informational draft. Stay up to date via the data tracker.
Ed Horley is CEO of HexaBuild.io, Co-Chair of the California IPv6 Task Force (CAv6TF), authored the Apress Press book on Practical IPv6 for Windows Administrators, and co-hosts the IPv6 Buzz Podcast on the Packet Pushers.
The views expressed by the authors of this blog are their own and do not necessarily reflect the views of APNIC. Please note a Code of Conduct applies to this blog.
One more blog post that massively fail to understand how ULA should work.
Why ? Because it describe the network as if ipv6 “simply” replaced ipv4. So ULA is private addressing with NAT at the end. And then people continue saying “just use GUA”.
Why ? Why do people still want to see it this way ?
It has no meaning !
ULA provide stable local addressing that you can manage at human level. That way you can manage your addresses there, in a meaningfull way. And those addresses never change. And obviously, you have GUA in parallel. But no,no one wants to understand that.
But you simply have to have several addresses per interface on your local networks :
global, with random host part or not and ULA, probably with stable host part
On my present computer, I have two ULA and two GUA. As it was intended to be if you use ULA.
ULA is not broken. Use it if it fits your need.
I note that Ubuntu (and quite possibly Linux in general) has been prioritising ULAs ahead of IPv4 for some time now – i.e. it isn’t conforming to RFC 6724 as written. This is a good thing!
I encourage the authors of the informational draft cited above (https://datatracker.ietf.org/doc/draft-buraglio-v6ops-ula/) to continue to formalise the changes required to RFC 6724 in order to capture the original intent of the RFC.
ULAs most definitely do have a place in IPv6 networking, but NAT doesn’t!