The FreeBSD Diary

The FreeBSD Diary (TM)

Providing practical examples since 1998

If you buy from Amazon USA, please support us by using this link.
[ HOME | TOPICS | INDEX | WEB RESOURCES | BOOKS | CONTRIBUTE | SEARCH | FEEDBACK | FAQ | FORUMS ]
Managing an IP address change 3 September 2002
Need more help on this topic? Click here
This article has 4 comments
Show me similar articles

Have you ever changed the IP address of your computer? For those of you with a dynamic IP address, such changes are transparent. You don't see it. Hopefully that's what will happen when we change the IP address of the server which hosts this website. It should just happen and nobody will notice.

If you're just interested in setting the IP address of your FreeBSD computer, then this article is way too much information. Just read the next section and it will show you. Please ignore the rest of the article as it is beyond the scope of what you are trying to do.

In this article, I will use 192.168.0.56 as the original IP address and 192.168.0.57 as the new IP address. In reality, the change is from a.b.c.56 to x.y.z.56 (i.e. all but the last octet will change).

Here is a brief outline of the plan we are going to use. Please think carefully about your own situation but this list will be helpful. In short, we will make the server respond to both the new and the old IP address, then change the DNS, and let it propagate before we remove the old IP address. This should minimize any down time for users of the system.

  1. /etc/rc.conf - add a new IP address to the NIC
  2. /etc/ipf.rules - modify the firewall rules
  3. /usr/local/etc/apache/httpd.conf - alter the virtual hosts
  4. test
  5. /etc/namedb/*.db - update the DNS
  6. let things propagate
  7. remove references to the old IP address
Adding an IP address to a NIC

A NIC (Network Interface Card) can handle more than one IP address. ifconfig (8) manages IP addresses. We will use that command to manually add an alias, but we will set a hook in /etc/rc.conf to add it at boot time.

You probably already know how to assign an IP address to a NIC at boot time. That can be done by adding this line to /etc/rc.conf:

ifconfig_rl0="inet 192.168.0.56 netmask 255.255.255.0"

This assigns an IP address of 192.168.0.56 to rl0. The netmask will be 255.255.255.0. You can issue this command manually:

ifconfig rl0 inet 192.168.0.56 netmask 255.255.255.0
Adding the alias to the NIC

The next step is to add an additional IP address. This is done with the alias parameter. Here is the line added to /etc/rc.conf:

ifconfig_rl0_alias0="192.168.0.57 netmask 0xffffffff"
NOTE: that the netmask shown is what you should use. Don't use the same netmask as the main IP address. Please read this extract from ifconfig (8)
  alias  Establish an additional network address for this interface. This
         is sometimes useful when changing network numbers, and one wishes
         to accept packets addressed to the old interface.If the address
         is on the same subnet as the first network address for this
         interface, a non-conflicting netmask must be given. Usually
         0xffffffff is most appropriate.
The manual equivalent of this /etc/rc.conf entry is:
ifconfig rl0 alias 192.168.0.57 netmask 0xffffffff

After doing that, here is what my NIC looked like:

$ ifconfig rl0
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet 192.168.0.56 netmask 0xffffff00 broadcast 192.168.0.255
        inet6 fe80::250:fcff:fe50:5688%rl0 prefixlen 64 scopeid 0x1
        inet 192.168.0.57 netmask 0xffffffff broadcast 192.168.0.57
        ether 00:50:fc:50:56:88
        media: Ethernet autoselect (100baseTX <full-duplex>)
Firewall rules

I use ipf which is in the base system for FreeBSD. It's a great firewall tool, my packet filter of choice, and is what I recommend to others.

You may have to modify your firewall rules to cater for the additional IP address. You will have to decide for yourself.

For my firewall rules, I searched for rules which referred to the old IP address, then duplicated those rules for the new IP address. After making those changes, I implemented the rules using this command:

ipf -s -Fa -f /etc/ipf.rules && sleep 10 && ipf -s
After issuing the command, I typed a few characters, noticed that they echo'd to the screen, then pressed control-C. I had 10 seconds to do this, during the sleep command. See man 8 ipf for more detail. I then tested the various services to make sure I could contact them on the new IP address. I did simple tests such as telnet 192.168.0.56 25 to ensure I could get to my mail server.
Apache virtual hosts

This web server uses virtual hosts. That allows multiple websites to share the same web server and IP address. I will modify the configuration to respond to multiple IP addresses. Luckily, that appears to be quite simple to do.

I am using name-based virtual hosts. There are also IP-based hosts. A very good explanation appears within the Apache documentation.  For more detail, please refer to that document.

NOTE: Although I am adding an IP address below, there is an easier way. Thanks to James A. Peltier for pointing this out.

My first place to look was /usr/local/etc/apache/httpd.conf. I found all references to the old IP address, and added references to the new IP address. For example, I found this old line:

<VirtualHost 192.168.0.56>
Which became:
<VirtualHost 192.168.0.56 192.168.0.57>

I did this for all other VirtualHost entries.

As mentioned above, there is an easier way. Instead of declaring your virtual hosts with a predefined IP address, you can use * instead. For example, I started out with this:

<VirtualHost 192.168.0.56>
But I could use this instead::
<VirtualHost *>

Similarly, you can use * in the NameVirtualHost declaration instead of an IP address:

NameVirtualHost *
Apache virtual hosts - testing the changes

It was then time to test what I'd done:

# /usr/local/sbin/apachectl configtest
[Tue Sep 3 10:30:21 2002] [warn] VirtualHost 192.168.0.57:80 overlaps with VirtualHost 192.168.0.57:80, the first has precedence, perhaps you need a NameVirtualHost directive

DOH! I knew about that. I just forgot it. You have to explicitly declare each IP address in an NameVirtualHost directive. Here is what I now have:

NameVirtualHost 192.168.0.56
NameVirtualHost 192.168.0.57

Of course, if I'd been using *, this problem would not have occurred.

Another quick retest of the configuration:

# /usr/local/sbin/apachectl configtest
Syntax OK

Then Apache was restarted:

# /usr/local/sbin/apachectl graceful
/usr/local/sbin/apachectl graceful: httpd gracefully restarted
HOT TIP: use NetSaint for testing!

NetSaint is a great tool. But it wasn't until I was almost finished writing this article that I realised I could use it for testing my changes. I added a new host to the configuration file, gave it a new name, and used all the same values from the existing host, but I changed the IP address.

Of course, this tip isn't much use unless you already have NetSaint installed and running...

Testing the http changes

Now that I have the server configured with the new IP address, it needs to be tested. I'm going to do this with my local DNS server. I will change that server to refer to the new IP addresses and get one of my test workstations to use it. This will allow me to confirm that the server is answering on the new IP address. If you don't want to test this using DNS, you could also do this with just /etc/hosts.

After making the local DNS changes, I was ready to test. To ensure that I was seeing traffic on the new IP address I used tcpdump to verify:

# tcpdump -i rl0 host 192.168.0.57

When I first browsed to this new IP address, I didn't see the website I expected. Instead, I saw my default website. That's what you'll see if you browse to the IP address associated with www.freebsddiary.org instead of browsing by hostname. The use of virtual hosts involves the HTTP\1.1 protocol passing the host name within the headers of the request. If this host name is not present or is unknown, the default website would be displayed.

The problem was I had forgotten to modify the VirtualHost entry for the website in question. Once I did that, browsing worked as expected.

Testing the SMTP changes

Along with changes to the IP addresses of various websites, mail is also affected. This server handles mail for many domains. To test that the SMTP server is responding to the new IP address, I added another entry to the /etc/hosts file which set the new IP address of the mail server. Then I sent myself a message to a domain for which the MX record used that mail server. Checking /var/log/maillog on both the server and the client, I found that the client had contacted the new IP address and that the server had received the message.

Changing the DNS server (for real this time)

I'm happy with the results of the testing. So now it's time to make the changes to the production DNS server. The goal is not to change the IP address, but to give each host two IP addresses. This will have the effect of splitting the traffic between the old and new IP addreses. If there is a problem with the new IP address (i.e. I forgot something during the setup), clients out there will hopefully retry another time with the new IP address. Or that's the theory....

So here are the two A records for my main mail server:

m20    IN  A       192.168.0.56
m20    IN  A       192.168.0.57

After making changes to the DNS, I started monitoring the new IP address using tcpdump to ensure traffic was slowing increasing. So far so good. I'll update this article as new issues come to light.

Other things to remember

Here are a few things to remember when you do this.

  • If you filter things by IP address, remember to change other firewalls under your control to allow access from the new location.
  • If you are using NetSaint then remember to update that too. In fact, I think that's an easy way to check that everything is running. Add the host to NetSaint under the new IP address.
  • With https, be sure to specify the right IP adresss in the right place. If you are using a name in the VirtualHost declaration, that might be a little difficult. I swapped from a name to an IP address.
    <VirtualHost www.freebsddiary.org:443>
    became
    <VirtualHost 129.168.0.57:443>
Other things to consider 15 September 2002

You may want to update these files with your new IP address:

  • /etc/hosts
  • /etc/hosts.allow
  • /usr/local/etc/smb.conf
It might also be wise to run a grep on /etc/ looking for your old IP address.
I'm not finished yet 15 September 2002

You will notice that I've not completed this article. That's because I've been waiting for the DNS to propogate. Then I'll remove the old IP address. Then I will update the article.

Part 2 3 October 2002

Part 2 of this article is now available.


Need more help on this topic? Click here
This article has 4 comments
Show me similar articles