Unique Local Addresses (ULA)

What is a ULA ? IPv6 ULA's are used similarly to IPv4 local adresses e.g. 10.0.0.0/8. A good reference and random ULA generator can be found here:
Unique Local IPv6 Generator

The 40-bit random part of the ULA makes it statistically unlikely that you will have a collusion with any other randomly generated ULA /48 prefix. Whether merging networks together or VPN use, a truly “unique” ULA is worth the effort.

Tip → If the IPv6 address begins with fd it is a ULA.

Some other examples, fd00::/48, fd01:1:1::/48, fd00:dead:beef::/48 are all examples of ULA's, but not very “unique” and should be avoided in practice.

As an alternative to using a web site for generating ULA prefixes, AstLinux has a CLI command unique-local-ipv6 for generating random ULA /48 prefixes:

# unique-local-ipv6
fd06:d115:91f1::/48

The unique-local-ipv6 command generates a new random ULA every time it is run.

Keep in mind you only need one ULA/48 prefix for your complete network. You will later carve the ULA/48 into ULA/64's for IPv6 autoconfig use. Since these are static and manually assigned, develop a method to keep track of the assigned /64's.

Global Unicast Addresses (GUA)

What is a GUA ? IPv6 GUA's are globally routable IPv6 addresses in the 2000::/3 prefix space.

Tip → If the IPv6 address begins with 2 it is a GUA.

If you want to connect to an IPv6 server on the internet, your device must either have a GUA, or a ULA with ULA→GUA prefix translation available.

Network Prefix Translation (NPTv6)

Is NPTv6 some sort of IPv6 NAT ? While NPTv6 is implemented in the Linux kernel NAT table, it is not the TCP/UDP port altering NAT we are familiar with IPv4. NPTv6 is a simple 1:1 mapping of one prefix to another prefix, the TCP/UDP ports remain the same. Often NPTv6 is stateless, but is implemented with the statefull firewall in AstLinux, so connection tracking occurs.

Note → NPTv6 is not the same as NAT66, which should be always avoided.

The benefit of NPTv6 is to have a network of static, never changing ULA's that can be mapped to a GUA of the same prefix length for internet access. With that in mind, if your ISP provides you a GUA/60 prefix, you should only assign ULA/60 prefixes on your network so a 1:1 mapping can occur. This will allow inbound EXT→LAN forward rules to be applied in the firewall using static ULA addresses. If your ISP provides you a GUA/56 prefix you should assign ULA/56 prefixes on your network, etc. .

Tip → If your ISP only provides a GUA/64 prefix it is not possible to perform a 1:1 mapping to a ULA/64 that won't collide with the GUA/64 prefix, but for only outbound initiated connections you can map a ULA/60 to your GUA/64 and the statefull firewall's connection tracking will properly return the packets to the ULA address.

Note → A “Reboot System” is required to apply any changes related to the interface settings.

Configure Network Prefix Translation Firewall Plugin:

Click Configure Plugin, set ENABLED=1 and …

Define the global prefix, since we are using dynamic DHCPv6 only specify the prefix length:

NET_PREFIX_TRANSLATION_GLOBAL_PREFIX="::/60"

Define the local prefix, this must be fully qualified:

NET_PREFIX_TRANSLATION_LOCAL_PREFIX="fd06:d115:91f1::/60"

Tip → ULA's are /48's but you typically want a symmetric mapping so inbound
firewall rules work. Only special situations may desire non-symmetric mapping.
In general use the same _LOCAL_PREFIX length as the _GLOBAL_PREFIX length.

Since NET_PREFIX_TRANSLATION_UPDATE_ON_STATUS=1 is enabled by default, when the DHCPv6 client detects a change in the global prefix, the Network Prefix Translation Firewall Plugin will be called to update using the new global prefix.

Important → Carving the ULA/48 into ULA/64's that will result in a 1:1 mapping to a GUA/60 is important to understand. In the example above we used IPv6/nn entries of <ula>:1::1/64 and <ula>:2::1/64 (where <ula> is shorthand for fd06:d115:91f1). For a ULA/60 the largest possible sequence is <ula>:0::1/64 to <ula>:f::1/64, which are 16 possibilities, but be careful the first <ula>:0::1/64 best not be used since that will share the same address space as the first “Assign GUA Prefix”, since they are indexed 0, 1, etc. . If we had selected a second “Assign GUA Prefix” (index 1) it would be best to start the IPv6/nn entries with <ula>:2::1/64 or higher, best practice is to start a little higher.

Suggestion on how to manage your ULA's with a GUA/60 prefix:

GUA Prefix Delegation

<gua>0::1/64, <gua>1::1/64, etc.

(dhcp6c automatic indexing 0, 1, etc.)

ULA's with Assign GUA Prefix

<ula>:5::1/64, <ula>:6::1/64, etc.

(use IPv6/nn in Network tab with “Assign GUA Prefix”)

ULA's for Local IPv6

<ula>:a::1/64, <ula>:b::1/64, etc.

(use IPv6/nn in Network tab with “enabled”)

ULA for OpenVPN

<ula>:f::1/64

(use Network IPv6/nn in OpenVPN Server Configuration)

For completeness, a ULA/56, the largest possible sequence is <ula>:00::1/64 to <ula>:ff::1/64, which are 256 possibilities. In the GUA/56 with ULA/56 case, it is a good idea to start your IPv6/nn entries with <ula>:10::1/64 or such to leave plenty of room for reserved “Assign GUA Prefix” entries since you have plenty to use.

Suggestion on how to manage your ULA's with a GUA/56 prefix:

GUA Prefix Delegation

<gua>00::1/64, <gua>01::1/64, etc.

(dhcp6c automatic indexing 00, 01, etc.)

ULA's with Assign GUA Prefix

<ula>:10::1/64, <ula>:11::1/64, etc.

(use IPv6/nn in Network tab with “Assign GUA Prefix”)

ULA's for Local IPv6

<ula>:20::1/64, <ula>:21::1/64, etc.

(use IPv6/nn in Network tab with “enabled”)

ULA for OpenVPN

<ula>:f0::1/64

(use Network IPv6/nn in OpenVPN Server Configuration)

OpenVPN Server IPv6 ULA

The use of ULA's is particularly useful with VPN's since ULA's are static. Additionally, VPN's can route ULA's in a tunnel just as easily as GUA's.