IPv6, Linux Firewall and Comcast
Here's a general overview of my setup, Comcast Business for my internet, a Raspberry PI running Debian 10 (Buster) as my firewall/router.
I want IPv6 to actually work on my network, here's how.
Here's a general overview of my setup, Comcast Business for my internet, a Raspberry PI running Debian 10 (Buster) as my firewall/router, a whole slew of systems behind it with a smattering of types of devices and OS's. I use nftables
and not iptables
. On my firewall, my internal interface is eth0
and my external is enxd037450b2409
.
This guide does not contain anything about advertising routes and autoconfiguring IPv6, take a look here https://www.frakkingsweet.com/radvd-on-debian-10/ for that. For this guide, you will need to assign static addresses to your systems for it to work. Implementing radvd
on the linked post will autoconfigure all of your devices on your network and is a sequel to this post.
First thing, this probably only applies to Raspberry PI's, make sure IPv6 is not disabled. sudo vi /boot/cmdline.txt
. If you have disable.ipv6=1
there, remove it. Save and reboot. I honestly don't remember if I added it or not, but it was there on mine and I had to remove it. With it there I was getting an error in my logs from dhcpcd. The error was Address family not supported by protocol
. If you get that error throughout this guide you will need to make sure that IPv6 is enabled.
Second, check to see if you have an IPv6 address already, ip -6 a
. Should output a few addresses. Yours won't match but here is an example:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 2603:3026:41d:7df3::1/64 scope global dynamic noprefixroute
valid_lft 203938sec preferred_lft 99906sec
inet6 fe80::8b5c:a54f:f2ac:303b/64 scope link
valid_lft forever preferred_lft forever
3: enxd037450b2409: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 2603:3026:41d:7d00::1/128 scope global dynamic noprefixroute
valid_lft 203938sec preferred_lft 99906sec
inet6 2603:3026:41d:7d00:b196:9cb1:cf62:25d/64 scope global dynamic mngtmpaddr noprefixroute
valid_lft 253173sec preferred_lft 253173sec
inet6 fe80::bb7f:780b:84c5:dc56/64 scope link
valid_lft forever preferred_lft forever
Next, set up your Comcast gateway to give out chunks of addresses. Open your admin page to your cable modem, the default username/password combination is cusadmin
and highspeed
. After you update the values be sure to pull the plug on the power, wait a minute then plug it back in. Took me a while to figure out that it is required for it to truly work.
- I don't entirely know if you need to fill out the assigned
User defined prefix
, but I did. TheSystem Delegated Prefix
is set it to the same value asIPv6 Prefix
,Number of addresses
is255
andValid Lifetime
is208064
. Enable Rapid Commit
is checkedEnable Unicast
is not checkedEnable EUI-64 Addressing
is not checkedEnable DHCPv6
is checkedAssign DNS Manually
is not checked
Now that your modem is setup we need to configure the kernel. Without this part traffic won't flow and it won't get the prefix delegation that you need. Replace enxd037450b2409
with your internet facing interface.
sudo sysctl net.ipv6.conf.all.forwarding=1
sudo sysctl net.ipv6.conf.enxd037450b2409.accept_ra=3
To make this persist through reboots, sudo vi /etc/sysctl.d/11-ipv6forward.conf
. The contents are:
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.enxd037450b2409.accept_ra=3
The forwarding=1
tells the kernel to allow forwarding traffic through the interfaces and the accept_ra
tells the kernel to respond to ICMPv6 packets as though it is a router and a client device. In the normal world, a system is either one but not both. In the Comcast world, we need to be both.
Now that the kernel is set up, lets configure the dhcpcd daemon on the firewall. Remember, eth0
is my internal interface and
is my external.enxd037450b2409
sudo vi /etc/dhcpcd.conf
# comment out clientid
# uncomment duid
interface eth0
static ip_address=x.x.x.x/24 # internal IPv4 address
noipv6rs
interface enxd037450b2409
static ip_address=x.x.x.x/28 # public IPv4 address
static routers=x.x.x.x # public IPv4 router
static domain_name_servers=8.8.8.8 # dns server
ipv6rs
ia_na 0
ia_pd 0/::/60 eth0/3/64
The clientid
, duid
, noipv6rs
, ipv6rs
, ia_na 0
and ia_pd blah
are the important parts. To see what they mean you can check out the man page at http://manpages.ubuntu.com/manpages/trusty/man5/dhcpcd.conf.5.html
Now that dhcpcd is configured, in one terminal, watch the logs. On Debian, sudo tail -f /var/log/syslog
. In another terminal restart dhcpcd. On Debian, sudo systemctl restart dhcpcd
.
You should see some messages in the logs about your prefix delegation, look for the entry that says its adding a route to your internal interface. Here's an example of what you are looking for:
Jul 24 18:08:54 firewall dhcpcd[6372]: eth0: adding address 2603:3026:41d:7df3::1/64
Jul 24 18:08:54 firewall dhcpcd[6372]: eth0: adding route to 2603:3026:41d:7df3::/64
The first line is the gateway address for your clients and the second is the subnet that you use on your internal network. In this case, the gateway is 2603:3026:41d:7df3::1
and the subnet is 2603:3026:41d:7df3::/64
.
If you run into firewall issues, make sure you open up traffic sourced from UDP port 547 (dhcpv6-server) and destined to 546 (dhcpv6-client) and ICMPv6. The necessary accept rules for nftables.conf
are this:
ip6 saddr fe80::/10 ip6 daddr fe80::/10 udp dport dhcpv6-client accept
ip6 saddr fe80::/10 ip6 daddr fe80::/10 udp dport dhcpv6-server accept
ip6 nexthdr ipv6-icmp accept
icmpv6 type { destination-unreachable, packet-too-big, time-exceeded } accept
icmpv6 type { nd-router-advert, nd-neighbor-advert, nd-neighbor-solicit } ip6 saddr fe80::/64 ip6 daddr fe80::/64 accept
In theory, if the logs are clear you should be good to go. Set an IPv6 address on your client in the subnet you were given with the appropriate gateway and some DNS servers and you should be set. For reference, the Comcast DNS servers I received are: 2001:558:feed::1
and 2001:558:feed::2
. Try and ping something over IPv6 ping -6 www.google.com
If you run into issues let me know, I'll try and help and update this post if necessary.