Raspberry Pi 3B+ MAC Spoofing

Hi. Currently our Balena application spoofs the MAC address on the Raspberry Pi’s ethernet connection, and we’ve done this successfully for quite some time. This was done using Raspberry Pi 3B’s.

Recently though, we’ve been adding some Raspberry Pi 3B+'s. When our MAC spoofing routine runs on this new model, it brings down the ethernet interface and subsequently disconnects from balenaCloud.

After investigating a bit, it turns out that the MAC address is indeed being spoofed as confirmed by ifconfig and nmcli, but the device never gets an IPv4 lease from the router. ifconfig does indicate that it was able to pick up a Link & Global IPv6 address (not sure if that’s relevant). In the end though, the device cannot reach out to the internet. As soon as I undo the change and bring the interface back up, it gets an IPv4 lease immediately and can get out to the wider internet.

I did also read about the smsc95xx.macaddr boot option that can be set in cmdline.txt before the SD card is installed in the Pi. I confirmed that this method works on the 3B+. Unfortunately, we need the MAC spoof to happen at run-time, so this option is ruled out. That said, it got me thinking that it would be possible to set this indirectly at run-time by using the Resin API to set the appropriate RESIN_HOST_CONFIG_* device config variable. However that’s also not possible because the API complains that “Configuration variable names can only contain alphanumeric characters and underscores.”, and of course there is a period in the desired config variable name. (Which in turn is because the config variables utilize bash environment variables underneath which is where this restriction originates from.)

Is there something I’m missing or a different way to set the MAC at run-time? Feel free to ask me for any more info that I may have missed :slight_smile: There were a couple other things that I tried that I omitted since this post is already getting pretty long, but I’d be happy to discuss those as well if helpful.

Here’s the minimal nmcli command that demonstrates the different behavior on the 3B and 3B+:

export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

nmcli --nocheck con mod "Wired connection 1" 802-3-ethernet.cloned-mac-address "B8:27:EB:00:00:00"
nmcli --nocheck con up "Wired connection 1"

Supervisor: 9.0.1
Host OS: balenaOS 2.29.2+rev2
VM OS: Debian Stretch

Dockerfile:

FROM resin/%%RESIN_MACHINE_NAME%%-debian:latest

RUN apt-get update && \
    apt-get install network-manager && \
    systemctl mask NetworkManager

ENV INITSYSTEM on