IPv6, Linux and Fiber7

Introduction, landscape.

My summary describes it simply. I had IPv6 on the outside of my router, but didn't do any propagation inside my lan. It was a rainy week-end, so I had no excuse, and fixed my setup.

I'm currently a Fiber7 user, and because I went for the highest speed, there was is not a real available CPE that would match my needs : SFP28 on a silent-ish” router. I've been running ipchains, iptables for +20 years, I'm familiar with the syntax, so that's why I went for Linux, further more that the router is running on Proxmox VM.

Current setup.

I run a Debian Buster, with a simple nat setup, with pihole handling DHCP announcement internally (therfor dnsmasq). Until now, I was only using Debian's network internal config. Here is how the file looks : - /etc/network/inferaces (Anonymized)

allow-hotplug ens18
# Internal interface
iface ens18 inet static
        address 10.10.10.254/24
        dns-nameservers 194.150.168.168 46.182.19.48 80.67.169.40
        dns-search internal.example.org
# External Interface
allow-hotplug ens19
iface ens19 inet dhcp

In order for NAT to work, I need to allow the kernel to forward. I was doing that the old way : In /etc/rc.local I had :

echo 1 > /proc/sys/net/ipv4/ip_forward

The cleaner way to do it is to set the parameter in the /etc/sysctl.conf :

net.ipv4.ip_forward=1

I created the small shell script to create the basic rules before saving them :

#!/usr/bin/env bash

INTERNAL=ens19
EXTERNAL=ens18

sysctl -w net.ipv4.ip_forward=1

iptables -t nat -A POSTROUTING -o $EXTERNAL -j MASQUERADE
iptables -A FORWARD -i $EXTERNAL -o $INTERNAL -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $EXTERNAL -o $INTERNAL -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $INTERNAL -o $EXTERNAL -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Saving the rules to /etc/iptables/rules.v4 looks like that :

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -o ens19 -j MASQUERADE
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A FORWARD -i ens19 -o ens18 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i ens18 -o ens19 -j ACCEPT
-A FORWARD -i ens18 -o ens19 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
COMMIT

Let's do IPv6 then.

Here are some of the requirements needed at this point (or at least let's verify we have them ) :

So we need to set some additional system parameters :

in /etc/sysctl.conf

# This was already configured
net.ipv4.ip_forward=1
# This is needed for IPv6 routing
net.ipv6.conf.all.forwarding=1
# This is needed to accept the advertisment form the ISP
net.ipv6.conf.ens19.accept_ra = 2

DHCPCD will be requesting the /48 fro the ISP, and will tell you where to assign it :

/etc/dhcpcd.conf :

# could be priavte, I used the mac address 
slaac hwaddr
interface ens18
    static ip_address=10.10.10.254/24
    static ip6_address=2001:DB8:1234::254/64
    static domain_name_server=9.9.9.9
interface ens19
    dhcp
    dhcp6
#  enable routing solicitation
    ipv6rs
# used for interface association identifier, it's a need for vlanid, but might be optional in my case
    iaid 1
# request prefix delegation and assign it to the desired interface
    ia_pd 2 ens18/0/64

Note that you cannot assign the /48, only one of the /64s . Also I added some parameters in my /etc/network/interfaces :

iface ens18 inet6 static
        address 2001:db8:1234::254/64

iface ens19 inet6 dhcp
# These 2 might be optional, as dhcpcd does the request, and the ra is set in the sysctl
        accept_ra 2     
        request prefix 1

I configured my pihole using the web interface, but you can also configure some of it via config file :

/etc/pihole/setupVars.conf

PIHOLE_INTERFACE=ens18
DHCP_ACTIVE=true
DHCP_IPv6=true

Also, I remember we need to protect the inside, as it's routed, so reachable from the outside world. Here is my file for that :

/etc/iptables/rules.v6

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -j ACCEPT -p icmpv6
-A FORWARD -p ipv6-icmp -j ACCEPT
-A OUTPUT -p ipv6-icmp -j ACCEPT
-A INPUT -j ACCEPT -m state --state RELATED,ESTABLISHED
-A INPUT -m conntrack --ctstate NEW -m udp -p udp --dport 546 -d fe80::/64 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j ACCEPT -i ens18
COMMIT

Conclusion

With all this, I had my setup working, I now have IPv6 in my lan, seems to be working with all my devices. Here is some of the ressources that were helpful to my setup, some are duplicates, and many informations are also in the man of each daemons. There is even a link for radvd, even if ra is done by pihole.

Links ressources :

This is a first draft, I welcome any corrections and fixes that might be needed. Hope it can be of help to someone.

whoami

I'm Will van Gulik, associate and network architect/engineer at Saitis / Nimag networks Sarl, we are operating AS6893, AS41882 and I'm experimenting on AS2613. I'm also a co-working group Chair of Ripe's Connect Working group.

This page was generated using Markdown and Lowdown by Kristaps Dzonsons