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