18 minute read

IPv6 with OpenWrt

There are at least three ways to use IPv6 ith OpenWrt: Prefix Delegation, NDP Proxy and 6in4 tunnel with Hurricane Electric or the like. In this video we will walk through the configuration for each of them.

The IPv6 from Scratch Episodes are here:

Episode 1 Episode 2

Watch the video on YouTube

Click to view the entire transcript (IPv6 with OpenWrt) I have some good news and some bad news for you. First the good news: IPv6 is fully supported by OpenWrt. Because OpenWrt is Linux and Linux does support it. Now the bad news: If and to what extend you can really use IPv6 with OpenWrt is largely determined by your ISP – that’s the people who provide internet access to you. Not by OpenWrt. Just because you have an IPv6 address on your router does not necessarily mean that you can do IPv6 in the way it had been intended by its inventors. But we’ll see into that in detail. There is however some more good news: Even if you only get IPv6 in a crippled way, then OpenWrt can help you to get the most out of it. Either with prefix delegation or with NDP proxy or with a 6in4 tunnel. Let’s walk through our options. (Option 1 – Prefix delegation) In an ideal world, your ISP would delegate an IPv6 prefix to you. That means that the first 40 or 48 or 56 bits of the IPv6 address are fix and you could do whatever you wanted with the remaining bits. How can you find out if you have prefix delegation or not? Look at the status page of Openwrt. If you have IPv6 enabled, then you should see an IPv6 Upstream here. And if your ISP does delegate a prefix, then there would be an entry called “Prefix delegated”. In my case it’s a 59 bit prefix. My ISP delegates a 56 bit prefix but this router is inside a test lab sandbox and there are some more routers in between. If you don’t see IPv6 at all, then either your ISP is not giving it to you or you have previously disabled it. Let’s check the relevant settings quickly. And this is on an OpenWrt router with default settings. First we go to network – interfaces. There should be interfaces for LAN and for WAN and also for WAN6. The relevant settings on the WAN6 interface are DHCPv6 client as a protocol, then Request-IPv6 address should not be set to disabled and in order to actually get assigned a prefix you should either select a fixed length setting or chose Automatic from the drop down that is titled “Request IPv6-prefix of length”. I have set it to Automatic. If we want IPv6 prefixes to be delegated further down the chain, for example to the LAN interface, then we would also tick this box on the advanced tab that is titled “Delegate IPv6 prefixes”. Watch what happens when I untick that box. You can see that my LAN interface has an IPv6 address in the 2003:de range. That’s Deutsche Telekom. Now let me go to the advanced settings of the WAN interface and remove the tick from the IPv6 prefix delegation box. Save and apply. Checking back on the LAN interface, you can see that the 2003:de address has now disappeared. The only remaining IPv6 address on this interface is the Unique Link (ULA) Address in the fd something range. If I go back to the advanced settings of the WAN interface and tick the box back in, then save and save and apply, then the global IPv6 address comes back on the LAN interface. Before we move on let’s quickly talk about that fd something address here. You may remember the IPv6 from scratch video where we talked about scopes. This unique local address comes from a ULA scope that we can define here on the network interfaces on the Global Options tab. There is an IPv6 ULA prefix tab here. This is randomly generated at install time. You could either set it to something more simple such as fddd::/48 or you can as well safely delete it – in my opinion there is no point in having ULA addresses if you have prefix delegation. You can safely do everything with global and link local addresses. So let me delete it. Save and Apply – see? The address has disappeared from the LAN interface. (Special case: PPPOE) Before we dig deeper into the LAN configuration, let’s quickly check two more possible situations. Maybe you had deleted your WAN6 interface in the past or your WAN interface is a PPPOE interface. So let me delete my WAN6 interface and recreate it. Add new Interface, select DHCPv6 client as a protocol and now – rather than selecting the same eth1 interface like the WAN interface has, I now tell OpenWrt that this is a so called alias interface. It’s the same interface like the wan interface but we do not need to do PPOE again, just DHCPv6. This way you can run multiple protocols over one interface. Just don’t forget to assign it to the right firewall zone, for instance WAN in my case. Save and apply and – here we go – we get everything back. IPv6 prefix and address on WAN6 as well as on LAN. (Firewall rules WAN side) You remember that IPv6 needs the ICMPv6 protocol to function correctly? That means that we might need to tweak the firewall settings a little bit – especially if you have deleted the corresponding rules in the past because you didn’t want to have IPv6 in your network. Let’s head over to Network- Firewall. Here on the traffic rules tab there are just three or four rules that we need to check on really. First of course we need to let in traffic on UDP port 546 to the router itself for DHCPv6. The next rule lets in any ICMPv6 traffic from any device on the local link. That would be the ISP’s router really. The next two rules actually let in ICMPv6 traffic from any device in the internet and will even forward it to any zone. But we will limit it in two ways. First, we only need a certain number of ICMPv6 types to be let in. And second, we will limit the number of packets to 1000 per second in order to be protected against flooding attacks. I will put a dump of the relevant firewall configuration into the cheat sheet repository on my github site. The link is in the description of the video. (LAN interface settings) Nice – now let’s quickly walk through the settings of the LAN interface. After all, what we want is that OpenWrt assigns or suggests IPv6 addresses to our clients in the LAN. If you remember the IPv6 from scratch videos then you know that we have essentially three possibilities to assign IPv6 addresses to our nodes. We could give them a static address, we could use DHCPv6 and/or we could use SLAAC. Let’s check the settings for this. I edit the LAN interface and go to the advanced tab. We already know this tick box from the WAN interface. Just now – we don’t want to delegate IPv6 prefixes further down the stream as presumably you don’t have any more routers behind the LAN interface. So let’s untick that box here. Next – the IPv6 assignment length. The network part of the IPv6 addresses are the first 64 bit – you remember? As we don’t want to delegate further down, we therefore set the assignment length to 64 bits. That means that the LAN network will now have its own full /64 network but we can’t subnet any further behind that interface. But which subnet will the LAN interface get? I have tuned the WAN interface to have a /60 prefix which means that I can use the last 4 bits of the network mask for various interfaces. That’s what the IPv6 assignment hint does. Let’s say I wanted the LAN to be subnet 5 – then I would set the IPv6 assignment hint to 5. The IPv6 suffix here defines which address my router will get inside that subnet. Usually this is set to ::1, but let me set it to 99 so that we see what it does. Save. Now I save and apply. Look what this did. My LAN interface now has a /64 IPv6 address. The subnet is 74d5 (it was 74d0 before) – that’s because of the assignment hint which I had set to 5. And the node address is ::99. Let’s add another interface, for example guest. I give that one another IPv4 address range, then I go to the advanced tab and put in the same values except this time I use let’s say “a” as IPv6 assignment hint. I would then expect the guest network to have the subnet 74da rather than 74d0 or 74d5. Save and apply. I did some more things here like define a device and a firewall zone and I had to restart the networking service so that OpenWrt applied the changes. But once I did that, as you can see - the subnet on the guest interface is now 74da as expected. By the way, when I stop the WAN6 interface, then the IPv6 addresses of the LAN and guest interface go away. Once I restart it, then they come back. In other words – the easiest way to shut down IPv6 in your whole network is to just stop the WAN6 interface. When you bring it back up, IPv6 comes back. Nice and clean. Cool, now let’s have a look at the DHCP settings. How do we tell our clients in the LAN that they can get IPv6 addresses from OpenWrt ? (Configuring DHCPv6 options) If we want to have global IPv6 addresses in our LAN, then we need to let our clients in the LAN know which IPv6 prefix they should use, which IPv6 router and a couple more things like the address of the DNS server. We can do this either via router advertisement or via DHCPv6 or – we can mix both mechanisms. Here is how. I go to Network-Interfaces, then I click on “Edit” next to the desired interface – let me use the LAN interface for starters. Under “DHCP Server” I can see the IPv4 DHCP settings. If the DHCP Server is not yet configured, then you get a button here to enable it. What I am interested in, are the IPv6 settings. Here I can tell OpenWrt that I want to have two things. First, I want this router to be advertised using ICMPv6 router advertisement. For this I select “server mode” in the RA-Service dropdown. But I also want this router to be an IPv6 DHCP Server. Therefore I also select “server mode” in the DHCPv6-Service dropdown. My router shall also serve DNS so I do check the “Local IPv6 DNS server” tick box. Please do not tick the designated master tick box and also set the NDP-Proxy dropdown to disabled. We don’t need this here, we’ll talk about this in the second scenario. On the next tab (that is titled IPv6 RA settings) I can define some more details. First – do I want my router to be the default router? I set this value to automatic. Now for the interesting part. The tick box “enable SLAAC” actually decides whether we allow our clients to do stateless automatic address configuration. If we tick this box, then the corresponding flag in the router advertisement packet gets set. In the next box we can configure some more flags for the router advertisement. If we set the managed config flag, then this tells our clients that they should request an IPv6 address via DHCPv6. If we tick the “other config” box here then this means that we let our clients know that they can have more info such as DNS servers over DHCPv6, even if they don’t request an IPv6 address via DHCPv6. I know that this part may sound a bit confusing, especially when you are new to IPv6. Please refer to the second episode of my IPv6 from scratch videos and also have a look at the comparison table on my IPv6 cheat sheet from my github repository. The table here helps you decide which mechanism to use. How am I using this at home? You may remember from other videos that I have a dedicated management VLAN here. This is where all my routers, servers, switches – generally speaking the whole infrastructure – provides https and or ssh interfaces. These devices need to be identifiable, therefore I don’t use SLAAC on that interface. On my LAN interface however, where all the laptops are in, I do not need fixed addresses and therefore I only have SLAAC on that interface. Still – even if I do not set the “Managed config flag”, I can still use DHCPv6 even in my LAN by forcing the client to do so. For example these Proxmox containers here. They do get an IPv6 address from the LAN range over DHCPv6, not SLAAC. I can do this because I set the IPv6 address to DHCP in Proxmox and also I told the container to NOT use SLAAC by setting this autoconf value to 0. As you can see, it does have a global IPv6 address, but its a nice clean address coming from DHCPv6. In a nutshell – the fact that we set the DHCPv6 Service to server mode on the first tab means that the router will answer to DHCPv6 requests on UDP port 546 to the multicast address ff02::1:2. The RA-Service dropdown determines whether we answer Router Solicitation requests on ICMPv6 or not. If I set this to disabled, then the second tab disappears. (static leases and DNS) Perfect. Now we have IPv6 configured on the WAN and LAN side. Just – we have a handful of little challenges here. Let’s say we don’t have a fixed IPv6 prefix, we rather get a new one from the ISP every 24 hours or so (like I do with Deutsche Telekom). How would we manage DNS and firewall rules for nodes that have ever changing IPv6 addresses? Let me show you the problem. I go to the firewall Traffic rules and I want to make a rule for this sandbox-adguard server here. If I made a rule now and then later the prefix or the address of this adguard server changes, then my rule would be useless. How can I solve this? First, I would need to make sure that this server gets a constant or static node address. I am not talking about the prefix. Just the lower 64 bits that identify the node itself. Also – I know that the server will always have the value 5 as the last 4 bits of the subnet – you remember? So – let’s start with the node address. Going to the status page of my router, I can see all the clients that have DHCP leases at the moment. For both IPv4 and IPv6. Using this “Set static” button I can make sure that this same device gets the same IP address the next time it requests one. The unique identifier for this would be the MAC address in the IPv4 world. In the IPv6 world, the machine has sent a unique identifier, the so called DUID to the DHCPv6 server. The client is responsible for generating this and needs to make sure that it is always the same value. You can actually see portions of the MAC address in the DUID. Unfortunately, if I now make both the IPv6 and the IPv4 address static, then OpenWrt will create two entries here under Network-DHCP and DNS- Static leases. That would work but I want to make sure that the IPv6 address also resolves correctly with DNS. Therefore, let me delete the IPv6 entry and rather edit the IPv4 entry. Here I have two parameters that I can tweak for IPv6. In the DUID dropdown box I can actually select the adguard server. I can see that’s the same MAC address. Or – if I have many machines or if I can’t find it here, then I could also just copy paste it in here. The next parameter is interesting and actually lets me define the node address portion of that machine. Let me put in 245, because the IPv4 address ends in 245. I know it’s not the same thing. The one is decimal and the other one is hex, but they look the same. Save, then Save and apply. The next time that this machine requests an IPv6 address, that address will end in 245. I can accelerate that a bit if I restart the odhcpd service on the router and down and up the network interface on the client. Takes a while. Here we go. Quick cross check with nslookup. Yep. That comes back with both addresses. IPv4 and IPv6. Beautiful. So – how does that help me with my firewall rule now ? Let’s have a closer look at this server’s address. We have the prefix which is 60 bits long. Then we have the 4 bit subnet which I can manage on my own, then we have the node address which is many zeros and then 245. If I apply a bitmask to this in the sense that I set all bits of the relevant (fixed) part to 1 and all bits of the changing prefix to 0, then I can write this address in subnet mask notation like this. Not beautiful, but it works. So rather than having a firewall rule for the whole IPv6 address, I now have one for any IPv6 address in subnet 5 that ends in 000... 245. I could now even have one single rule for IPv4 and IPv6. Of course I could have used the MAC address as well. (NDP proxy – no prefix delegation) So far so good. This all works if we have prefix delegation by our ISP. Unfortunately, many ISPs do not offer prefix delegation, but they rather just give you a /64 subnet. What can we do here? In this case, you would not see any delegated prefix here on the status page or on the WAN interface. Just a /64 address really. And no IPv6 address on the LAN or guest interface, because there are no more subnets to be delegated really. The whole /64 space is already “eaten up” by the WAN interface. If you still want to use IPv6 in your LAN, then you can configure OpenWrt as an IPv6 NDP proxy between the WAN and LAN zone. NDP stands for the Neighbor discovery protocol. Here is how. First, we need to edit the WAN6 interface and add DHCP settings. Important – we don’t want to run a DHCP Server on the WAN zone here, so make sure that this “Ignore Interface” Checkbox is ticked. On the IPv6 Settings tab, we tick the box “Designated Master” and we set all other drop downs to “relay mode”. On the interfaces in our LAN or guest network we now set all drop downs to relay as well. Once we save and apply, we won’t really notice any difference on this screen. But watch what happens if I turn the network connection on my client off and on again. Tadaaa – I get an IPv6 address. My OpenWrt router now proxies all my requests through to the WAN side. Unfortunately, our possibilities what we can do with IPv6 LAN side are quite limited with this setup. In a nutshell we get a SLAAC or DHCPv6 address for our nodes and that’s pretty much it. (6in4 tunnel) So what can we do if we want to enjoy full IPv6 functionality but our provider doesn’t give it to us? There is a third alternative called 6in4. This basically tunnels IPv6 through IPv4. In order to use this you have to sign up to a tunnel broker on one side and create a 6in4 interface on your side. The tunnel broker will now give you ipv6 connectivity through a tunnel inside ipv4. Pretty similar to a VPN really. There are IPv6 tunnel brokers who give you a whole /48 prefix for free like Hurricane Electric for example. All that you have to do is sign up on their site tunnelbroker.net. From here, you can create a new tunnel to many locations on various continents. Let me add one for New York here. All that you have to give them in order to be able to generate a tunnel is a valid IPv4 address which they can ping in this IPv4 endpoint field here. So I am not sure if this works with double Nat (Carrier grade NAT / CGN). Leave me a comment if you have it up and running. Also you might need to add a firewall rule to your router so that they can actually ping you. Don’t forget to select /48 prefix. Now for the configuration on the OpenWrt side. You go to system-software and install the 6in4 software package. You will need to reboot after this so that LuCI shows the new protocol. Once you’re back in, go to network-interfaces and add a new interface with the IPv6-in-IPv4 protocol. Enter all the information from the tunnelbroker website. Just down here where it says HE.net password, enter the dynamic update key. This way hurricane electric will automatically update the IPv4 endpoint for you. Don’t forget to assign the interface to the WAN firewall zone. And – there we go. Beautiful /48 prefix delegated to us. Full IPv6 functionality. Awesome. You might wonder – why does Marc not talk about IPv6 NAT? Well, there’s two reasons for that. First – I have never used it. I am only using IPv6 for a couple of months now and really want to understand the whole thing fully before I examine things like IPv6 NAT. Second, OpenWrt have just recently moved from iptables to nftables as their firewall and currently it looks like IPv6 NAT relies on Iptables. So I guess we will just have to wait a bit. Even though IPv6 NAT might not sound right to the IPv6 purists among us, I do actually have a use case for it which is reverse proxy between network segments. So – there’s probably more to come. Stay tuned. Until then – many many thanks for watching, liking and commenting. Stay safe, stay healthy, bye for now.