DISCLAIMER: I’m still working on the current setup for this router. I might update and clean up this blog at a later date when I’m fully happy with the state of my firewall and router settings. For now, this seems like a good starting point.
I’ve written before on how to use a NixOS router for my home network. Since that has been successful so far, I wanted to look into enabling IPv6 on my home network and since my ISP offers it, I might as well use it.
First off all, I needed to click on a checkbox on my ISPs admin page to enable IPv6 on my connection. After a few seconds my internet rebooted and it showed in the admin page that IPv6 was now enabled on my connection.
Great, the ISP claims that I have IPv6, now to change some settings on the NixOS router and see if I can actually connect to the IPv6 internet.
As shown in the previous blog, my ISP uses PPPoE for my internet connection. So
lets first tell pppd
to support IPv6.
services.pppd = {
enable = true;
peers = {
isp1-pppoe = {
autostart = true;
enable = true;
config = ''
plugin rp-pppoe.so wan0
name "<username>"
password "<password>"
+ipv6 ipv6cp-use-ipaddr
persist
maxfail 0
holdoff 5
noipdefault
defaultroute
'';
};
};
};
Well, that seems simple. The +ipv6
should be pretty self explanatory. The
ipv6cp-use-paddr
1 makes it so the local
identifier for IPv6 is the local IPv4 address. When we now restart the PPPoE
connection and run ip -6 a
, we see some IPv6 addresses appearing on the ppp0
interface. A quick check proves that we can connect to the IPv6 internet:
$ ping6 google.com
PING google.com (2a00:1450:4001:808::200e): 56 data bytes
64 bytes from fra02s19-in-x0e.1e100.net: icmp_seq=0 ttl=115 time=51.320 ms
64 bytes from fra02s19-in-x0e.1e100.net: icmp_seq=1 ttl=115 time=43.248 ms
64 bytes from fra02s19-in-x0e.1e100.net: icmp_seq=2 ttl=115 time=33.240 ms
64 bytes from fra02s19-in-x0e.1e100.net: icmp_seq=3 ttl=115 time=43.208 ms
^C--- google.com ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 33.240/42.754/51.320/6.410 ms
Nice, our router is connected to the IPv6 internet now. But it gets this IP
assigned through the pppd
daemon. Since I want some more control over this,
lets assign one through dhcpcd
. This requires some tweaking to our networking
settings of the NixOS router.
networking = {
...
interfaces = {
...
ppp0 = {useDHCP = true; } # enable dhcpcd on this interface
};
dhcpcd = {
enable = true;
# Do not remove interface configuration on shutdown.
persistent = true;
allowInterfaces = [ "ppp0" ];
extraConfig = ''
# don't touch our DNS settings
nohook resolv.conf
# generate a RFC 4361 complient DHCP ID
duid
# We don't want to expose our hw addr from the router to the internet,
# so we generate a RFC7217 address.
slaac private
# we only want to handle IPv6 with dhcpcd, the IPv4 is still done
# through pppd daemon
noipv6rs
ipv6only
# settings for the interface
interface ppp0
ipv6rs # router advertisement solicitaion
iaid 1 # interface association ID
ia_pd 1 lan0 # request a PD and assign to interface
'';
};
};
After applying these settings we should end up in the same state as before. Except I didn’t, I lost the IPv6 settings and connectivity. After banging against several walls for way too much time, I realized my firewall settings. I block access to the router by default, but since I’m now requesting things from my ISP, I need to allow certain services to my router.
I made the following modifications to the input
chain of the router:
networking.nftables.ruleset = ''
table inet filter {
...
chain input {
type filter hook input priority filter; policy drop;
# Allow trusted networks to access the router
iifname {
"lan",
} counter accept
# Allow returning traffic from ppp0 and drop everthing else
iifname "ppp0" ct state { established, related } counter accept
iifname "ppp0" drop
# Always allow router solicitation from any LAN.
ip6 nexthdr icmpv6 icmpv6 type nd-router-solicit counter accept
# Default route via NDP.
ip6 nexthdr icmpv6 icmpv6 type nd-router-advert counter accept
# DHCPv6
udp dport dhcpv6-client udp sport dhcpv6-server counter accept comment "IPv6 DHCP"
}
...
}
'';
After applying these settings, I did end up in the same state as before: the router had IPv6 connectivity.
ping6 google.com
PING google.com (2a00:1450:4001:808::200e): 56 data bytes
64 bytes from fra02s19-in-x0e.1e100.net: icmp_seq=0 ttl=115 time=32.619 ms
64 bytes from fra02s19-in-x0e.1e100.net: icmp_seq=1 ttl=115 time=33.596 ms
64 bytes from fra02s19-in-x0e.1e100.net: icmp_seq=2 ttl=115 time=43.601 ms
64 bytes from fra02s19-in-x0e.1e100.net: icmp_seq=3 ttl=115 time=33.402 ms
^C--- google.com ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 32.619/35.805/43.601/4.516 ms
Even more, where before I only had IPv6 on the ppp0
interface, I know also had
it on the internal interface lan0
! So all that is left now is to start up a
router advertisement daemon and all my devices should immediately have IPv6
connectivity. I picked corerad for this
purpose, it has some nice Prometheus metrics built in and a simple config
file.
services.corerad = {
enable = true;
package = unstable.corerad; # unstable refers to the unstable branch of nixpkgs
settings = {
debug = {
address = "localhost:9430";
prometheus = true; # enable prometheus metrics
};
interfaces = [
{
name = "ppp0";
monitor = false; # see the remark below
}
{
name = "lan0";
advertise = true;
prefix = [
{ prefix = "::/64"; }
];
}
];
};
};
These settings is all that stand between my devices and IPv6 connectivity. So after applying these I tested out the IPv6 connectivity on my laptop and it was successful!
In a good evenings work I set up IPv6 for my home network.
This article was posted on 2022 M2 25. Some things may have changed since then, please mail me at francis @ begyn .be if you have a correction or question.
Tags: #linux #networking #nixos #router #ipv6