18

The router on my network hands out an IPv6 prefix assigned by my ISP. This prefix is dynamic but "fairly sticky".

I would like my machines to automatically pick up the prefix advertised in the RAs, but combine it with a user-specified local part rather than generating one randomly or based on the MAC address. Is there any easy way to do that?

plugwash
  • 4,352

4 Answers4

16

There are two ways to do this. One is the easy way and one is the hard way.

The easy way is to run a DHCPv6 server on your network and assign host addresses to each device yourself. Or let the server pick the host part; the DHCPv6 servers I have seen will keep the same host part even if the prefix changes.

The hard way is to use ip token to set tokenized interface identifiers. This is described as:

IPv6 tokenized interface identifier support is used for assigning well-known host-part addresses to nodes whilst still obtaining a global network prefix from Router advertisements. The primary target for tokenized identifiers are server platforms where addresses are usually manually configured, rather than using DHCPv6 or SLAAC. By using tokenized identifiers, hosts can still determine their network prefix by use of SLAAC, but more readily be automatically renumbered should their network prefix change. Tokenized IPv6 Identifiers are described in the draft: <draft-chown-6man-tokenised-ipv6-identifiers-02>.

The reason this is the hard way is that while Linux includes this functionality, no Linux distribution I'm aware of includes support for making such a configuration persistent and applying it at boot time, as they do for manual or DHCP configured addresses. So it is probably not going to work very well for you, until some distribution does so. Note that it is now possible to configure IPv6 tokens in NetworkManager and systemd-networkd; more recent answers have specific configuration instructions.


Finally, if your ISP is occasionally changing your prefix, consider using Unique Local Addresses within your network. This way, all of your devices will always have an address that will never change, with which they can talk to each other. Some IPv6-supporting home/SOHO routers (such as OpenWrt) have an option to enable ULA across the entire home network; if there are multiple routers in the home, this should be enabled on the router which connects to the ISP.

  • The issue that actually prompted the question was my ISPs router sends out RAs with a short lifetime. This causes big problems with privacy addresses. OTOH I don't much like the idea of revealing my MAC address to the world. – plugwash Jan 09 '17 at 13:49
  • A static local part avoids the issues with privacy addresses without revealing my MAC address, thanks. – plugwash Jan 09 '17 at 13:50
  • Do you know a way to add multiple tokens to a single interface to set multiple "dynamic static' IPv6 address? – wedi Aug 15 '18 at 06:24
  • @wedi Linux supports only one token per interface. IPv6 tokens are probably not the solution to your problem, whatever it is. – Michael Hampton Aug 15 '18 at 12:48
8

Michael did a very good summary and plugwash's recent tip was the best I could find after hunting for several hours for a CentOS 7/RHEL (also systemd and network manager) solution. After getting used to nmcli (I was mainly still using ifcfg and ip) - I could successfully apply it.

But digging deeper according to https://developer.gnome.org/NetworkManager/stable/settings-ipv6.html NetworkManager directly supports IPv6 tokenized interface identifiers as a property (from release 1.4 August 2016 http://news.softpedia.com/news/networkmanager-1-4-adds-support-for-setting-ipv6-tokenized-interface-identifiers-507601.shtml).

So you don't need to set network manager IPv6 settings to ignore but you should set the settings to

nmcli connection modify eth0 ipv6.method "auto" # if not already
nmcli connection modify eth0 ipv6.addr-gen-mode "eui64" # use interface token
nmcli connection modify eth0 ipv6.token "::2"

which will write IPV6_TOKEN=::2 to /etc/sysconfig/network-scripts/ifcfg-eth0 to survive a reboot. To immediate apply this restart the interface by

nmcli connection up id eth0  # restart
Jürgen
  • 81
6

Thanks to Michael for confirming that Linux supported the feature and pointing at the the low-level command. This answer covers how to make it work in practice on a Debian stretch desktop (with systemd and network-manager).

First edit the connection in network manager and set the IPv6 settings to ignore.

Now create a file /etc/NetworkManager/dispatcher.d/pre-up.d/iptoken . The file should be owned by root, permissions 755 and with the following contents.

#!/bin/sh
ip token set ::2 dev eth0

Replace eth0 with the device you want and ::2 with the suffix you want.

plugwash
  • 4,352
6

Under Linux you can use systemd-network.

Just create a .network file under /etc/systemd/network/somename.network:

[Match]
Name=e*

[Network]
DHCP=yes
IPv6Token=::1

instead of e* to match all interfaces starting with e, you can enter the full interface name.  This enables DHCP{v4,v6} and uses ::1 as suffix.  You can choose any IPv6 address, but the first 64 bits must be set to zero.

After this enable and start the systemd-networkd.service.

Inrin
  • 161
  • Thanks! This actually works on recent systemd distributions. The other solutions have issues, i.e. the Token is set but not applied when IPv6 is attached to a device. – mschmoock May 17 '21 at 09:07