Anonymizing MAC Address Documentation Clarification

#use random IPv6 addresses per session / don’t leak MAC via IPv6 (cf. RFC 4941):
ipv6.ip6-privacy=2

I think this should be clarified. By default connections use ipv6.addr-gen-mode=stable-privacy which prevents MAC leakage.

Adding ipv6.ip6-privacy=2 is a separate feature which uses temporary addresses for outgoing connections (this prevents MAC leakage also).

The comment should become #OPTIONAL: Use temporary addresses for outgoing connections as opposed to stable address. MAC address leakage via IPv6 is prevented with or without this option.

1 Like

Hm, my experience is different:

nmcli -f 'connection.stable-id,802-11-wireless.cloned-mac-address,802-11-wireless.mac-address-randomization,802-3-ethernet.cloned-mac-address,ipv4.dhcp-client-id,ipv6.addr-gen-mode,ipv6.dhcp-duid,ipv6.ip6-privacy' connection show [wifi network]
connection.stable-id:                   --
802-11-wireless.cloned-mac-address:     --
802-11-wireless.mac-address-randomization:default
ipv4.dhcp-client-id:                    --
ipv6.addr-gen-mode:                     eui64
ipv6.dhcp-duid:                         --
ipv6.ip6-privacy:                       -1 (unknown)

eui64 indicates that my MAC address would be used. Setting ipv6.addr-gen-mode explicitly might work. Btw my Ethernet port had stable-privacy set for some reason.

I believe eui64 is set as /etc/NetworkManager/NetworkManager.conf has the keyfile plugin configured on debian-11 (which I use) by default. On Fedora that appears to be different.

man nm-settings:

        addr-gen-mode
            Configure method for creating the address for use with RFC4862 IPv6 Stateless Address Autoconfiguration. The permitted values are:
            NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64 (0) or NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY (1). If the property is set to EUI64, the
            addresses will be generated using the interface tokens derived from hardware address. This makes the host part of the address to stay
            constant, making it possible to track host's presence when it changes networks. The address changes when the interface hardware is replaced.
            The value of stable-privacy enables use of cryptographically secure hash of a secret host-specific key along with the connection's stable-id
            and the network address as specified by RFC7217. This makes it impossible to use the address track host's presence, and makes the address
            stable when the network interface hardware is replaced. On D-Bus, the absence of an addr-gen-mode setting equals enabling stable-privacy. For
            keyfile plugin, the absence of the setting on disk means EUI64 so that the property doesn't change on upgrade from older versions. Note that
            this setting is distinct from the Privacy Extensions as configured by "ip6-privacy" property and it does not affect the temporary addresses
            configured with this option.

Not sure why the NetworkManager developers decided to use privacy friendly settings only when a certain plugin is disabled. So at least on debian that setting isn’t optional.

Anyway the recommendations at [1] are based on [2], which I guess should be reliable.

I’m still unsure whether

ipv4.dhcp-client-id=stable
ipv6.dhcp-duid=stable-uuid

makes sense as well, but I guess I’ll add that, too.

[1] https://github.com/Qubes-Community/Contents/blob/master/docs/privacy/anonymizing-your-mac-address.md#randomize-all-ethernet-and-wifi-connections
[2] examples/nm-conf.d/30-anon.conf · main · NetworkManager / NetworkManager · GitLab

I think you might have manually set your WiFi connection’s ipv6.addr-gen-mode and not reverted it because ipv6.addr-gen-mode=stable-privacy is the default on Debian. I’m running an up to date debian-11 template with a disposable sys-net. I think you’ve misunderstood the documentation, as did I initially. I think what it’s saying is that if the keyfile plugin reads the connection file from disk and ipv6.addr-gen-mode is missing then it will use EUI64, but NetworkManager itself gets configured via the D-Bus API which uses stable-privacy as the default.

https://wiki.archlinux.org/title/IPv6#NetworkManager_2

Actually, I think I know what’s happened. You first connected to the WiFi network with an older version of NetworkManager where the defalt was EUI64 and that was written to disk so it is still used. Can you delete the connection profile and try again?

I’ve just done some testing and I think these values are good. Maybe get someone else to verify them first but they definitely need to be added to the documentation because the defaults are not good.

There are privacy benefits to ip6-privacy which is why I think they’ve included it, but it’s not necessary. It’s fine to keep in there but it needs to be accurately commented and made optional.

The documentation on anonymizing the hostname is also incorrect, although it does give the expected result. It turns out that NetworkManager doesn’t work as documented and doesn’t actually send the hostname in the case where ipv4.dhcp-hostname=null and ipv4.dhcp-send-hostname=yes. You get the same result if you use the default NetworkManager internal dhcp client. In general NetworkManager overrides the configuration of the dhcp client based on how NetworkManager is configured, so a hostname should be sent even with the send host-name commented out. You can verify this by setting a value for ipv4.dhcp-client-id in NM and commenting out the send dhcp-client-identifier in the dhclient.conf. It sends the value set in NM.

The documentation should just state that a bug in NetworkManager means hostname is not sent in the default configuration. The current method seems like it is doing something but it isn’t. I don’t think there’s a better solution to this problem until No way to set dhcp-send-hostname globally (#584) · Issues · NetworkManager / NetworkManager · GitLab is solved. Maybe get someone else to test this before making the change but I’ve tested thoroughly on debian-11.

I think there also needs to be some comments about active probing on the MAC randomization page. It’s a different topic but people who randomizing MAC often also want to avoid active probing.
The recommendation should be to use a disposable sys-net, otherwise you have to trust that NetworkManager actually forgets a network when you instruct it to and I don’t think that is reliable.

“I think you might have manually set your WiFi connection’s ipv6.addr-gen-mode and not reverted it because ipv6.addr-gen-mode=stable-privacy is the default on Debian.”

I just tested that and it’s 70% true. The 100% truth is that if ipv6.addr-gen-mode=stable-privacy or ipv6.ip6-privacy=2 is not explicitly set anywhere, weird stuff may happen (as I had it). However new connection profiles created at /rw/config/NM-system-connections/[connection].nmconnection currently explicitly contain ipv6.addr-gen-mode=stable-privacy. So NetworkManager uses the weird documented defaults internally, but sets different defaults explicitly when creating new connection profiles (in the current version only!). My connection didn’t have that explicit opt-in as it was created via salt. So I still think that explicitly setting something like ipv6.ip6-privacy=2 makes everyone get the desired results regardless of per-connection settings, which depend on when the connection was created. I added a hint to the PR though [1].

“The documentation on anonymizing the hostname is also incorrect, although it does give the expected result.”

Full ack [1].

“It turns out that NetworkManager doesn’t work as documented and doesn’t actually send the hostname in the case where ipv4.dhcp-hostname=null and ipv4.dhcp-send-hostname=yes. You get the same result if you use the default NetworkManager internal dhcp client. In general NetworkManager overrides the configuration of the dhcp client based on how NetworkManager is configured, so a hostname should be sent even with the send host-name commented out. You can verify this by setting a value for ipv4.dhcp-client-id in NM and commenting out the send dhcp-client-identifier in the dhclient.conf. It sends the value set in NM.”

I’m unsure about that theory as it doesn’t explain why the hostname is sent on debian-11-minimal [2].

“The documentation should just state that a bug in NetworkManager means hostname is not set in the default configuration. The current method seems like it is doing something but it isn’t. I don’t think there’s a better solution to this problem until No way to set dhcp-send-hostname globally (#584) · Issues · NetworkManager / NetworkManager · GitLab is solved. Maybe get someone else to test this before making the change but I’ve tested thoroughly on debian-11.”

I fully agree except I’m unsure whether it’s a bug or something else. I had already planned [1] that way, but had waited for some possible results on [2]. Attempting to file a NetworkManager or Debian bug might lead to some clarifications though.

“I think there also needs to be some comments about active probing on the MAC randomization page. It’s a different topic but people who randomizing MAC often also want to avoid active probing.
The recommendation should be to use a disposable sys-net, otherwise you have to trust that NetworkManager actually forgets a network when you instruct it to and I don’t think that is reliable.”

Is NetworkManager doing active Wifi probing?
I haven’t done testing wrt that. If so, a section dedicated to that topic would indeed make sense. Feel free to send a PR to the community doc.
Fortunately disposable sys-net is the default as of 4.1.

[1] https://github.com/Qubes-Community/Contents/pull/227
[2] Anonymizing hostname doesn't work on Debian 11 minimal sys-net · Issue #217 · Qubes-Community/Contents · GitHub

So everything is working as expected per the documentation. NetworkManager isn’t using different defaults internally and externally. The connection is originally created by the NetworkManager service which is configured via D-Bus so uses ipv6.addr-gen-mode=stable-privacy as default. When the connection profile is written to disk ipv6.addr-gen-mode=stable-privacy is written because that’s what is being used. The next time the connection is loaded the keyfile plugin reads the connection profile and uses the value of ipv6.addr-gen-mode that was previously written (the D-Bus default). If there was no value on disk then they keyfile plugin would use EUI64 (which is what occurred when your connection profile was created manually).

I think it is very unlikely the default would get reverted back to EUI64, but it does not matter if it does because IPv6 addresses are generated from the randomized MAC (not the permanent MAC) which is generated from the stable-id. I have verified this manually.

The issue of previously created connection profiles not getting the new configuration is easily solved by instructing users to delete all old connections.

Setting ipv6.ip6-privacy=2 rotates the temporary address out at random times meaning you can end up connecting to the same server with multiple addresses. This is functionality that is additional to MAC randomization (which the guide is for). The way it is currently documented implies there is just a single temporary address.

You are in control of the document but my final suggestion:

# OPTIONAL: This is an additional privacy mechanism that generates temporary addresses to use for
# outgoing connections. These temporary addresses do not leak MAC address. Be aware that the 
# temporary addresses can rotate randomly and cause you to connect to the same server using different
# addresses. 
ipv6.ip6-privacy=2

This hould be easy to diagnose. Verify that debian-11-minimal and debian-11 use same version of NetworkManager. Run sudo journalctl -u NetworkManager.service in sys-net and confirm that they are both loading the same configuration files. If the versions are the same and the configurations are the same then something strange is happening. I suspect there could be a default configuration difference, but I don’t have debian-11-minimal to test with and I’m moving on from this.

Yes NetworkManager does active probing. I will make a PR when I can.

One last thing that I would like to verify before completely moving on is that the dhcp values are working as expected but I am unable to verify them myself. Would you be able to verify using wireshark/tcpdump that these values are being sent as documented?

ipv4.dhcp-iaid (default) (I’m not sure if this is sent by the internal dhcp client)

ipv6.dhcp-duid=stable-uuid
ipv6.dhcp-iaid (default)

I have solved the hostname issue. NetworkManager looks for the persistent hostname in /etc/hostname which doesn’t exist for debian-11. If you add file /etc/hostname then the hostname is sent (must exist before NetworkManager starts).

This command tells you the current hostname that NetworkManager is using.

nmcli general hostname
1 Like

"I’ve since realized that even if ipv6.addr-gen-mode somehow ends up as EUI64 it does not matter because the IPv6 address is generated from the randomized MAC which is based on the stable-id. I’ve verified this manually.

One last thing that I would like to verify before completely moving on is that the dhcp values are working as expected but I am unable to verify them myself. Would you be able to verify using wireshark/tcpdump that these values are being sent as documented?

ipv4.dhcp-client-id=stable
ipv4.dhcp-iaid (default)

ipv6.dhcp-duid=stable-uuid
ipv6.dhcp-iaid (default)"

I just tested the variant with ipv4.dhcp-client-id=stable and without and honestly I don’t really see the point of that setting as not setting it results in the randomized MAC address to be used as client identifier. Setting it results in some random hex value to be used instead.

The only reason to set it might be to make sure it doesn’t change again in future NetworkManager versions. The doc at least implies that the default behaviour may be subject to change / is undefined: “If unset, a globally configured default is used. If still unset, the default depends on the DHCP plugin.”

I cannot test IPv6 as I have it disabled everywhere, sorry.

“I have solved the hostname issue. NetworkManager looks for the persistent hostname in /etc/hostname which doesn’t exist for debian-11. If you add file /etc/hostname then the hostname is sent.”

A very nice find, thanks for sharing that! I can confirm it on debian-11.
I wonder whether that debian-11-minimal user had created that file accidentally…

Anyway I guess I have to rework that PR again… :smiley:
Thanks a lot for your support!

1 Like

There’s no issue with using the randomized MAC, but as you point out the default is basically undefined. I couldn’t identify what the DHCP plugin was so I think explicit is definitely better in this case.

If by IPv6 disabled everywhere you mean you haven’t opted in to Qubes IPv6 then be aware that some IPv6 traffic still goes out, it’s just gets dropped on the way back in. If you’re disabling it some other way, can you share how?

After realizing the hostname issue isn’t an NM bug I’m happy to trust that NM is doing what it says for those fields but it would be good to get someone to test them.

One last thing, you should set ipv6.ip6-privacy=0 when not using ipv6.ip6-privacy=2. Better to make it explicit than rely on the value in that random file.

I just sent a new PR [1]. Feel free to have a look.

I currently disable IPv6 in 3 ways at the same time:

  1. qvm-features: Networking | Qubes OS
  2. VM kernel option: ipv6.disable=1
  3. net.ipv6.conf.all.disable_ipv6 = 1 in '/etc/sysctl.conf` on debian templates.

Might be a bit overkill, but gets the job done. And I had it in Salt anyway, i.e. I had mostly forgot about it.

[1] anonymize MAC & hostname: misc fixes by 3hhh · Pull Request #228 · Qubes-Community/Contents · GitHub

1 Like

ipv6.ip6-privacy=2 will cause a random IPv6 address to be used during every session. If you want to use an IPv6 address based on the already random MAC address, choose ipv6.ip6-privacy=0. Leaving this setting at the default is not recommended as it is basically undefined.

Regardless of ip6-privacy setting you will have an address based on the stable-id (not MAC). Setting ip6-privacy to 2 will generate additional addresses for outgoing connections (potentially multiple per “session”).

ipv6.addr-gen-mode=stable-privacy is a default explicitly set by current versions of NetworkManager when creating new connection profiles. Setting it globally just makes sure that previously created connection profiles will use the same setting.

You can’t set ipv6.addr-gen-mode globally. The default is built in.

To see all the available configuration options, refer to the man page: man nm-settings

man NetworkManager.conf are the options available for defaults, man nm-settings are all options.

ipv4.dhcp-client-id=stable and ipv6.dhcp-duid=stable-uuid instruct NetworkManager instruct NetworkManager to use a DHCP client identifier based upon the random MAC address

Based upon the stable-id, not MAC address.

This behaviour may be subject to change in future NetworkManager versions though. So please always double check whether your hostname is leaked or not on e.g. your home router, via wireshark or tcpdump.

I think the easier option is to run nmcli general hostname for those that don’t know how to use wireshark/tcpdump.

“ipv6.ip6-privacy=2 will cause a random IPv6 address to be used during every session. If you want to use an IPv6 address based on the already random MAC address, choose ipv6.ip6-privacy=0. Leaving this setting at the default is not recommended as it is basically undefined.”

“Regardless of ip6-privacy setting you will have an address based on the stable-id (not MAC). Setting ip6-privacy to 2 will generate additional addresses for outgoing connections (potentially multiple per “session”).”

ethernet.cloned-mac-address=stable essentially means that stable-ID and MAC are identical. So we’re both right. Since most people have never heard of “stable ID”, I prefer to use the MAC wording though. Btw my tests with ipv4.dhcp-client-id=stable prove that NetworkManager uses the random MAC as intended.
But yes, you’re right wrt multiple IPv6 addresses as per RFC4941.

"ipv6.addr-gen-mode=stable-privacy is a default explicitly set by current versions of NetworkManager when creating new connection profiles. Setting it globally just makes sure that previously created connection profiles will use the same setting.

You can’t set ipv6.addr-gen-mode globally. The default is built in."

I have never found any documentation of what NetworkManager actually accepts to be configured globally and what not… But yes, my test confirms that it doesn’t work as global setting. I’ll remove it then.

1 Like

Btw my tests with ipv4.dhcp-client-id=stable prove that NetworkManager uses the random MAC as intended.

The randomized MAC will be used as the hardware address regardless of this setting. This setting results in the DHCP client id being a random string. Thinking about this some more, the random MAC will always be learnt by the DHCP server, so there’s no point using an additional random string as the client identifier. I think you should update the guide to use ipv4.dhcp-client-id=mac. The reason the template (examples/nm-conf.d/30-anon.conf · main · NetworkManager / NetworkManager · GitLab) uses stable over mac is so that if the interface can’t randomize MAC then a random client identifier will still be used, but I think you can assume that anyone that is logging the client identifier will also be logging the hardware identifier (MAC). Maybe make a comment that if your interface can’t perform MAC randomization that you should use stable. The random string sticks out in the packet dump and is pretty unique, I don’t think many devices do this.

I have never found any documentation of what NetworkManager actually accepts to be configured globally and what not… But yes, my test confirms that it doesn’t work as global setting. I’ll remove it then.

Global defaults are documented in man NetworkManager.conf. You should also verify any configuration that you publish by looking for warnings or errors in sudo journalctl -u NetworkManager.

In the guide you recommend to name the file 00-macrandomize.conf but I think you should name it something so that it takes precedence over the default file. At the moment the values in 31-randomize-mac.conf will override any values set by 00-macrandomize.conf. Perhaps suggest naming it 50-macrandomize.conf.

Well, the default is the most common setting and uses the random MAC, so I decided to remove it again.

This section is now back to where it was in the beginning… :lol:

1 Like

Why have you gotten rid of the DHCP configuration?

ipv4.dhcp-client-id=mac is necessary because the default it to use the “DHCP plugin” which there is no information about anywhere. At the moment it happens to use MAC, but that’s not reliable.

ipv6.dhcp-duid=stable-uuid is necessary because the default is to use “lease” which is bad.

“ipv4.dhcp-client-id=mac is necessary because the default it to use the “DHCP plugin” which there is no information about anywhere. At the moment it happens to use MAC, but that’s not reliable.”

If the DHCP plugin ever changes its behaviour, the setting will also change for privacy focused users. So they’ll stick with “the masses”, which should be privacy friendly. That’s the intention. If the default ever goes to something really awful (e.g. hardware MAC), one can still set it explicitly.

“ipv6.dhcp-duid=stable-uuid is necessary because the default is to use “lease” which is bad.”

Ah yes, I hadn’t explicitly checked the doc on that one as I had assumed it would be the IPv6 equivalent of ipv4.dhcp-client-id in behaviour as well… NetworkManager is a mess configuration-wise.

So on what should we align regarding the ipv6 setting?
I don’t want to send another ton of PRs and invest even more time. So maybe we should align beforehand this time.

Btw I also wouldn’t mind giving up or at least sharing maintainership for that page. However over the last 3-5 years or so no one took care of it and I use these settings myself, so I attempted to verify and optimize them for my use and put that stuff back upstream. I certainly have no intention of being the exclusive maintainer or anything as long as edits are privacy-friendly and reasonable.

If the DHCP plugin ever changes its behaviour, the setting will also change for privacy focused users. So they’ll stick with “the masses”, which should be privacy friendly. That’s the intention. If the default ever goes to something really awful (e.g. hardware MAC), one can still set it explicitly.

So instead of setting it explicitly you recommend we leave it up to an undocumented plugin and make sure we closely monitor everytime NetworkManager updates? That makes no sense to me. It’s a good chance that NM will never alter the beahvior but why would you risk it when you can make sure it will never be an issue by adding a single line. I will definitely be including that line in my config.

So on what should we align regarding the ipv6 setting? I don’t want to send another ton of PRs and invest even more time. So maybe we should align beforehand this time.

I think we go with examples/nm-conf.d/30-anon.conf · main · NetworkManager / NetworkManager · GitLab and use ipv6.dhcp-duid=stable-uuid.

Btw I also wouldn’t mind giving up or at least sharing maintainership for that page. However over the last 3-5 years or so no one took care of it and I use these settings myself, so I attempted to verify and optimize them for my use and put that stuff back upstream. I certainly have no intention of being the exclusive maintainer or anything as long as edits are privacy-friendly and reasonable.

Once this document is finalized I won’t have much to contribute so there’s not much point in giving me access. Hopefully this is the last change that needs to be made.

OK, I re-introduced ipv6.dhcp-duid=stable-uuid.

Btw ipv4.dhcp-client-id=mac is only supported for Ethernet devices according to the doc.