Random MAC when bringing the network interfaces
From Telecomix Crypto Munitions Bureau
This script has been working for me on Ubuntu 9.04. When "networking" is restarted - or started, such as when the system is - it attempts to change the MAC address of all interfaces. It currently does not have any error detection, but as I haven't had any problems with it, I haven't needed it either. Please visit our IRC channel if you are having problems with it.
Contents |
[edit] /etc/init.d/networking
#!/bin/sh -e
### BEGIN INIT INFO
# Provides: networking
# Required-Start: mountkernfs ifupdown $local_fs
# Required-Stop: ifupdown $local_fs
# Default-Start: S
# Default-Stop: 0 6
# Short-Description: Raise network interfaces.
### END INIT INFO
## INSTALL:
# sudo cp networking.sh /etc/init.d/networking
PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
[ -x /sbin/ifup ] || exit 0
. /lib/lsb/init-functions
# helper function to set the usplash timeout. https://launchpad.net/bugs/21617
usplash_timeout () {
TIMEOUT=$1
if [ -x /sbin/usplash_write ]; then
/sbin/usplash_write "TIMEOUT $TIMEOUT" || true
fi
}
random_mac_for_interface(){
interface=$1
MACCC=`perl -e '@x=map(sprintf("%02x",$_), map(int(rand($_)), 00,255,255,255,255,255));print @x,"\n"'`
log_action_begin_msg Setting MAC address $MACCC for interface $interface
ifconfig $interface hw ether $MACCC 2>/dev/null || true
}
process_options() {
[ -e /etc/network/options ] || return 0
log_warning_msg "/etc/network/options still exists and it will be IGNORED! Read README.Debian of netbase."
}
check_network_file_systems() {
[ -e /proc/mounts ] || return 0
exec 9<&0 < /proc/mounts
while read DEV MTPT FSTYPE REST; do
case $DEV in
/dev/nbd*|/dev/nd[a-z]*|/dev/etherd/e*)
log_warning_msg "not deconfiguring network interfaces: network devices still mounted."
exit 0
;;
esac
case $FSTYPE in
nfs|nfs4|smbfs|ncp|ncpfs|cifs|coda|ocfs2|gfs|pvfs|pvfs2|fuse.httpfs|fuse.curlftpfs)
log_warning_msg "not deconfiguring network interfaces: network file systems still mounted."
exit 0
;;
esac
done
exec 0<&9 9<&-
}
case "$1" in
start)
process_options
log_action_begin_msg "Configuring network interfaces"
usplash_timeout 120
for interface in `ifconfig -a -s | egrep -v "^(lo|Iface)" | cut -f 1 -d" "`; do
random_mac_for_interface $interface
done
if [ "$VERBOSE" != no ]; then
if ifup -a; then
log_action_end_msg $?
else
log_action_end_msg $?
fi
else
if ifup -a >/dev/null 2>&1; then
log_action_end_msg $?
else
log_action_end_msg $?
fi
fi
usplash_timeout 15
;;
stop)
check_network_file_systems
log_action_begin_msg "Deconfiguring network interfaces"
if [ "$VERBOSE" != no ]; then
if ifdown -a --exclude=lo; then
log_action_end_msg $?
else
log_action_end_msg $?
fi
else
if ifdown -a --exclude=lo >/dev/null 2>/dev/null; then
log_action_end_msg $?
else
log_action_end_msg $?
fi
fi
;;
force-reload|restart)
process_options
log_action_begin_msg "Reconfiguring network interfaces"
ifdown -a --exclude=lo || true
for interface in `ifconfig -a -s | egrep -v "^(lo|Iface)" | cut -f 1 -d" "`; do
random_mac_for_interface $interface
done
if ifup -a --exclude=lo; then
log_action_end_msg $?
else
log_action_end_msg $?
fi
;;
*)
echo "Usage: /etc/init.d/networking {start|stop|restart|force-reload}"
exit 1
;;
esac
exit 0
[edit] if-pre-up.d
This has not been tested, so if you try it, please remove this notice if it works. If it doesn't work, you could try to fix it or just remove the entire section if it's made of aids and fail.
Download this list of vendors and their MAC address prefixes and save somewhere: http://standards.ieee.org/regauth/oui/oui.txt
Create a file in /etc/network/if-pre-up.d/ with this content, and fix the path to oui.txt
#!/bin/bash
for interface in `ifconfig -a -s | egrep -v "^(lo|Iface)" | cut -f 1 -d" "`; do
ifconfig $interface hw ether $(grep -Eo '^[0-9A-F]{6}' /path/to/oui.txt | shuf -n 1)$(hexdump -n3 -e'3/1 "%02X"' /dev/urandom)
done
[edit] rc.multi
This has been tested on Arch.
Fetch macchanger
pacman -S macchanger
Add this above the #Start Daemons loop
macchanger -r eth0
Change eth0 to any interface you want to have spoofed
[edit] See also
http://www.alobbs.com/macchanger (macchanger sucks because it uses a pseudo-random number generator that is seeded with the current unix timestamp - if you call macchanger -r twice within the same second, it will assign the same MAC address to the two different NICs, causing all sorts of trouble. Also, it's easily replaced by the perl script above)
[edit] /etc/init.d/macchanger.sh
I have not seen any of the problems described above but that may be because they only occur when fully random values are used to replace the MAC. I use the -e setting to just replace the ending. This results in different MACs for my eth0 and wlan0 interfaces.
An advantage to this script is that it does not require changing any other script installed by the system.
Tested on Debian Wheezy.
Update Sept 9, 2012: Small change to the Required-Start parameter because of changes in Debian Wheezy. If you're using this script or one based on it and you updated it, you will need to run update-rc.d to make sure the new file is called at the right time.
#!/bin/sh
### BEGIN INIT INFO
# Provides: macchanger
# Required-Start: mountall-bootclean
# Required-Stop:
# X-Start-Before: networking
# Should-Start: glibc
# Default-Start: S
# Default-Stop:
# Short-Description: Randomize the wlan0 and eth0 mac addresses.
# Description: Randomize the wlan0 and eth0 mac addresses.
### END INIT INFO
#
# Written by Someone
#
## INSTALLING
# sudo cp macchanger.sh /etc/init.d/macchanger.sh
# sudo chmod u+x /etc/init.d/macchanger.sh
# sudo update-rc.d macchanger.sh start defaults
PATH=/sbin:/bin
. /lib/init/vars.sh
. /lib/lsb/init-functions
do_start () {
/usr/bin/macchanger -e wlan0
/usr/bin/macchanger -e eth0
exit 0
}
case "$1" in
start|"")
do_start
;;
restart|reload|force-reload)
echo "Error: argument '$1' not supported." >&2
exit 3
;;
stop)
# No-Op
;;
*)
echo "Usage: macchanger.sh [start|stop]" >&2
exit 3
;;
esac

