Hosting a website at home behind a Fritzbox with IPv6 enabled

Oli Zimpasser
4 min readMay 11, 2021

My “web-server infrastructure” at home is composed of:

  • a Fritzbox acting as a DSL modem and a network Router
  • a Raspberry Pi as my web-server with Ubuntu 20.04

On this Raspberry Pi I host a few web applications including my homepage. As my home IP changes every night, I use a dynamic DNS service (ydns.eu) as the target for a CNAME on www.oglimmer.de.

As we know hosting a website at home, on a Raspberry Pi for example, is very simple and making it available on the Internet via IPv4 is super straight forward.

Let us recap the situation for IPv4

  • The browser resolves www.oglimmer.de and finds a CNAME for oglimmer.ydns.eu, which returns an A entry pointing on my Fritzbox’s public and dynamic IPv4
  • The Fritzbox forwards a request on port 443 to the Raspberry Pi’s web-server, because a port forwarding for 443 to the private and fixed IPv4 of my Raspberry Pi is configured

Things are more complicated with IPv6

As there is no NAT for IPv6, the Fritzbox does not have a port forwarding, instead it has port permissions on routing configurations. So for my scenario the web-server's IPv6 is given permission to be routed on port 80/443 on incoming requests.

This looks like that:

Here is the problem

My Ubuntu 20.04 assigns two global unicast IPv6 addresses and both of those IPs have randomly generated interface ids.

While this is very good for privacy reasons, this is a problem for my setup, as the Fritzbox needs a static interface id for its routing permission.

The solution

Enable EUI-64 on the standard address to avoid a randomly generated interface id, that means Ubuntu will use "a MAC address derived" interface id instead.

Where this configuration needs to be applied depends on which component is responsible for SLAAC.

If SLAAC done by the Kernel you need to use sysctl to enable EUI-64 via:

net.ipv6.conf.default.addr_gen_mode = 0
net.ipv6.conf.eth0.addr_gen_mode = 0

On the other hand if SLAAC is done by dhcpcd you need to change dhcpcd.conf like this:

slaac hwaddr

Finally if SLAAC is done by NetworkManager, you need to change the configuration via:

nmcli con modify “Connection name” ipv6.addr-gen-mode eui64

This is my IP setup after applying EUI64. As you can see the MAC address is reflected in the interface id of the second global unicast IPv6 address:

A shout-out needs to go to the user Grawity on qastack.co who pointed us to the right solution. See this post.

Configuration on the Fritzbox

The Fritzbox as under “Internet” -> “Permitt access” -> “Port sharing” the following dialog:

Sharing options

Most notably is the setting for “IPv6 Interface ID” which must reflect the MAC address.

Updating ydns.eu

To complete the process we need a script on the web-server to update the dynamic DNS service with both IPs when my ISP updates my public IP.

A simple cgi-bin is called from the Fritzbox (as a custom dyamic DNS provider):

#!/bin/bash

set -f

echo “Content-type: text/plain; charset=iso-8859–1”
echo

IPV4=$(curl -s ifconfig.me)
curl -u ‘user:password’ “https://ydns.io/api/v1/update/?host=oglimmer.ydns.eu&record_id=164921&ip=$IPV4"

IPV6=$(ip -6 address show dev enp2s0f0 | grep -v “ 0sec” | grep “sec” -B 1 | grep inet | grep -v ‘temporary’ | grep -v ‘inet6 fd’ |cut -d ‘ ‘ -f6|cut -d ‘/’ -f1)
curl -u ‘user:password’ “https://ydns.io/api/v1/update/?host=oglimmer.ydns.eu&record_id=173613&ip=$IPV6"

Conclusion

Running an IPv6 enabled web-server at home is a bit more complicated than thought, but still pretty doable.

The main problem comes from the fact that enabling EUI-64 on Ubuntu depends on your configuration, but once you understood how it works it’s quite straight forward again.

--

--