IP Aliasing on FreeBSD 2.2.x & 3.0
By Ben Black
IP aliasing is the process of adding more than one IP address to a network interface. Typical uses of IP aliasing are virtual hosting of Web and FTP servers and reorganizing servers without having to update any other machines (this last one is especially useful for nameservers). Think of an IP alias as a little kid piggy-backed on their parent interface (which is has the primary address of the physical interface).
IP aliasing is not concerned with the concept of multi-homing, (a multi-homed machine has more than one network interface active), except where a multi-homed machine provides services such as those listed above. The term multi-homing used to denote IP aliasing is a mistake propagated from the Mac world and you would be wise not to follow in their footsteps.
The two commands essential to creating an IP alias on FreeBSD (and all other Unix systems I've ever used) are ifconfig and route. Correct usage of these commands is described below. For all the exquisite details of using these commands, please refer to the man pages which are linked from the sections below. There are two more commands which are useful for verifying that things are working as they should and for debugging if they aren't. netstat allows you to view the kernel routing table (among many other useful things), and ping is a lovely little tool to test reachability of your new alias (or any IP address, for that matter).
ifconfig is used to configure all aspects of a network interface (address, protocol, netmask, etc.). Our concern with ifconfig here is adding (and sometimes deleting) address aliases for interfaces.
For the examples below we will assume our machine has a single 3Com 3C509 Ethernet interface (ep0) with the address 192.168.57.82 and a netmask of 255.255.255.0, in addition to the standard loopback interface (lo0) at 127.0.0.1. You will, of course, need to substitute your own address and netmask for your network interface(s). The address and netmask for the loopback interface are the same on every machine.
To add an alias to ep0, we simply execute a command such as:
You may also leave off the netmask option (or set it to something else). In FreeBSD 2.1.0 and earlier, however, there is a bug that causes ifconfig alias commands to return an error on the first try, but succeed on the second if you don't specify a netmask of 255.255.255.255. If you do not set the netmask to 255.255.255.255, you will also need to add a route by hand as described below.
To remove an alias, we execute the very similar command:
route is used to manually make changes to the kernel routing table. In our application, once we have told FreeBSD about the alias for the interface, we must specify an IP route to it. If you set the netmask to 255.255.255.255 in your ifconfig command above, you can skip this step.
To add a route to our new interface alias, we execute: route add -host 192.168.57.10 127.0.0.1 0 This tells FreeBSD that to get to single host 192.168.57.10, packets should be sent to the loopback address (127.0.0.1, also called localhost), and the metric (hop count) is 0, meaning it is on the local machine.
To delete this route, we execute: route delete -host 192.168.57.10 Again, since the route can be identified by the given parameters, we can leave off things such as the netmask and metric. See the man page for a full explanation of the route command.
Checking Your Work
Now that we (hopefully) have an alias defined and routable, we need to check that it is working properly. First we'll look at the kernel routing table to verify the route to the alias is in place, then we'll use ping to verify packets can actually reach the interface alias.
To look at the numeric version of the kernel routing table, execute: netstat -nr In our example, the output will look something like this: Routing tables Internet: Destination Gateway Flags Refs Use Netif Expire default 192.168.57.1 UGSc 4 964 ep0 127.0.0.1 127.0.0.1 UH 1 39 lo0 192.168.57 link#2 UC 0 0 192.168.57.10/32 link#2 UC 0 0 192.168.57.82 127.0.0.1 UGHS 0 0 lo0 224/4 link#2 UCS 0 0 Here we see the default route, the route to the loopback interface, the route to our local network, and a strange looking route to our alias. The /32 on the end of the aliased address indicates the length of the subnet mask (the number of 1's starting from the left of the netmask). Because I used a netmask of 255.255.255.255, the length of the subnet mask (the number of 1's) is 32.
Once you have established that the route is in the kernel routing table, just do a quick check to be sure routing actually works. Execute a ping like this: ping 192.168.57.10 If things are good, you will see something like this: PING 192.168.57.10 (192.168.57.10): 56 data bytes 64 bytes from 192.168.57.10: icmp_seq=0 ttl=255 time=0.313 ms 64 bytes from 192.168.57.10: icmp_seq=1 ttl=255 time=0.197 ms 64 bytes from 192.168.57.10: icmp_seq=2 ttl=255 time=0.190 ms Just press Ctrl-C to stop the ping if it seems happy. It will then spew some interesting statistics which you can generally just ignore. If none of the pings come back or if there are error messages, something is wrong. Try starting again from the beginning, reading the man pages (no, really, GO READ THE MAN PAGES), and finally, asking on the freebsd-questions list.
Putting it All Together
Now that we understand how to use ifconfig and route commands to add and delete IP aliases, let's make the machine execute the proper commands at startup so the alias will always be active.
Near the end of the file /etc/rc.local, you would add the lines: ifconfig ep0 inet 192.168.57.10 netmask 255.255.255.255 alias If you used a netmask other than 255.255.255.255, then you will also need to use the route command as described above. You can add as many aliases as you like this way (assuming you have enough addresses allocated to you). Simply put several copies of the above commands in /etc/rc.local with the appropriate addresses. You can even have addresses in another IP network aliased onto an interface if that network is also routed to you. This differs from the situation with multiple physical interfaces in a machine which must always have addresses in different IP networks.
There are a couple of issues when dealing with large numbers of aliases (more than ~10) that I'll mention here.
First, there is a bug in all distributions of bind (the named DNS server is part of BIND) that prevents named from starting properly when there are more than 64 aliases on an interface. None of the fixes are particularly simple, so I will skip them all for now.
Second, to prevent cluttering up your /etc/rc.local file with lots of ifconfigs, I suggest you use a seperate file in /etc to hold them. For instance, create a file called ifconfig.ep0 and put all your ifconfig alias commands in there. Then, in /etc/rc.local, add the following: if [ -x /sbin/ifconfig ]; then echo -n 'Adding local ifconfigs ' . /etc/ifconfig.ep0 echo ' done.' fi This script segment is from an rc.local file provided by Neil Fowler Wright. The particularly industrious can find ways to use a loop if there are multiple interfaces with aliases contained in multiple ifconfig.* files