Managing an IP address change
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.
/etc/rc.conf
– add a new IP address to the NIC/etc/ipf.rules
– modify the firewall rules/usr/local/etc/apache/httpd.conf
– alter the virtual hosts- test
/etc/namedb/*.db
– update the DNS- let things propagate
- 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.
Apache virtual hosts – an easier way
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 (added on 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 (added on 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 (added on 3 October 2002)
Part 2 of this article is now available.
Why wouldn’t you just use something like
NameVirtualHost *
<VirtualHost *>
ServerName http://www.site-fx.net
</VirtualHost>
for all your vhosts on the system instead. Unless of course they needed SSL which would require an IP Address be set. Or am I missing something?
James A. Peltier wrote:
>
> Why wouldn’t you just use something like
>
> NameVirtualHost *
Ignorance.
A good point. Thanks. For those going this route, if * is used instead of an IP address, you must modify all VirtualHost declarations.
I’ve also updated the article (<http://www.freebsddiary.org/ip-address-change.php>😉 to reflect this. I’ll also update the Virtual Hosts article (<http://www.freebsddiary.org/virtualhosts.php>).
Another neat apache trick is to use module vhost_alias_module
and then you can add new hosts on the fly (without changing config file or restarting apache)
Another directives needed if you go this way are:
VirtualDocumentRoot /home/vhosts/%0/
ScriptAlias /cgi-bin/ /home/cgi-bin/
Then as long as your DNS names point to the right (changed) IP address, you are good to go.
site1.com files go under /home/vhosts/site1.com
site2.com files go under /home/vhosts/site2.com
New sites get picked automatically.
HTH
Amit