Ubuntu Changing Network Device ID udev/rules.d

I do quite a bit of work with Virtual machines based on an ESX platform. One of the advantages of such a platform is the ability to create a template server, then duplicate copies as and when you need one. With most operating systems it’s just a question of changing the IP and hostname and you are in business.

In the case of Ubuntu Linux a udev rule is created for each network interface and which is bound to the MAC address of the card. Which makes loads of sense in the “Real World” but when you create a new VM an additional MAC address is generated. This can be a little frustrating as the first machine would have an eth0 the second an eth1 the third and eth2 and so on.

The database which stores these values is located in a file :

/etc/udev/rules.d/70-persistent-net.rules

An example of one of mine – on a third install.

# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.
#
# PCI device 0x8086:0x100f (e1000)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:c9:f4:13", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"
#
# PCI device 0x8086:0x100f (e1000)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:c9:f3:19", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
#
# PCI device 0x8086:0x100f (e1000)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:38:fd:fa", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"

In this case whilst I would prefer the device to be known as eth0 it is in fact known as eth2.

# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.
#
# PCI device 0x8086:0x100f (e1000)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:38:fd:fa", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

If the file is amended to the following and a reboot done all is sorted.
Don’t forget to amend the network configuration to reflect the change of device ID. In the case of UBUNTU this would be /etc/network/interfaces.

Ubuntu 9.04 installation on ESX

Firstly grab a copy of the 64bit Ubuntu server ISO from the ubuntu website and store is somewhere you can get to from your ESX box. Over the years I have taken the approach of storing server VMDK’s on ESX’s local hard disk pushing installation media onto a NAS.

(Note: Earlier this year we went gigabit ethernet on the NAS LAN so plans are there to potentially store VM’s a NAS too).

Install the virtual machine as you would do normally. I selected 64bit Ubuntu – I’m finding that telling ESX the O/S is a 64bit version regardless of whether you actually install the 64bit version or not seems to make the virtual machine more stable.

Edit the VM and set the boot media to be the Ubuntu ISO you downloaded ealier and mark it as connected and connected on boot.

Run the installation as you would do on normal hardware.

Now it’s time to install VMWare tools.

From the VMWare menu select Install/Upgrade VMWare Tools.

Mount the media and extract the installation files into /tmp

mount /cdrom
cd /tmp
tar zxf /media/cdrom/VMwareTools*.tar.gz

As part of the installation some compiling needs to be done so we’ll need to put some source libraries on unless they’re already there.

sudo apt-get install build-essential linux-headers-`uname -r`

The config.h file whilst needed is not created by default so an empty one is created so the build will complete.

sudo touch /usr/src/linux-headers-`uname -r`/include/linux/config.h

(Thanks https://help.ubuntu.com/community/VMware for the tip on this).

cd vmware-distribution
sudo ./vmware-install.pl

Follow the prompts for the installation – shared folders fails to build but in the ESX environment they’re not essential.

Reboot the box and you are in buisiness.

Using sftp on a non-standard port

Just a quick note about sftp.

It makes good security sense to change the ssh port on servers that are Internet accessable. To take advantage of this using ssh is quite straight forward as their is a parameter -p to support this eg:

ssh -p 3432 mick@mickvaites.com

Unfortunately the same is not true for sftp (secure file transfer). To achieve the same result with sftp we need to use specify an option of “Port 3432” eg:

sftp -o "Port 3432" mick@mickvaites.com

Once done log it as you would normally.

SSH Escape commands

Note to self:

These are the ssh escape commands from within an ssh connected session.

%~?
Supported escape sequences:
 ~.  - terminate connection (and any multiplexed sessions)
 ~B  - send a BREAK to the remote system
 ~C  - open a command line
 ~R  - Request rekey (SSH protocol 2 only)
 ~^Z - suspend ssh
 ~#  - list forwarded connections
 ~&  - background ssh (when waiting for connections to terminate)
 ~?  - this message
 ~~  - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)

The ~ (tilda) is normally accessed by keying [shift] + [`]

To pull up the list as above send a Tilda + Question Mark ~?

Ubuntu 9.04 installed on my laptop

Just some notes in respect of installing Ubuntu 9.04 on the Laptop Fujitsu Amilo Pro. In particular getting the wireless card to work.

The problem is that the wireless button doesn’t do anything so whilst the hardware is detected it cannot be brought up.

The solution is in two parts.

1. Get the OS to load the fsam7400 driver and pass a parameter radio=1

sudo echo fsam7400 >> /etc/modules
sudo echo options fsam7400 radio=1 >> /etc/modprobe.d/options

2. To survive hibernate/resume

modprobe -r ipw2200
modprobe -r fsam7400

to /etc/acpi/sleep.sh and /etc/acpi/hibernate.sh and

modprobe fsam7400 radio=1
modprobe ipw2200 led=1

to /etc/acpi/resume.sh

A big thanks to cartes and ph1721 for their postings on http://ubuntuforums.org

Load Balancing with Linux

Disaster had struck when both of the Arrowpoint Content Switches died with power supply faults. We needed to move them in the racks, they powered off but they didn’t power back on.

I looked at off the shelf solutions and was forced to rethink when I discovered that they come in with a price tag of between £2000 and £9000 each device. Whilst visiting on a good friend and colleague Scott the subject load balancers came up. His advise was to check out the Linux Virtual Server Project and in particular to look at ipvsadm.

We were looking for a simple solution to load balance both secure and non-secure web servers. After hunting around the internet I came across Keepalived and I am impressed to say that with a small amount of iptables it pretty much just works out of the box.

lbnetwork

The solution consists of two load balancers  lb1 and lb2 sitting between the Internet and the web server farm. VRRP is the redundancy protocol used to allow multiple boxes to work together.

The Internet facing IP addresses are managed by keepalived and associated with vrrp 1. An IP address is allocated as the default gateway for the web server farm and this is associated with vrrp 2. Keepalived ensures that only the active lb has these ip addresses active.

We run VMWare ESX Servers which aids fast deloyment of new services. It’s also quite useful as you can create the build you want the copy it as many times as you need … I digress.

From the list of Linux Distro’s I chose Ubuntu 8.10 Server as it was one I had to hand.  Once installed the packages were patched using apt-get and then keepalived was installed

apt-get install keepalived

This creates a folder /etc/keepalived which contains the control file keepalived.conf an document example as follows.

global_defs {
	notification_email {
		mick@mydomain.com
	}
	notification_email_from keepalived@mydomain.com
	smtp_server localhost
	smtp_connect_timeout 30
# name associated with this load balancer LVS_BACKUP is my backup
	router_id LVS_MASTER
}

vrrp_sync_group VG1 {
	group {
		VI_PUBLIC
		VI_GATEWAY
	}
}

vrrp_instance VI_PUBLIC {
# this denotes the default state - the backup is state BACKUP
	state MASTER
# interface connected to the public lan
	interface eth0
# vrrp 1
	virtual_router_id 1
	lvs_sync_daemon_interface eth0
# sets who is primary and backup (backup priority is 150)
	priority 200
	authentication {
		auth_type PASS
		auth_pass xxx
	}
	virtual_ipaddress {
# the public ip address associated with the web farm
		200.200.200.200/24
	}
}

vrrp_instance VI_GATEWAY {
# this denotes the default state - the backup is state BACKUP
	state MASTER
# interface connected to the web farm lan
	interface eth1
	lvs_sync_daemon_interface eth2
# vrrp 2
	virtual_router_id 2
# sets who is primary and backup (backup priority is 150)
	priority 200
	advert_int 1
	smtp_alert
	authentication {
		auth_type PASS
		auth_pass ThisPassword
	}
	virtual_ipaddress {
# the default gateway for the web farm
		192.168.1.1/24
	}
}
# public ip address associated with the webserver
virtual_server 200.200.200.200 80 {
# HTTP 1.1 hostname
	virtualhost www.mydomain.com
	delay_loop 30
	lb_algo wlc
# we are NAT'ing the addresses
	lb_kind NAT
	nat_mask 255.255.255.0
	persistence_timeout 50
	protocol TCP
# ip address of real web server 1 from farm
	real_server 192.168.1.100 80 {
		weight 1
		HTTP_GET {
			url {
# look for a small image that you know will always exist
				path /icons/unknown.gif
# if web server okay you will get a status code 200
				status_code 200
			}
# you'll need to tinker around with these to get them just right
			connect_timeout 20
			nb_get_retry 10
			delay_before_retry 30
# web server runs of port 80
			connect_port 80
		}
	}
# ip address of real web server 2 from farm
	real_server 192.168.1.101 80 {
		weight 1
		HTTP_GET {
			url {
				path /icons/unknown.gif
				status_code 200
			}
			connect_timeout 20
			nb_get_retry 10
			delay_before_retry 30
			connect_port 80
		}
	}
}

Because the load balancers will be the default gateways for the web server farm. We need to configure iptables nat masqurade so that if the web server needs to talk to the internet it will have a public IP address. The following very basic /etc/iptables.rules is used to nat the replies.

:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [4980:5513190]
:OUTPUT ACCEPT [3522:318353]
-A INPUT -i l0 -j ACCEPT
-A INPUT -i eth0 -j ACCEPT
-A INPUT -i eth1 -j ACCEPT
-A FORWARD -i eth1 -j ACCEPT
COMMIT
*nat
:PREROUTING ACCEPT [4036:3275594]
:POSTROUTING ACCEPT [118:7080]
:OUTPUT ACCEPT [142:8825]

-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT

To bind this in to ubunu a script load_tables containing

#!/bin/sh
iptables-restore < /etc/iptables.rules

Is placed in/etc/network/if-pre-up.d and then it will be called on boot.