MAC Address Spoofing in NetworkManager 1.4.0

The new NetworkManager release 1.4.0 adds new features to change the current MAC address of your Ethernet or Wi-Fi card. This is also called MAC address “spoofing” or “cloning”.

His name is Václav
Václav sleeps better with NetworkManager’s MAC address randomization

Previously NetworkManager 1.2.0 added MAC address randomization for Wi-Fi, as Lubomir explains in his blog post. He also explains why you may want to do that in the first place, so I skip the introduction. Suffice to say, some consider randomizing the MAC address an important feature to protect their privacy. Only be aware that for real™ privacy, more considerations come into play. The Tails distribution and Wikipedia have good reads on the subject.

1.2.0 relies on support from wpa_supplicant to configure a random MAC address. The problem is that it requires API which will only be part of the next major release 2.6 of the supplicant. Such a release does not yet exist to this date and thus virtually nobody is using this feature.

With NetworkManager 1.4.0, changing of the MAC address is done by NetworkManager itself, requiring no support from the supplicant. This allows also for more flexibility to generate “stable” addresses and the “generate-mac-address-mask”. Also, the same options are now available not only for Wi-Fi, but also Ethernet devices.

Tools like macchanger and macchiato are commonly used to change the MAC address of a device. They support flexible mechanisms to generate a random address, most of these options are now also supported by NetworkManager.

Randomization during Wi-Fi scanning

During Wi-Fi scanning, NetworkManager resets the MAC address frequently to a randomly generated address. This was already enabled by default in 1.2.0, but as said, users likely didn’t have the required support from wpa_supplicant.

This default behavior can be disabled with a global configuration option in NetworkManager.conf:

[device]
wifi.scan-rand-mac-address=no

Note that this is a per-device configuration value, because at the time of Wi-Fi scanning, no connection is yet activated. A “connection” in NetworkManager-speak is a profile, a bunch of settings.

Supported Modes

Since long, NetworkManager supports two connection properties “ethernet.cloned-mac-address” and “wifi.cloned-mac-address”. These settings take effect when activating the connection. They got extended in 1.4.0 and support the following values:

  • An explict MAC address: this was already supported before 1.4.0 and allows to spoof a specific MAC address.
  • “permanent”: use the permanent MAC address of the device. Before 1.4.0, the permanent MAC address was used if the “cloned-mac-address” property was left empty, thus it was the default.
  • “preserve”: don’t change the MAC address of the device upon activation.
  • “random”: generate a randomized value upon each connect.
  • “stable”: generate a stable, hashed MAC address.
  • NULL/unset: this is the default value which allows fallback to a globally configured default, see below. In case no global override exists, NetworkManager falls back to “permanent”, like it did before.

Update-2017-01-25: with 1.6 release and newer, the default value changed from “permanent” to “preserve” [commit],[bug].

Note that in the D-Bus API, the “cloned-mac-address” field is not a string and thus could not be extended in a backward compatible way. That is why on D-Bus there are new fields “ethernet.assigned-mac-address” and “wifi.assigned-mac-address” instead. On the other hand, in nmcli, libnm.so, and keyfile-format the properties are indeed called “cloned-mac-address”.

How to configure it?

It is likely that your favorite NetworkManager client does not expose these options in the UI. In that case, I would suggest to use nmcli to configure the per-connection settings:

$ nmcli connection show
NAME               UUID               TYPE            DEVICE
My Wi-Fi           fca8fc45-c47...    802-11-wireless --
...

$ nmcli connection show "My Wi-Fi"
...

$ nmcli connection modify "My Wi-Fi" \
        wifi.cloned-mac-address stable

$ nmcli connection up "My Wi-Fi"

$ ip link show
...

Stable MAC Address Generation

The “stable” method warrants more explanation. In a way it is similar to “random”, but instead it generates a stable, hashed value. This way every time the connection activates, the same address is generated. However, each connection generates a different address.

This is for example useful so that you get the same IP address from DHCP, which might not be the case with “random”. Or a captive-portal might remember your login-status based on the MAC address. With “random” you may be required to re-authenticate on every connect.

The “stable” mode still makes you easily recognizable when you re-connect to a previous network, but your hardware MAC address is hidden and tracking you across different networks may be harder (YMMV).

The stable address is generated by hashing a private key from /var/lib/NetworkManager/secret_key, the ifname of the device, and a stable-id. The stable-id by default is the UUID of the connection (“connection.uuid”), unless you configure the new property “connection.stable-id“. The latter allows you to have multiple connections that generate the same MAC address. Note that “connection.stable-id” property is also used when generating stable-privacy IPv6 addresses (“ipv6.addr-gen-mode”, RFC 7217).

Format of the MAC Address

The “random” and “stable” modes both generate a MAC address. By default, all 48 bits of the MAC address are scrambled except the following two bits. For one, the LSB of the first octet which must always be cleared to indicate a unicast MAC address. And then, the 2nd-LSB of the first octet is set to indicate a locally administered address — contrary to a burned-in address. This has the same effect as calling macchanger --random with respect to which bits are scrambled.

Which bits are scrambled is configurable by the per-connection properties “ethernet.generate-mac-address-mask” and “wifi.generate-mac-address-mask” [man]. During Wi-Fi scanning, the per-device property “wifi.scan-generate-mac-address-mask” is used instead [man].

The property works as follows. If the mask-setting contains one MAC address, that address is used as a mask. For example “FF:FF:FF:00:00:00” results in randomizing the lower 3 octets and use the vendor OUI of the device’s permanent MAC address. This is similar to macchanger --ending, except that NetworkManager uses the permanent MAC address of the device while macchanger preserves the OUI of the current address.

Update-2016-11-04: it doesn’t use the permanent MAC address, instead the “initial” MAC address, that is the current MAC address that was configured on the device outside of NetworkManager.

If after the initial mask a second MAC address follows, that address is used instead of the device’s permanent address. For example “FF:FF:FF:00:00:00 00:50:E4:00:00:00” sets the OUI to “00:50:E4” but randomizes the last 3 octets. Likewise, “02:00:00:00:00:00 00:00:00:00:00:00” scrambles all bits but clears the second LSB of the first octet, thus creating a burned-in address like macchanger --random --bia.

Actually, there can follow arbitrary many MAC addresses after the mask, in which case one will be chosen randomly. “02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00” will scramble all 47 bits — except the unicast bit which must be always cleared. This allows you to specify a list of OUIs.

Global Default Configuration

NetworkManager supports certain per-connection properties to fallback to a globally configured default value. By having “cloned-mac-address” or “generate-mac-address-mask” unset, it allows fallback to a value configured in NetworkManager.conf.

For example, I have a file /etc/NetworkManager/conf.d/30-mac-randomization.conf like:

[device-mac-randomization]
# "yes" is already the default for scanning
wifi.scan-rand-mac-address=yes

[connection-mac-randomization]
ethernet.cloned-mac-address=random
wifi.cloned-mac-address=random

which sets the default fallback to random. Only for a few selected connection profiles I explicitly switch the per-connection setting to “stable”.

Note: distributions and packages are advised to install configuration snippets to /usr/lib/NetworkManager/conf.d directory instead of /etc.

What’s missing?

What feature do you miss?

One idea would be to support some special “connection.stable-id”. This would allow to implement a “change daily” feature like Windows 10 has. Allowing for a stable-id “time: <date> <time> <period>” could have the effect to start at <date>-<time> and generate a new ID each <period> time. Say, “time: 2016-08-22 6:00:00 7d” could mean to generate a new ID every Monday at 6:00 a.m. Of course, the ID only gets re-generated upon activation of a connection.

Update-2017-01-25: since 1.6, NetworkManager supports dynamic stable-ids like "${BOOT}", "${CONNECTION}", "${RANDOM}" or any combination of these. This also affects RFC7217 stable privacy IPv4 addresses [commit], [example].

Another idea would be to allow a special keyword “preserve” in “generate-mac-address-mask”. It could be used to set a value like “FF:FF:FF:00:00:00 preserve” which should have the same effect as macchanger --ending and use the current MAC address instead of the permanent one.

If you have problems, questions or suggestions, meet us on mailing list, IRC (#nm on freenode) or check our documentation and our bugtracker.

6 thoughts on “MAC Address Spoofing in NetworkManager 1.4.0”

  1. I am using 1.4.2 under Linux Mint (Debian version) and this procedure does not work. I downloaded 1.4.2 from unstable and installed using aptitude. Network manager works fine after update but the only recognition of the of mac randomization is in the applet where the word “permanent” appears in the place where the cloned mac address normally goes.

    So I tried the command line procedure outlined above. When I use the “modify” command to mark the profile to “random” it processes the command but breaks the profile. It won’t connect. Both ifconfig and macchanger show that network manager is randomizing the mac address upon each connection attempt after applying the modify command. However, the profile won’t connect either using the applet or using the “connection up” command.

    The only way I could get my connection working again was to delete the profile, create a new profile, reboot the machine, and then apply the modify command using the permanent option to the new profile. Note that these are the precise steps that have to be followed in this order otherwise the connection will stay broken. Simply deleting the profile and creating a new one was not enough.

    So the upshot is that the mac randomization is working properly but it is breaking the profile so one cannot get an Internet connection. I have no idea why.

    1. James, it’s not clear from your description why `nmcli connection up` fails or in which way the profile is broken. Also, it is quite unlikely that you have to delete a profile that is ill-configured, you can also undo your change, for example via `nmcli connection modify $NAME wifi.cloned-mac-address ”`. Of course, deleting and re-creating works too. You usually also don’t have to reboot (or restart NetworkManager).

  2. Well explainded Thomas, however in wifi card stock this tutorial are good, but when I used a wifi card USB, doesn’t work. There are any setting else for USB cards?

    My best.

  3. I haven’t understood this “feature”. So you are exploiting WiFi standards to have false feeling of improved privacy? Most subjects today use more advanced methods for user tracking. E.g. for free WiFi hotspots there is usually web login form for newly appearing MACs, so it’s easy to pair users with MACs by utilizing HTTP agent fingerprints, cookies, third party tracking sites (e.g. Facebook) etc. Randomly changing MACs is strange and shouldn’t be done. It increases probability of collisions which you are unable to detect as you needn’t hear all stations connected to the AP.

    Also I don’t understand why you need to change MAC during scanning. If SSID is visible you can do passive scan and you needn’t transmit anything, so you don’t need to change the MAC.

    I am afraid that this “feature” will break a lot of users, because MAC ACLs are still quite common. For free WiFi hotspots it would probably require user to often re-login through the web form.

    I think that at least this “feature” shouldn’t be on by default.

    1. I tried to make clear that changing the MAC address alone cannot defeat all other forms of tracking. Some people think this is an essential feature, that is why tools like macchanger exist. What that is actually the case is a different question.

      Which Wi-Fi standards do you see exploited there?

      The probability of collision is extremely low (because the range of Wi-Fi is some 100 meters). It is like a million times more likely that you loose association because your neighbor turns on his Microwave oven then that he accidentally uses NetworkManager and accidentally choose the same MAC address as you.

      Passive SSID scans are possible, but that is not usually done because they take too long. NetworkManager certainly doesn’t do passive scans (maybe it should, but certainly not by default, because it just takes too long).

      Wi-Fi hotspots requiring re-login only matters during association and only happens with “method=random”. That is not the default, nor is likely to become the default. Randomization during scanning doesn’t matter here, and is indeed the default.

      The “feature” that is only by default is ~only~ randomization during scanning. Most points you make don’t apply in that case.

  4. Thanks for this helpful article. Finally I understood the different randomization modes and how to actively use them for e.g. keeping my privacy and/or extending time-limited hotspot possibilities. :-)

Comments are closed.

Leave a Reply

Your email address will not be published. Required fields are marked *