Feuerfest

Just the private blog of a Linux sysadmin

Configuring an mixed IPv6 setup - static ULA, dynamic GLA

In Fix keepalived error: bind unicast_src - 99 cannot assign requested address I mentioned that I fixed my problem with a mixed static & dynamic IPv6 setup. Here is how I did it.

Status quo

For a few years I followed the Raspbian recommendation to use DHCP to assign the static IP. And it worked - until it didn't. This was my config. Note that I didn't use a fallback profile. I like to notice when DHCP doesn't work.

root@raspi:~# cat /etc/dhcpcd.conf
[...]
interface eth0
        static ip_address=192.168.1.10/24
        static ip6_address=fd87:f53:25b4:0:231d:4cbb:bca7:10/64
        static routers=192.168.1.1
        static domain_name_servers=127.0.0.1 ::1

# It is possible to fall back to a static IP if DHCP fails:
# define static profile
#profile static_eth0
#static ip_address=192.168.1.23/24
#static routers=192.168.1.1
#static domain_name_servers=192.168.1.1

# fallback to static profile on eth0
#interface eth0
#fallback static_eth0

Due to an accidental power loss my RaspberryPi rebooted and got a new IPv4 and IPv6, totally different from the configured ones.

The changed IPv4 was easily identified. I forgot to set a DHCP reservation for the MAC address in my DSL router. I suspected then that I also forgot this for the IPv6. Only to notice: My FritzBox 7530 doesn't allow to add IP/MAC reservations for IPv6. Only IPv4 addresses are supported.

And that was the moment where I had enough and decided to ditch DHCP all together.

For IPv4 this was easy enough.

root@raspi:~# cat /etc/network/interfaces.d/ipv4
auto eth0
iface eth0 inet static
        address 192.168.1.10
        netmask 255.255.255.0
        gateway 192.168.1.1

However for IPv6 it took me a few minutes. Specify address and netmask, done. Right?

Well, no. Internet access wasn't working. A quick check revealed that the GLA address was missing.

root@raspi:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether aa:aa:aa:aa:aa:aa brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.10/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fd87:f53:25b4:0:231d:4cbb:bca7:10/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::aaaa:bbbb:cccc:dddd/64 scope link
       valid_lft forever preferred_lft forever

Hosts in my LAN were perfectly reachable. A ping to an public IPv6 didn't succeed.

root@raspi:~# ping6 google.de
PING google.de(lcmuca-ah-in-x03.1e100.net (2a00:1450:4016:803::2003)) 56 data bytes
^C
--- 2a00:1450:4016:803::2003 ping statistics ---
13 packets transmitted, 0 received, 100% packet loss, time 12441ms

Turns out, when you configure a static Unique Local Address (ULA), which is the IPv6 equivalent to our beloved RFC1918 IPv4 (192.168.0.0/16, etc.), Linux doesn't listen to Router Advertisements (RAs) anymore. Hence no Global Link Address (GLA).

The small details is to set autoconf 1 and accept_ra 2 for the interface. This is also documented in the Debian Wiki. This is my working config. My internal network config is now static which is a must as I run some services on keepalived VIPs.

root@raspi:~# cat /etc/network/interfaces.d/ipv6
# IPv6
auto eth0
iface eth0 inet6 static
        address fd87:f53:25b4:0:231d:4cbb:bca7:10
        netmask 64
        # Mixing static and dynamic IPv6
        # from: https://wiki.debian.org/NetworkConfiguration
        # use SLAAC to get global IPv6 address from the router
        # we may not enable ipv6 forwarding, otherwise SLAAC gets disabled
        #
        # Automatically create IPv6 addresses based on Router Advertisements (RA)
        autoconf 1
        # Always accept RAs, even if a static IPv6 address is configured
        # as normally Linux doesn't listen to RAs anymore when a static IPv6 is assigned
        accept_ra 2

Disable DHCP

And don't forget to disable the DHCP service.

root@raspi:~# systemctl stop dhcpcd.service
root@raspi:~# systemctl disable dhcpcd.service
Synchronizing state of dhcpcd.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable dhcpcd
Removed "/etc/systemd/system/dhcpcd5.service".
Removed "/etc/systemd/system/multi-user.target.wants/dhcpcd.service".

After all these years?

Once again I am left wondering why I had this problem for the first time in 2026. After all IPv6 is 25 years old..