Skip to content

Instantly share code, notes, and snippets.

@timothyham
Last active June 29, 2024 16:42
Show Gist options
  • Save timothyham/dd003dbad5614b425a8325ec820fd785 to your computer and use it in GitHub Desktop.
Save timothyham/dd003dbad5614b425a8325ec820fd785 to your computer and use it in GitHub Desktop.
A Short IPv6 Guide for Home IPv4 Admins

A Short IPv6 Guide for Home IPv4 Admins

This guide is for homelab admins who understand IPv4s well but find setting up IPv6 hard or annoying because things work differently. In some ways, managing an IPv6 network can be simpler than IPv4, one just needs to learn some new concepts and discard some old ones.

Let’s begin.

First of all, there are some concepts that one must unlearn from ipv4:

Concept 1

Don’t pick numbers. Because IPv4 space is small, we are used to managing them, thinking about them, memorizing them. So we pick numbers like 1, 10, 20, 101, etc. However, IPv6 address space is so big, it’s better to let the computers pick the numbers randomly from the large address space, and not limit yourself to small numbers. Use DNS, so you can remember names and not numbers. Therefore, never pick your own numbers! This is fundamental to IPv6, and going against this concept will make everything harder, so don’t do it.

Concept 2

IPv6 will have multiple addresses per interface. This is normal. Fighting this will also make everything harder. Just accept the fact that a host will have multiple addresses.

The above concepts are what makes IPv6 different from IPv4, so it’s better to let them go as soon as possible.

Ok, now on to IPv6.

Concept 3

IPv6 addresses are 128 bits long. You have the first 64 bits as the routable part, called the prefix, and the last 64 bits as the interface identifier. Your ISP will give you the first 64 bits, and your host machine will have the last 64 bits. Furthermore, IPv6 subnets are always 64 bits or /64. This will make life much simpler for you as a network admin—no more thinking about subnet masks.

The addresses are displayed as 8 groups of hexadecimals, like this: 1111:2222:3333:4444:aaaa:bbbb:cccc:dddd. The first 4 groups (1111:2222:3333:4444) is the prefix, and the last 4 groups is the machine or interface identifier (aaaa:bbbb:cccc:dddd). Some runs of zeros can be condensed as ::.

There are some common prefixes to remember. Globally routable addresses start with a 2 or possibly 3, like 2xxx::. Link local start with fe80:: and ULA (Unique Local Address, similar to private addresses in IPv4) start with fdxx::. Memorize these. These are not any harder to remember than knowing 192.168.x.x and 10.x.x.x are private IPv4 addresses.

Concept 4

IPv6 uses Router Advertisement (RA), not DHCP. The difference is that whereas DHCP will give the asking client the exact IP address, while keeping track of a lot of state (like MAC address, lease time, etc etc), RA just advertises the prefix. When the client sees the RA, it will self-configure its own IPv6 address using the advertised prefix plus its own unique identifier. This is called Stateless Address Auto Configuration (SLAAC), and it removes the need for a stateful DHCPD server. For a given prefix, the interface will always pick the same identifier, (in fact, the eui-64 algorithm will pick the same identifier across multiple prefixes), so once a client picks an IPv6 address, you can assume it’s stable. A slightly different algorithm will pick a different identifier for different prefixes, but these will also be stable for each prefix.

There exists stateful DHCPv6 servers which can hand out full IPv6 addresses just like IPv4 DHCP, but Android does not support these, and are not needed for a fully functional IPv6 setup. As tempting as it is, there is no need for an IPv6 DHCP server on your LAN.

Concept 5

Prefix Delegation. As seen from concept 4, routing is done by advertising the prefix. So how do I get this prefix from the ISP? You ask for it via prefix delegation (PD). With IPv4, when your router connects to your ISP, you get one public address for the WAN, and you use a picked private address like 192.168.0.0/24 for your LAN. With IPv6, since you want a globally routable address for hosts on your LAN also, you need to ask the ISP for a routable prefix.

After your router connects to your ISP, the router can ask for prefix delegation. RFC suggests that the ISP should give you a /56 address space, giving you 255 routable subnets, but some (looking at you, Comcast) gives you only one /64 by default, which is just one routable subnet. Comcast can give you a /60, or 16 routable subnets, but you have to ask for it via config.

As a side note, if you get a /56 PD, your prefix will be something like 1111:2222:3333:4400, where the zeros can be replaced by a hexadecimal number of your choosing, allowing you to have 256 subnets. A /60 prefix delegation is something like 1111:2222:3333:4440, where the zero can be replaced by one hexadecimal number, giving you 16 subnets.

Once you have the prefix, your dhcpv6 client will assign that prefix+address to your LAN interface, and something like radvd can Route Advertise that prefix on that interface. Other hosts on the LAN can now automatically configure their own prefix+identifier IPv6 addresses.

Concept 6

ULA (unique local addresses). These are like private addresses from IPv4, but with a much larger address space. Remember Concept 1: don’t pick numbers. Use a website to randomly generate a ULA prefix. For company level LANs, this will allow multiple LANs to be merged in the future without conflict.

Once you have a ULA, assign it to your LAN interface. Radvd will pick it up and advertise it to the rest of your LAN, giving all your hosts a second IPv6 address.

You want to use these ULA for all your LAN communication. If you want to reach your printer or a media server, put their ULAs in the DNS and not the globally routable one. The reasons are that 1) for residential internet, the globally routable prefix can change and 2) if your ISP goes down for some reason, your LAN can function without disruption.

Now that we’ve gone through the concepts, let’s setup the LAN.

  1. Configure your router to get IPv6 from your ISP. Most Linux distros will have instructions on setting up IPv6, RA, and PD on your Linux router.

  2. Configure your LAN with a ULA. Now your hosts will have a globally routable address and a local address.

  3. For servers on your LAN that you want to talk to, add their ULA to the LAN DNS. Heck, you could even add ULA to the global DNS, but if your internet goes out, that will stop working.

  4. For your externally visible servers, use dyndns type service, and update it with the globally routable address. Residential internet will rotate the prefix over time (the prefix is dynamic), so this is the same as running a server on a residential dynamic IPv4.

  5. For firewall, drop all inbound packets by default. For externally visible servers, you can match the last 64 bits only, so that changing prefixes don’t affect the firewall rules. For nftables, the syntax to match ssh and ping on ipv6 identifier is

    chain forward { 
        type filter hook forward priority 0; 
        policy drop; 
        
        # allow forwarding of some incoming connections to ::aaaa:bbbb:cccc:dddd
        ip6 daddr & ::ffff:ffff:ffff:ffff == ::aaaa:bbbb:cccc:dddd tcp dport 22 accept
        ip6 daddr & ::ffff:ffff:ffff:ffff == ::aaaa:bbbb:cccc:dddd icmpv6 type {echo-request} accept 
        
        ct state vmap { established : accept, related : accept, invalid : drop }
    }
  1. For some reason, people are mistakenly getting that ULA could be used for IoT devices. Let's think about this for a minute.

If an IoT device must be disconnected from the internet entirely, in IPv4, it would get its own subnet away from your other hosts, without a route to the internet. In this use case, ULA only subnet would behave exactly the same way.

However, for IoT devices that need the internet to function, for example a SmartTV or SmartFridge, having only a ULA means the device would make a request from its ULA to the router, the router must do NAT in order to forward reply packets back to the device. This adds an unnecessary NAT in the path! Might as well let it have a globally routable IPv6 address, and protect it by blocking incoming connections at the firewall, like all other devices on your LAN.

@0x3333
Copy link

0x3333 commented Jun 10, 2024

radvd = Router Advertisement Daemon

Router Advertisement Daemon is an open-source software product that implements link-local advertisements of IPv6 router addresses and IPv6 routing prefixes using the Neighbor Discovery Protocol(NDP) as specified in RFC 2461.

Source: https://en.wikipedia.org/wiki/Radvd

@0x3333
Copy link

0x3333 commented Jun 10, 2024

In Concept 6 it says:

...This adds an unnecessary NAT in the path!...

To the best of my knowledge, IPv6 doesn't have NAT, what do you mean by that?

@juliaszone
Copy link

juliaszone commented Jun 11, 2024

In Concept 6 it says:

...This adds an unnecessary NAT in the path!...

To the best of my knowledge, IPv6 doesn't have NAT, what do you mean by that?

NAT in this case has nothing to do with protocol version, it's concept can also be done with IPv6. You can create a table named ip6 nat in nftables and do your NAT like on IPv4. However, this should not be done unless absolutely necessary.

@Michagogo
Copy link

For your externally visible servers, use dyndns type service, and update it with the globally routable address. Residential internet will rotate the prefix over time (the prefix is dynamic), so this is the same as running a server on a residential dynamic IPv4.

The one difference is that now that has to be set up on the device/server itself, or at least on a per-device basis with a mechanism that’s able to discover the address of the target device (or have a fixed suffix that it knows how to append to the network address), as opposed to IPv4 (with port forwarding) where one device (either the router, or any one host) could do it on behalf of the whole network.

@timothyham
Copy link
Author

For your externally visible servers, use dyndns type service, and update it with the globally routable address. Residential internet will rotate the prefix over time (the prefix is dynamic), so this is the same as running a server on a residential dynamic IPv4.

The one difference is that now that has to be set up on the device/server itself, or at least on a per-device basis with a mechanism that’s able to discover the address of the target device (or have a fixed suffix that it knows how to append to the network address), as opposed to IPv4 (with port forwarding) where one device (either the router, or any one host) could do it on behalf of the whole network.

You could still have your router update dns records for all the servers when it detects a prefix change, as long as the servers are using eui-64.

@timothyham
Copy link
Author

https://blog.apnic.net/2022/06/10/iot-devices-endanger-ipv6-privacy/ https://dl.acm.org/doi/10.1145/3544912.3544915

I trust my ISP to at least rotate the prefix for me, but how can I rotate the suffix, if a device in LAN is not cooperative, because it is IoT spyware like a smart TV ignoring privacy extensions and uses legacy EUI-64?

IPv6 is far from ready unless I can assign any device legacy DHCP style 100% randomized suffixes. I seriously don't want to deal with this and rather NAT to IPv4 if I was forcibly IPv6 terminated to WAN.

I would think that your SmartTV is hitting a fixed list of tracking websites, with a unique token in the payload, regardless of whether your ISP is rotating IPs or not. I don't think IPv6, even with privacy extension, is going to protect your privacy there.

@lpar
Copy link

lpar commented Jun 17, 2024

I'd be inclined to put in a note that now is a good time to start using Zeroconf rather than trying to memorize ULA addresses. (Microsoft were the last holdout, and apparently Windows 10 now supports it.)

@pedrompcaetano
Copy link

This has some nicely compiled information about whether filtering icmp or not:
http://shouldiblockicmp.com/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment