NetworkManager gained itself the ability to change the ethernet MAC addresses of interfaces it handles, and does it by default on wireless interfaces. This will override any other tool having changed the MAC address of the interface before.
Per connection settings for ethernet are prefixed with 802-3-ethernet., for wireless with 802-11-wireless.. I will show an example with ethernet, and will tell about the differences with wireless after.
Ethernet
The main setting about this for each connection is called 802-3-ethernet.cloned-mac-address. Note also that cloned-mac-address is what is displayed by nmcli for compatibility reasons. The actual property is internally named assigned-mac-address. There are a few related too:
$ nmcli connection show id Myeth0 |grep mac # permanent MAC was redacted
802-3-ethernet.mac-address: 06:05:04:03:03:01
802-3-ethernet.cloned-mac-address: --
802-3-ethernet.generate-mac-address-mask:--
802-3-ethernet.mac-address-blacklist: --
mac-address when set (it usually is) tells the connection applies only to the NIC with this permanent MAC address (as can be retrieved also with ethtool --show-permaddr eth0), mac-address-blacklist is the opposite: to avoid a generic connection to apply to a given interface with this MAC address (obviously only one of them should be set). They aren't used for MAC spoofing settings.
So there are a few choices:
not using NetworkManager
but for example directly wpa_supplicant and a DHCP client.
asking NetworkManager to not interfere anymore
You can ask NetworkManager to not touch the MAC address at all:
# nmcli connection down id Myeth0
# nmcli connection modify id Myeth0 802-3-ethernet.cloned-mac-address preserve
# ip link set eth0 down #very old NICs don't support changing MAC when up
# ip link set eth0 address 0A:09:08:07:06:05
# nmcli connection up id Myeth0
The newly set MAC address will be preserved to whatever value it has currently.
or simply letting NetworkManager do this work and not have to use an other tool before:
$ nmcli connection modify id Myeth0 802-3-ethernet.cloned-mac-address 0e:0d:0c:0b:0a:09
$ nmcli connection down id Myeth0
$ nmcli connection up id Myeth0
NM will now take care of changing the MAC address to the one specified.
To revert to permanent, you can set 802-3-ethernet.cloned-mac-address to permanent (or leave it empty as this is the default for ethernet).
There are other modes like random or stable where generate-mac-address-mask can also be used (for example to generate a random MAC but appearing to be always from the same real manufacturer)
Wireless
By default, when 802-11-wireless.cloned-mac-address is empty, random is used.
There's a 802-11-wireless.mac-address-randomization which might be deprecated which maybe affects the previous setting. Not very clear in documentation, but not really needed
Most of these settings are also exposed in the GUI applet. The "Cloned MAC address" field there isn't limited to a drop-down menu: you can put a MAC address in the field instead of predefined values (Preserve, Permanent, Random, Stable).
There's an additional wifi setting I don't know how to change except by editing NetworkManager's configuration files: wifi.scan-rand-mac-address: set to yes by default, it tells NetworkManager to change the MAC address of the wifi interface when scanning. This setting is global or per device, but not per connection, since there's no connection activated yet. To change it to no instead of yes you could add a file in /etc/NetworkManager/conf.d/devicewlan0.conf looking like this:
[device]
match-device=interface-name:wlan0
wifi.scan-rand-mac-address:no
but the documentation isn't very verbose about it. Anyway this setting would be needed, perhaps, only if the 2nd option above was chosen (preserve) rather than the 3rd (setting a MAC address).
references:
https://developer.gnome.org/NetworkManager/stable/settings-802-3-ethernet.html
https://developer.gnome.org/NetworkManager/stable/settings-802-11-wireless.html
https://developer.gnome.org/NetworkManager/stable/NetworkManager.conf.html (check device section)