MAC spoofing con indirizzo casuale generato dal kernel Linux
Stavo litigando con un Microchip LAN 9500 senza la EEPROM in cui salvare il suo indirizzo MAC. Usando il driver smsc95xx fornito dalla mainline di Linux, mi sono accorto che il kernel stava (ragionevolmente) creando un indirizzo random ad ogni reboot.
Al mio cliente questo non piaceva, e del resto l'oggetto avrebbe dovuto lavorare solo all'interno di una LAN, così ho iniziato a cercare un modo per fare MAC spoofing.
Ho trovato questo link interessante, che mi ha dato le prime idee su come affrontare il problema.
Tuttavia, nessuno dei metodi automatici proposti stava funzionando nella mia
distribuzione Yocto. Ad esempio, il "Method 1", basato su
/etc/systemd/network/00-default.link
, mi dava questo messaggio di errore
nel journalctl:
Dec 12 09:22:26 colibri-imx6 systemd-udevd[273]: Could not set Alias, MACAddress or MTU on eth1: Device or resource busy Dec 12 09:22:26 colibri-imx6 systemd-udevd[273]: Could not apply link config to eth1: Device or resource busy
Temo che systemd stava cercando di applicare la regola troppo presto, quando l'interfaccia eth1 era ancora occupata a fare altro.
Un altro problema con il metodo standard di spoofing è legato al MAC address da ottenere, che dovrà essere cambiato manualmente per ogni macchina, e questo non è semplice da gestire. Pensai che la cosa migliore sarebbe lasciare che il kernel generi l'indirizzo casuale al primo boot, e che poi il sistema lo riusi ai reboot successivi.
Ecco come sono riuscito a ottenere questo obiettivo, e qualche suggerimento nel caso che voglia fare lo stesso.
Prima di tutto, ho scelto, nel mio filesystem, dove mettere gli script per lo
spoofing. Ho deciso di creare una directory apposita,
/var/local/mac_spoof/
.
Poi, ho aggiunto la seguente regola di udev, creando un file di una linea in
/etc/dev/rules.d/75-mac-spoof.rules
. Questo il suo contenuto:
ACTION=="add", SUBSYSTEM=="net", KERNEL=="eth1", RUN+="/var/local/mac_spoof/mac_spoof.sh %k"
Per finire, questo è lo script /var/local/mac_spoof/mac_spoof.sh
:
#!/bin/sh ETH=$1 BATCH=/var/local/mac_spoof/${ETH}_spoof.batch ADDR=$(cat /sys/class/net/$ETH/address) # Create batch file if not exists (first boot) if [ ! -f $BATCH ] then echo link set dev $ETH down > $BATCH echo link set dev $ETH address $ADDR >> $BATCH echo link set dev $ETH up >> $BATCH fi # Apply ip batch, or delete it if anything failed ip -batch $BATCH || rm -f $BATCH
Come funziona lo script
mac_spoof.sh
è chiamato da udev ogni volta che l'interfaccia
eth1 viene aggiunta al sistema. Il suo compito è:
controllare se il file
/var/local/mac_spoof/eth1_spoof.batch
esiste; in caso negativo, lo crea scrivendo il batch ip per eseguire MAC spoofing d'ora in avanti. L'indirizzo (variabileADDR
) è letto da sysfs, e basandosi sul fatto che è stato creato in maniera random dal kernel;applicare il batch ip, or cancellare il file the
eth1_spoof.batch
in caso di fallimento.
Ecco come controllare che tutto sia andato bene: l'indirizzo MAC in eth1_spoof.batch deve essere lo stesso di quello ritornato dal comando ip (o ifconfig). Nel mio caso, si può vedere che è 52:23:64:e2:fa:ad in entrambi i casi:
root@colibri-imx6:~# cat /var/local/mac_spoof/eth1_spoof.batch link set dev eth1 down link set dev eth1 address 52:23:64:e2:fa:ad link set dev eth1 up root@colibri-imx6:~# ip addr show eth1 4: eth1: <BROADCAST,MULTICAST,DYNAMIC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 52:23:64:e2:fa:ad brd ff:ff:ff:ff:ff:ff inet 169.254.138.55/16 brd 169.254.255.255 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::5023:64ff:fee2:faad/64 scope link valid_lft forever preferred_lft forever
Questo metodo ha funzionato nel mio caso, non posso assicurare che funzioni su qualsiasi distribuzione o situazione; se trovi qualcosa da segnalarmi, contattami.