The problem:
The requirement: To move a linux software product licensed by MAC, from the physical machine into the virtualized environment or the cloud and to have it still running.
Solutions:
1. Contact the software vendor and get a new license based on the new MAC address in the virtualized environment.
That's the perfect solution in case the software vendor is NOT a mother-fu***r, as hungry for money as a fat kid for chocolate (this is not mine, it is from a song :)In my case, I wasn't lucky and they asked for money for this operation "not covered by the license".
Just a small piece of info: the software I talk about costs ~20,000 euro and the support for it is "just" 16% from the cost, per year. Define greediness...
2. Change the MAC address of your main network card in VMWare
This can be done in Linux by adding (or modifying) the HWADDR=aa:bb:cc:... / MACADDR=aa:bb:cc:.. configuration options in /etc/sysconfig/network-scripts/ifcfg-eth0 as to indicate the new MAC address.I added them both but in my VMWare Workstation 10 environment, this didn't work until I modified the advanced parameters of the network interface and put there the new MAC too.
On my Ubuntu host having VMWare 10 and CentOS as guest VM, this is done in:
VM Settings->Hardware->Network Adapter->Advanced->MAC Address
Then it worked perfect.
3. Create a dummy interface with the needed MAC address
Then I moved to the cloud, where things were not totally in my control. The cloud guys didn't know how (or didn't bother) to set the MAC for me, saying that OnApp virtualization doesn't accept this. Maybe they are actually right, but wat to do wat to do...I followed this tutorial: http://www.question-defense.com/2012/11/26/linux-create-fake-ethernet-interface but it doesn't work because it has some typos and wrong indications, so I thought I should re-publish it here, edited. So: how to create a dummy interface on your CentOS machine, just to use its MAC address for licensing purposes:
Assumptions:
- you will create a new fake / dummy interface, named eth1 with MAC address: aa:bb:cc:dd:ee:ff . If you need another interface number, please modify in the code below. Also replace aa:bb:cc.... with your own MAC address you need to clone.Step 1
Add the following lines to /etc/rc.d/init.d/network , on top if the file./sbin/modprobe dummy
/sbin/ip link set name eth1 dev dummy0
/sbin/ifconfig eth1 hw ether AA:BB:CC:DD:EE:FF
Notes:
- the tutorial linked above, indicates you should put this in /etc/rc.local to work, which is WRONG. /etc/rc.local is executed after /etc/rc.d/init.d/network, and so, you'll get an error at boot time, saying: device eth1 does not seem to be present, delaying initialization
- I know that altering /etc/rc.d/init.d/network it is not ok in case of upgrades, etc. In my case it is ok because I have no intention to upgrade it ever (the software works anyway only on CentOS 5 so I need to keep it 5 and not upgraded it to the latest 7). Still, if you know about a script similar to /etc/rc.local that executes before the others in /etc/rc.d/init.d/, I'd like to hear from you!
Step 2
Add to /etc/sysconfig/network-scripts a new file named ifcfg-eht1. Actually, just copy ifcfg-eth0 with the new name, then edit the ifcfg-eth1:cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth1
After editing it, my ifcfg-eth1 looks like:
DEVICE="eth1"
ONBOOT="yes"
So only a couple of things were mentioned: that is named eth1 and that it should be brought up when system starts. Nothing else, since it will be unused for networking; just to have it in the system with a MAC. The tutorial linked above, misses this step.
Step 3
Reboot the system or reload networking. Then, issue a ifconfig at command prompt and admire your new MAC faked interface.Notes:
- If you follow the boot messages you'll see that there is a warning though when it tries to bring up eth1: RTNETLINK answers: no such device
Fortunately, it is just a warning and the eth1 is present in ifconfig afterwards. Still, if anyone knows how to get rid of this warning too, I'd be happy to update this post.
4. Fake your MAC dynamically, per request
Instead of doing something definitive like creating a new network interface or so, what about reporting a fake MAC to those apps that are known to ask for it?
This most elegant approach can be done using https://blog.kumina.nl/2011/12/spoofing-mac-addresses-using-fakemac/ or http://www.chiark.greenend.org.uk/~peterb/linux/fakeif/ or ftp://mirror.inode.at/slackwarearm/slackwarearm-devtools/slackkit/fakeuname.c or others.
All are some type of wrappers that launch the executable and intercepts any calls to the SIOCGIFHWADDR (the low level C function returning the real MAC Address), replacing it with the one we want.
It happens that I've liked fakeuname that allows for faking also hostname, so that's the one I tried (not that the others are not ok!). To make it work you need to:
Step 1
Download the fakeuname.c file and save it somewhere.
Step 2
Compile the fakeuname.c program into a dynamic libfakeuname.so library, as instructed in the .c file itself:
gcc -o fakeuname.o -c -fPIC -Wall fakeuname.c
gcc -o libfakeuname.so -shared -W1,export-dynamic fakeuname.o -ldl
Step 3
Prepare the environment a bit, before launching your command that takes into account the MAC address, like this:
export LD_PRELOAD=/tmp/libfakeuname.so
export FAKEMACADDR=AA:BB:CC:DD:EE:FF
Step 4
Launch your command and you'll see that magically it takes the new MAC address from the FAKEMACADDR environment variable.
Step 5
Make the exports of the above variable part of your bashrc, profile,... whatever init script you use for launching your server (automatically or manually). Maybe even the /etc/rc.local is now very good to be used for this.