Let's give some context here. My internet service provider allows IPv6, but I don't get any v6 from them, only v4. Why? 3 years ago, when I was learning how to set up a home server, every time I opened a new port, it'd be completely randomized, and the port number would change too, so it was a hassle, and during a conversation with a support person, they told me that this issue was because of the CGNAT. I then asked to get removed from it, and during that process I lost IPv6. Fast forward to the present, I have a friend who cannot open ports over IPv4 and I cannot play games such as Minecraft from his server. Another thing that happened is that I purchased my first VPS, which would be great, if it were not to be because its v4 address is behind NAT... So, what options do I have? I tried asking the support team again for help, they tried reenabling my IPv6 ability back for me to test if it would be worth for me to use v6 instead of just v4... Bad news, the router won't accept any IPv6 stuff, change the router time!

A few days before, another friend suggested me to use an IPv6 broker, which in term sounds like a good idea, and it was not a bad one, as you will see as you read this post. I decided I'd give it a go after my final exams, and here we are!

So, what is an IPv6 broker? It's a company that sells you a v6 prefix, that simple. Well then, how do you use it if you don't have IPv6 at home? Well, using 6to4 of course. 6to4 allows you to send IPv6 packets over IPv4 using encapsulation. Great! So we are set... Not so quick, we still have the issue of the router not being configurable... Well then, what is this saga about then?

So I created an account in TunnelBroker, from Hurricane Electric, and created my tunnel to Lisbon, as it is the nearest location with the least ping. When you have your tunnel set up, you will see different parameters, client IPv6 and v4, server v6 and v4. This is all necessary as you will see during the configuration of the 6to4 tunnel. Once that is set up, I changed the configuration for the bridge we created the other day, instead of it having two network interfaces, now it has only one. This is because I'm going to be setting up a NAT on this machine, so the bridge would be the inside of the network and then enp2s0, the second ethernet card will be the one facing the outside.

Before we begin setting up the tunnel, I had to set up the NAT with nftables to masquerade. That was easy, next I started filtering ports, and important, allowing the ICMP requests. After that, I set up the ports I want to have public and then I set the machine as the DMZ in my ISP router. Why am I not replacing my main router with my Linux box? As beautiful as a Linux box sounds to have as a router, I don't want to screw the other people living inside my home with my excentricities, so I just have my separate nat for my tidbits.

Alright, we have the machine exposed to the interwebs, time to set up the router. For this, HE will give you configuration examples, just choose your OS and copy/paste, easy enough... Right? Wrong! It should be easy, but for some reason I spent like the entire day getting the tunnel to work. In the end it was an issue on my end, turns out I did not set the client IPv4 correctly. If you want to do this at home, keep in mind that if your server is behind NAT, you have to set the client IP to your internal address. Another tip is to set up Dynamic DNS with HE, so that if your public v4 changes, then the change keeps being refreshed in your configuration, so that you are not left out of IPv6 at random.

Right, tunnel is up, I can ping the interwebs, great! The easy part is now done, now comes the fun part of setting up the DHCPv6. From what I have been reading, you ought to have an stateless v6 server due to how Android does IPv6, in this case, set up dnsmasq and done, then we add the configuration so that it behaves like a stateless v6 server. I'll share the configuration I have at the end of the file.

It is important you keep in mind that for the DHCPv6 server, we are going to be using the routed v6 prefixes, all your devices will get a v6 address from this prefix, the prefix that is allocated to the client and the server should not be used for anything else than that. If you are going to use more than one DHCPv6 server, you should ask for the /48 range. Iirc, they both should be free. We might make use of the /48 in the future for wireguard...

Once you have the DHCPv6 stuff, don't forget to enable IPv6 routing, and while you are at it, if you haven't enabled v4 routing, do so, as you want to have a working IPv4, right? Anyway, once you have set up the DHCP and the routing, you should assign your bridge an static IPv6 address. This is easy to do by hand, I wasn't able to get the server to allocate an static IPv6 to the bridge during boot time for some reason, if I find out why, I'll share the solution over here. I'll not go into detail but all of these addresses that you are assigning, as we are working with a /64 prefix, we have to keep in mind that this is the bare minimum to get stateless DHCPv6 and SLAAC from what I understood. Restart your DHCPv6 server and off we go.

Let's keep going, we have stateless IPv6 + SLAAC and the router should be doing router announcements, so the network is complete! We can check the router announcements, but most importantly, if you flush and then reconnect a device to the network, it will be assigned two IPv6 addresses. Then if we go into a web browser and run an IPv6 test, we will see that we have IPv6 working, which is great!

Aight, onto the configuration:

table inet filter {
    chain input {
        type filter hook input priority filter; policy accept;
    }

    chain forward {
        type filter hook forward priority filter; policy accept;
    }

    chain output {
        type filter hook output priority filter; policy accept;
    }
}

table ip nat {
    chain prerouting {
        type nat hook prerouting priority dstnat; policy accept;
        iifname "enp2s0" tcp dport --ssh-port-num-- dnat to 172.16.12.1:22
        iifname "enp2s0" tcp dport --gitlab-ssh-- dnat to 172.16.12.1:2222
        iifname "enp2s0" tcp dport 80 accept
        iifname "enp2s0" tcp dport 443 accept
        iifname "enp2s0" udp dport --wireguard-port-- accept
        iifname "enp2s0" tcp dport 25565 accept
        iifname "enp2s0" udp dport 25565 accept
        iifname "enp2s0" ip protocol icmp accept 
        iifname "enp2s0" drop
    }

    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        oifname "enp2s0" masquerade
        ip daddr 172.16.12.1 masquerade
    }
}            
                

This is my configuration for nftables, here in the NAT table we have everything more or less covered, at least in my case. Most importantly, we want to keep in mind the oifname "enp2s0" masquerade. This tells the server that your network adapter that goes outside the NAT is enp2s0, and that all the traffic going through it has to be rewritten in order to be passed along in this hot potato game called network.

Other important directives are the ones to allow/deny ports. We don't want a public MySQL port, do we? Also it is important to masquerade the address in the case of changing ports around. Finally and most important of all, it's the drop all traffic. It is also important to remember that we have to accept all the ICMP traffic, as this is what HE uses to know if our host is up.

enable-ra
dhcp-range = --ipv6-prefix-without-netmask--, ra-stateless
dhcp-option = option6:dns-server, [2001:470:20::2], [2001:4860:4860::8888]
                

Not much here, just specifying the IPv6 range and then specifying that it is stateless, also the DNS servers. Most important is the enable-ra, as this allows the router announcements. Important that you don't specify it's /64 because we are assuming the minimum unit.

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
                

Don't forge the forwarding, this is now a router, not a switch.

ip -6 addr add --ipv6-prefix-without-netmask--::1/64 dev br0
                

Don't forget to assign an address to the bridge.

After all of this, you should have a working IPv6 in your devices.

Now, about the quality of the service, if you have a server near you, the ping is not that bad. In my case I only get 10ms more than if I were on v4, which is perfectly fine for normal usage.

Anyway, this is all I have to show for setting up IPv6, this is my first contact with it and I mostly did it because I want to learn how to use it, seeing this will most likely be the future as there are no more available IPv4 addresses. I hope this served you for something aside of all the ranting about how IPv4 works.