Restoring /etc/resolv.conf after a modem/router burp

Chris Friedt Chfriedt-0jnyayh6ARPqzrOJbVgLALDks+cytr/Z at public.gmane.org
Mon Jun 13 13:54:52 UTC 2005


Hello Alex, 

I've just started reading your message, and I'm pretty confident that I
have a useful solution for your problem. <edit> well... actually, this
would only work for a linux router, so if you use a small embedded
router, forget it </edit>

When your DHCP client is refreshing its lease, although your ip address
stays the same, it updates your DNS records in /etc/resolv.conf .

As of yet, I haven't found any '--no-dns-update' option in any of the
documentation for DHCP clients, although I haven't really spent a lot of
time looking. 

Instead I wrote a script to update the DNS on my linux router. Since
I'm running a small name server for home use only (i.e. not listening on
the outside ports, a simple caching / forwarding bind job) every time
DHCP updated I was losing integrity within my network (I couldn't lookup
a computer by name). 

Some people may say that using a name server at home is somewhat
pointless, and I can agree to a certain extent... but then again I am a
bit lazy and prefer to type 'obiwan' instead of '192.168.1.101' ;-)

Anyway, below is a perl script which acts well as a daemon. Below that
is an init script which should ease some of your problems with only a
few modifications. One more thing... i'm just taking a wild stab at it,
but your router is probably something like a tiny linksys box, in which
case this won't work at all. But in the odd chance that it is a linux
box, this would solve all of the problems =).

Also, I wrote this script years ago when i was kindof a n00b, but it
works, so I don't really care how algorithmically correct it is, or if
it isn't the best way to use a call in the shell. So just in case there
are any comments about my garbage code, I don't really care.

=================================================
# /user/sbin/resolv


#!/usr/bin/perl
# resolvd v0.2 
# Aug. 7, 2004
# written by Christopher Friedt
# Electrical & Computer Engineering 
# Ryerson University
# Toronto, Canada
# chfriedt-0jnyayh6ARPqzrOJbVgLALDks+cytr/Z at public.gmane.org 

# The purpose of this script is to remove the effects of a dhcp client
update
# on /etc/resolv.conf. The reason for this is that if one is running a
local
# BIND resolving, caching nameserver on a private subnet, it
references
# /etc/resolv.conf upon local request. However, when a dhcpcd update
occurs, 
# /etc/resolv.conf is overwritten, replacing the 'search here.net' with

# the nameserver of the local server's ISP or gateway.

# for example
# this is the proper /etc/resolv.conf of a locally running nameserver,
which 
# is of course only accepting requests from the local interface, but
resolving
# names outside of the local network:

# #nameserver 192.168.1.100
# nameserver 24.153.22.195
# #nameserver 24.153.23.66
# search here.net
# #search bloor.phub.net.cable.rogers.com

# note that the 1st line is the ip address of the local network
interface
# and that the 4th line is the domain name associated with the local
subnet.

# this is what happens when dhcpcd's lease expires, and subsequently it

# rewrites /etc/resolv.conf, overriding local name resolution.

# nameserver 24.153.22.195
# nameserver 24.153.23.66
# search bloor.phub.net.cable.rogers.com

######

# in the future, it may be nice to have the dhcpcd developers offer an
option 
# to preserve the /etc/resolv.conf of the local nameserver at least
partially.
# There are two options: insert the local nameserver's info while
refreshing
# the dhcpcd lease, or to insert the remote nameserver's info giving
precedence 
# to the local nameserver. Both would be trivial to implement. 

######

$minute=60;
#$hour=60*$minute;
$sleeptime=3*$minute;

$file="/etc/resolv.conf";
$log="/var/log/resolv.log";
$print_targ=$log; # or STDERR

$nameserverip="192.168.1.100";
$localdomain="perpetual-notion.myftp.org";
$ns_counter=0;
$s_counter=0;


while (1) {
    open ( LOG, $log );
    print LOG `date`;
    `more $file | grep "$nameserverip" 1> /dev/null`;
    $result = $? >> 8;
    if ( $result == 0 ) {
	print "No need for updates, $file has not changed\n";
	sleep ( 10*$minute );
    } else {
	print LOG `date`;
	print LOG "$file has changed\n";
	open (RESOLV, $file);
	
	while (<RESOLV>) {
	    if ( /;/ ) {
		print LOG "found semicolon\n";
	    } elsif ( /(search[\s]+)(.*)[\s]*\n/ ) {
		print LOG "found name $2\n";
		push (@name, $2);
	    } elsif (
/nameserver[\s]+([0-9]+.[0-9]+.[0-9]+.[0-9]+)[\s]*\n/ ) {
		print LOG "found ip $1\n";
		push (@ip, $1);
	    } else {
		;
	    }
	}
	close (RESOLV);
#	exit(0);
#       @name = split(/ /, $name);
	
	print LOG "Backing up $file to $file.bak\n";
	`cp $file $file.bak`;
	if ( ($? >> 8) != 0 ) { 
	    die("Couldn't back up $file\n");
	}
	
	$ns_counter=0;
	$s_counter=0;	

	print LOG "Writing new $file\n";
	open (RESOLV, ">$file") or die ("Couldn't open $file for
rewriting\n");
	
	print RESOLV ";generated automatically by Chris
Friedt\n;Electrical & Computer Engineering\n;Ryerson
University\n;Toronto, Canada\n;chfriedt\@gwemail.ryerson.ca\n";
	print RESOLV "nameserver $nameserverip\n";
	$ns_counter++;

	foreach $a (@ip) {
	    if ( $a ne $nameserverip ) {
		if ( $ns_counter <= 1 ) {
 			print RESOLV "nameserver $a\n";
			$ns_counter++;
		} else {
			print RESOLV ";nameserver $a\n";
		}
	    }
	}

	print RESOLV "search $localdomain\n";
	$s_counter++;

	foreach $a (@name) {
	    if ( $a ne $localdomain  ) {
		if ( $s_counter < 1 ) {
			print RESOLV "search $a\n";
			$s_counter++;
		} else {
			print RESOLV ";search  $a\n";
		}	
	    }
	}
	print RESOLV "\n";

	close (RESOLV);
    }
    close (LOG);
}

===========================================================
# /etc/init.d/resolvd


#!/sbin/runscript
# . /etc/rc.d/init.d/functions  # uncomment/modify for your killproc

## Written by Christopher Friedt chfriedt-0jnyayh6ARPqzrOJbVgLALDks+cytr/Z at public.gmane.org (Mar. 16
2004)

. /etc/init.d/functions.sh

depend () {
    after sshd
    after net.eth0
    after net.eth1
}

usage() {
    echo "Usage: $0 {start|stop}"
    exit 1
}

start () {
    ebegin "Starting resolvd ..."
    #start-stop-daemon --start --make-pidfile --pidfile
"/var/run/resolvd" --exec "/usr/sbin/resolv"
    /usr/sbin/resolv > /var/log/resolvd 2>&1 &
    eend $?
}

stop () {
    ebegin "Shutting down resolvd ..."
    #start-stop-daemon --stop --pidfile "/var/run/resolvd"
    kill -9 `pidof -x resolv`
    #eend $?
    eend 0
}


>>> talexb-Re5JQEeQqe8AvxtiuMwx3w at public.gmane.org 6/12/05 5:46:46 pm >>>
Hi,

This will probably be as easy-peasy question for some of you, but
right now the answer is frustratingly beyond my reach.

I use OpenVPN to stay in touch with my employer's LAN, through
Sympatico's DSL service. I have nameserver statements at the top of my
/etc/resolv.conf file to let me use the Company's name servers to get
to the company servers that I need to, as well as a search statement
for the company domain. Below that are the standard Sympatico name
servers.

Every once in a while either the modem or the router (Netgear RP614)
goes burp and my /etc/resolv.conf gets overwritten with Sympatico's
two name servers. When that happens, I have to go back into
/etc/resolv.conf and add in the definitions to get name service
working with my employer's LAN again.

Now, OpenVPN comes up right away, so I could use just the IP
addresses, but name servers were invented for a reason -- so you
wouldn't have to remember if that server was 192.168.0.123 bu instead
was foo.bar.com.

So really my question boils down to:

What causes /etc/resolv.conf to be overwritten on a modem or router
burp, and how can I hook that to automagically fix it?

Thanks much.

Alex
--
The Toronto Linux Users Group.      Meetings: http://tlug.ss.org 
TLUG requests: Linux topics, No HTML, wrap text below 80 columns
How to UNSUBSCRIBE: http://tlug.ss.org/subscribe.shtml
--
The Toronto Linux Users Group.      Meetings: http://tlug.ss.org
TLUG requests: Linux topics, No HTML, wrap text below 80 columns
How to UNSUBSCRIBE: http://tlug.ss.org/subscribe.shtml





More information about the Legacy mailing list