How do I get a stable IPv6 address in 16.04?

Solution 1:

I just figured this out. For each connection in /etc/NetworkManager/system-connections/, you need to set the following property:

[ipv6]
addr-gen-mode=eui64

NetworkManager in 16.04 appears to set a default of stable-privacy for the addr-gen-mode setting.

Solution 2:

The other answers here are a bit incomplete: changing NetworkManager configs doesn't help if you don't have one (which is actually the problem, see below), and disabling IPv6 privacy extensions is actually somewhat unrelated (again if your supposedly-stable IPv6 address changes on each boot, removing the extra privacy addresses doesn't help).

As detailed in this thread, a default, new install of 16.04 has a slight oversight if you are using a wired connection. NetworkManager automatically generates an "ephemeral" configuration, which works great but is, well, ephemeral. This means that the GUID used to hash into a supposedly-consistent IPv6 address isn't stored, and so you get a new one each boot. Just going into NetworkManager, pressing "edit" on the wired connection, and saving it with no changes will generate an actual NM config, with a saved GUID, and so you'll get the same IPv6 address each boot.

This address is an RFC7217 address (a crypto hash of the GUID, your prefix, etc etc) -- so although it's stable each boot, it isn't the sort that includes your MAC address into the address directly. If you want one of those EUI64 addresses, this other answer on this question details how to change that.

Solution 3:

Ubuntu 16.04 and previous releases have always defaulted to the EIU-64 for me, so for servers I have to disable it. I'm happy to use the privacy address on my desktop.

So you need something like:

    sysctl -w net.ipv6.conf.all.use_tempaddr=0
    sysctl -w net.ipv6.conf.default.use_tempaddr=0
    sysctl -w net.ipv6.conf.default.use_tempaddr=0
    sysctl -w net.ipv6.conf.<devname>.use_tempaddr=0

Then ifdown/ifup. The result for me, note the MAC/IPv6 relationship:

$ ifconfig enp3s0 | egrep 'HWaddr|Global'
enp3s0    Link encap:Ethernet  HWaddr 74:d0:2b:90:8b:90  
          inet6 addr: 2501:300:d008:61c8:76d0:2bff:fe90:8b90/64 Scope:Global

You can name specific interfaces if you need it enabled on some interfaces not others. You can see the list with:

$ sysctl -a | grep tempaddr

I don't recommend Network manager for production services. For instance it doesn't it does't play well others, like /etc/sysctl.conf for instance. If you want to do that you willl need an entry in /etc/networking/interfaces for a static address or an automatically configured one. I'm just using:

auto enp3s0 
iface enp3s0 inet dhcp
iface enp3s0 inet6 auto
pre-up modprobe ipv6

Adjust to taste of course.