Bernhard's Homepage

IPv6 configuration in Alpine Linux, Debian and GNS3 Docker

IPv6 configuration in Alpine Linux, Debian and GNS3 Docker

The IPv4/IPv6 configuration is documented in

GNS3 docker images use the same base component (busybox) as Alpine to configure the interfaces, so use the instructions for Alpine.

The most interesting part of IPv6 is the auto-configuration, it's completely different from IPv4. I'm going to show its configuration for Debian Linux, it's also valid for Ubuntu and all its derivatives. Furthermore the configuration for Alpine Linux is shown. I will cover some specifics of GNS3 Docker at the end.

IPv6 Auto-configuration Basics

IPv6 can configure its IPv6 address/netmask and its default gateway by stateless address auto-configuration (SLAAC). The router in an IPv6 network sends periodical router advertisements (RA), which contains the necessary information. A host can use a router solicitation message to request an immediate RA. SLAAC can't configure further parameters, especially DNS servers and domain name are not configured by SLAAC.

Additionally the DHCPv6 protocol can be used. It exists in two variants, stateless and stateful DHCPv6. The stateless version is meant to complement SLAAC, it mainly supports options for defining DNS parameters. The stateful variant supports all the stateless options, additionally it manages an IPv6 address pool and gives host addresses (with /128 netmask) to the clients. Neither variant is able to give netmasks, default gateway or other routing information to the clients. That has to be done via SLAAC or by static configuration.

Linux handles SLAAC completely in the kernel, no user mode process is involved.

The kernel parameter net.ipv6.conf.<interface>.accept_ra controls it:
0 - Do not accept Router Advertisements.
1 - Accept Router Advertisements unless forwarding is enabled.
2 - Always accept Router Advertisements, even if forwarding is enabled.

Additional kernel parameters can fine-tune this, for example the parameter net.ipv6.conf.<interface>.accept_ra_defrtr defines if a default route is added (1, the default) or not (0).

DHCPv6 is not handled by the kernel, it needs a user mode process, for example the isc-dhcp-client (dhclient).

IPv6 test setup

I'm using a simple GNS3 project to test IPv6 configuration in a controlled environment.

IPv6 test

The cisco router configuration supports IPv6, SLAAC (enabled by default) and stateful DHCPv6. Stateless DHCPv6 requests are also answered by the stateful DHCPv6 server. Additionally a very basic DNS server allows the test of IPv6 DNS requests.

ipv6 unicast-routing
ipv6 dhcp pool test
 address prefix 1:2:3:4:4711::/80
 dns-server 1:1:1:1::1
 domain-name test
interface Loopback1
 ipv6 address 1:1:1:1::1/128
interface GigabitEthernet0/0
 ipv6 address 1:2:3:4::1/64
 ipv6 dhcp server test
 no shutdown
ip dns server
ip dns primary test soa ns.test admin@test
ip domain name test
ip host r1.test 1:1:1:1::1

The "ipterm-1" device is a docker container running Debian. It has the additional package "ifupdown" installed, that allows the network configuration within that container. "alpine-1" runs Alpine Linux within Docker, ifup/ifdown are installed by default.

Static confguration

That's easy, here an example:

iface eth0 inet6 static
	address 1:2:3:4::100
	netmask 64
	gateway 1:2:3:4::1
	up echo nameserver 1:1:1:1::1 > /etc/resolv.conf
	pre-up echo 0 > /proc/sys/net/ipv6/conf/eth0/accept_ra

This will work both for Alpine and Debian.

The 'pre-up' command is not necessary for Debian, it will set the accept_ra kernel variable to 0 by default. Alpine doesn't touch the kernel variables during the interface configuration, so the 'pre-up' command is mandatory in Alpine.

The 'up' command sets the nameserver by overwriting /etc/resolv.conf. Alternatively you can remove the 'up' command and manually edit /etc/resolv.conf.

Auto-configuration (SLAAC)

For Debian, that's simple, use iface eth0 inet6 auto. That sets the accept_ra kernel variable to 2 and activates the interface. The kernel does the rest.

But SLAAC doesn't configure DNS, so either configure that manually as shown in the static configuration section, or enable stateless DHCPv6 by using the dhcp option.

iface eth0 inet6 auto
	dhcp 1

Alpine has no 'auto' method, it uses 'manual', which only activates the interface. As accept_ra is active by default, you don't have to touch this. The Alpine documentation sets accept_ra anyway to be on the safe side.

iface eth0 inet6 manual
	pre-up echo 1 > /proc/sys/net/ipv6/conf/eth0/accept_ra

The DHCPv6 client udhcpc6 in Alpine is very weak. Alpine 3.7 (with busybox 1.27) is the first version with a DHCP6 client that might actually work. But I haven't tested that, as it is not yet released at the time of writing. Even that DHCPv6 version is not integrated in ifup/ifdown. So DHCPv6 can't be used in Alpine.

Alpine also contains a package with the debian version of ifup/ifdown. But at least in Alpine v3.6 this package doesn't help either.

Privacy Extensions

IPv6 initially uses a static interface address during auto-configuration, based on the MAC address. But this static address makes it easy to track a user. Therefore RFC 3041 (obsoleted by RFC 4941) defines a method to use a pseudo-random IPv6 address. This feature is realized by the Linux kernel and is controlled by the kernel variable 'use_tempaddr'.

This can be enabled permanently by adding this to /etc/sysctl.conf:


It can also enabled in /etc/network/interfaces by adding pre-up echo 2 > /proc/sys/net/ipv6/conf/<interface>/use_tempaddr to the interface configuration. Alternatively, Debian/Ubuntu users can use privext 2 in the iface section.


No problem for Debian, use iface eth0 inet6 dhcp. As the accept_ra kernel variable is also set, the computer gets two addresses, one from stateful DHCPv6 and one from SLAAC. It's not reasonable to turn off SLAAC, as DHCPv6 alone doesn't send enough information to get a working IPv6 interface configuration.

As written in the previous section, Alpine doesn't support DHCPv6 by default.

GNS3 Docker

Normally the Docker software does the IPv4/IPv6 interface configuration. But as GNS3 wants the Docker container to use the virtual links of GNS3, it has to use it's own setup for the network interfaces. For the interface configuration it injects a busybox binary into the container, which configures them the same way, an Alpine system will do. But that means, it has the same limitations with DHCPv6.

If the Docker container uses Debian or Ubuntu, a workaround could be to configure the interfaces not in the injected busybox, but in the OS of the Docker container.

The idea is to use /etc/network/interfaces in Debian style. At startup of the container the ifup of busybox will complain about unknown methods "auto" or "dhcp". Simply ignore that and redo the interface configuration in Debian/Ubuntu with ifup -a. But that will work only if the "ifupdown" package is installed in the Docker image. By default that's not the case, so this will normally not work. That's the reason, why I have included the "ifupdown" package in my own GNS3 Docker images (