3

Enabling Privacy Extension (net.ipv6.conf.eth0.use_tempaddr=2 in /etc/sysctl.conf) for IPv6 gives me a new IP address for a fixed period of time, is there a way to get a new IPv6 on demand? i.e. refresh a new IPv6 when needed?

1 Answers1

2

The "active" temporary address has properties temporary and dynamic but not deprecated. When it's about to become deprecated (ie: its preferred_lft value drops to 0), a new temporary address is added by the kernel to the interface.

The interface's current temporary address, will be part of the results shown here:

ip -6 address show temporary dynamic

but not part of the older addresses which are still valid but deprecated shown with:

ip -6 address show temporary deprecated

You just have to lower its preferred_lft property to near zero to trigger the creation of the new temporary address. From trial and error, this won't work if preferred_lft is set below 3: the countdown reaches 0 before triggering the creation and then it won't work anymore (but one can still set again preferred_lft to >= 3 later to get the trigger). I don't know if there's any knob about this peculiarity. 5 seconds looks like a safe value, meaning the new address will appear about 2 or 3 seconds later.

Let's suppose the current found value is 2001:db8::1/64 on interface eth0:

ip address change 2001:db8::1/64 dev eth0 preferred_lft 5

Note that tampering with this removes the dynamic property, which would have not happened naturally, and might possibly trigger later creation of additional temporary addresses sooner than expected.


With ip's JSON output and jq some scriptability is possible, here's what I came with to output the commands ready to pipe to a shell to change all candidate temporary addresses at once (usually requires a multi-homed system to get more than one but tampering with this might perhaps create multiple ones later too). It verifies that the temporary and dynamic address is not deprecated to consider it a candidate:

ip -6 -p -j address show temporary dynamic | jq -j '.[] |
    . as $i |
        .addr_info[] as $a |
            if $a.local == null // $a.deprecated == true then
                empty
            else
                "ip -6 address change ",
                $a.local, "/", $a.prefixlen,
                " dev ", $i.ifname,
                " preferred_lft 5\n"
            end'

which would output again:

ip -6 address change 2001:db8::1/64 dev eth0 preferred_lft 5

You might consider also reducing valid_lft to have the now deprecated address disappear completely faster.

A.B
  • 9,037
  • 2
  • 19
  • 37
  • Your solution had provided me quite a lot of insight into how things work with IPv6, my usage scenario is something like this -> my python script initiates an external download using IPv6, I want a new IPv6 on every invocation of the script, I guess this won't be possible with above (5 second). I would further like to clarify A). If I disable privacy extension can I randomly assign IPv6 IP's from my subnet as source IP's? If yes a python example would be helpful? B). Using privacy extensions what happens to my ongoing/established downloads when the temp address becomes depreceated? – WannabeCoder Aug 24 '20 at 07:55
  • A/ you'll have to check if duplicate address detection is still honoured: keep `ip -6 monitor address` running and check if there is any temporary "tentative" status appearing and disappearing: that means DAD was done and didn't fail. DAD appears to require about 1/2s. A2/ you can add an address in addition to the privacy mechanism, without having to disable it B/ as long as valid_lft doesn't reach 0, the address is still usable (but not selected unless explicitly bound). That means anything currently using it is unaffected. – A.B Aug 29 '20 at 12:46