From the IPv4 world to IPv6


Internet connection

Your router at home can connect to the internet via three different types of connections:

  • IPv4-only (with public IPv4 address)
  • Dual Stack (with public IPv4 and public IPv6 address)
  • Dual Stack Lite / DS Lite (with public IPv6 and private (to the ISP) IPv4 address)

DS Lite - Incoming connections

While nowadays IPv4 and Dual Stack connections just work fine, DS Lite might make you scratch your head in regards to incoming connections.

The reason is IPv6 is not backwards compatible to IPv4

Let's imagine a server (like a mailserver) would be assigned with an IPv6 address only. This means, that no client with just an IPv4 address would be able to connect. Now imagine you run a server like FTP or VPN in your LAN. If your internet router is connected with DS Lite, it can be accessed from the outside via IPv6 only.

Back in 2018 this excluded all of the mobile devices in Germany (e.g. connected via Vodafone or T-Mobile ISP).  Btw: A solution for this problem would be "port mapping" which I won't address here.

Btw: If your home router currently connects via IPv4 only, try to enable support for IPv6 via your router settings. If you're lucky you can "switch" from IPv4-only to Dual Stack or IPv6 via tunnel. In any case, you'll be assigned a IPv4 AND IPv6 address.

DS Lite - Outgoing connections

Now you might wonder, if your DS Lite account is limited to IPv6 incoming connections only, how is it possible you can still connect to external IPv4 addresses?

This is possible due to your ISP using a IPv6 tunnel carrying IPv4 information in his own network. From a high level point of view this is how it works:

As you can see your ISP doesn't need to buy a public IPv4 address for each and every customer, like you.

If your device supports IPv6 addresses it will connect "directly" to the target IPv6 server. Actually the target server will see your PC's IPv6 address as the origin address, no more hiding behind your routers public IP.

Different types of IPv6 addresses

Did you notice in the chart above, that your PC uses a public IPv6 address? So what about private addresses? Actually there is nothing like a public or private address in the world of IPv4. Something similar is available, but it's called differently. Let's start from the beginning:

From a high level view an IPv6 address is made of two parts:

  • Prefix
  • Suffix - Interface identifier

Let's take a look some of the different types of IPv6 addresses:

Link-local (prefix FE80::)

If you run ipconfig / ifconfig on your device you'll see an IPv6 address that starts with prefix FE80::
This is a constant address which is immediately and automatically available and can be used for communication inside your LAN, across switches but not across routers, to other Link-local addresses. Link-local addresses in IPv6 exist on each interface, regardless of whether the interface has an address assigned from DHCP or is configured using another method.

The prefix FE80:: is always the same and followed by the suffix (aka interface identifier). Latter is generated automatically (usually based on MAC address).

Optional: Unique Local Addresses - ULA (prefix FCxx: to FD:xx)

Equivalent to reserved private addresses in an IPv4 network (like 192.168. or 172.16) , that start with FCxx: up to FDxx: and cannot be routed to the internet. They are routable only within the scope of such private networks, but not in the global IPv6 internet. In a private home network you won't need ULAs.

Global Unicast (prefix from ISP)

Equivalent to public IPv4 addresses but no longer limited to a router. Instead every device in your local network can be assigned a global address that is routable. So how is this done?

Obtaining an IPv6 address

Three ways are available for a device to obtain its IPv6 address:

  • manual configuration
  • automatic Stateful Address Autoconfiguration (via DHCPv6 server, similar to normal DHCP server)
  • automatic Stateless Address Autoconfiguration (aka SLAAC)

In a nutshell SLAAC (auto configuration without a DHCP server) is always used for link-local addresses and in home environments usually the default for global unicast addresses.

Using the Neighbor Discovery Protocol (NDP) client devices send a Router Solicitation message (a special ICMPv6 packet type) to locate the local router(s). The router itself will answer with a  Router Advertisement message. This message will be sent periodically even without a request. It includes several network configuration information. First, the network prefix provided by your ISP that is used to generate a Global Unicast address via SLAAC. The prefix combined with the 'interface identifier' part generates the global address. Connected to the same ISP this address will never change. The RA message can also tell the client to obtain a Unique Local Address (M Flag) from a DHVPv6 server. Additionally or alternatively it can tell the client to obtain other configuration information like ipv6 DNS Server (O Flag) from a DHCPv6 server.

Recommendation for home networks:

I've configured my local router to send the O flag and omit the M flag. This way all ipv6 clients will have assigned a Link-local address and a Global Unicast address. Additionally my Linux DHCPv6 informs clients about where to find the pi-hole ipv6 DNS server.

Privacy Extensions (no more static IPv6 address)

Someone can now assume that a specific device will always communicate from the same source ip address (in case the ISP hasn't changed). This is only true as long "Privacy Extensions" hasn't been enabled. All modern operating systems have Privacy Extensions enabled by default and as such you'll end up with IPv6 address whose 'interface identifier' is not based on the mac address (but a random hash). Windows 10 for example will show the real and fake address if you run ipconfig. The 'temporary address' is used for outgoing connections until the next reboot. You definitely want to disable this for services (like FTP) or at least using a DNS name.

Linux - Disable Privacy Exentions

execute the following commands and reboot:

cat >> /etc/sysctl.conf <<EOT
sysctl -p