How To: Make Sure /etc/resolv.conf Never Get Updated By DHCP Client

by on September 8, 2008 · 32 comments· LAST UPDATED April 22, 2014

in , ,

I'm using GNU/Linux with the Internet Systems Consortium DHCP Client. The dhclient, provides a means for configuring one or more network interfaces using the Dynamic Host Configuration Protocol. It also updates my /etc/resolv.conf file each time my laptop connects to different network. I would like to keep my existing nameservers. How do I skip /etc/resolv.conf update on a Linux based system?

Tutorial details
DifficultyIntermediate (rss)
Root privilegesYes
RequirementsISC DHCP client
Estimated completion time5m
The DHCP protocol allows a host to contact a central server which maintains a list of IP addresses which may be assigned on one or more subnets. This protocol reduces system administration workload, allowing devices to be added to the network with little or no manual configuration. There are various method to fix this issue. Use any one of the following method.

WARNING! Many firewalls only allow access to certain nameservers only. So make sure your nameservers are supported. Also, many corporates block snooping name server such as OpenDNS due to privacy issues.

Option # 1: Write protecting /etc/resolv.conf file

Write protect your /etc/resolv.conf file using the chattr command on a Linux bases system. The syntax is:
# chattr +i /etc/resolv.conf
The +i option (attribute) write protects /etc/resolv.conf file on Linux so that no one can modify it including root user. You can use chflags command on FreeBSD based system.

Option #2: dhclient-script hooks

The DHCP client network configuration script is invoked from time to time by dhclient. This script is used by the dhcp client to set each interface's initial configuration prior to requesting an address, to test the address once it has been offered, and to set the interface's final configuration once a lease has been acquired.

This script is not meant to be customized by the end user. If local customizations are needed, they should be possible using the enter and exit hooks provided. These hooks will allow the user to override the default behavior of the client in creating a /etc/resolv.conf file.

When it starts, the client script first defines a shell function, make_resolv_conf, which is later used to create the /etc/resolv.conf file. To override the default behavior, redefine this function in the enter hook script.

Create hook to avoid /etc/resolv.conf file update

You need to create /etc/dhcp3/dhclient-enter-hooks.d/nodnsupdate file under Debian / Ubuntu Linux:
# vi /etc/dhcp3/dhclient-enter-hooks.d/nodnsupdate
Append following code:

#!/bin/sh
make_resolv_conf(){
	:
}

Save and close the file. Set permissions:
# chmod +x /etc/dhcp3/dhclient-enter-hooks.d/nodnsupdate
Above script will replace make_resolv_conf() with our own function. This functions does nothing.

A note about resolvconf program on a Debian or Ubuntu based system

If the resolvconf program is installed, you should not edit the resolv.conf configuration file manually on Debian or Ubuntu based system as it will be dynamically changed by programs in the system. If you need to manually define the nameservers (as with a static interface), add a line something like the following to the interfaces configuration file at /etc/network/interfaces file:

##Place the line indented within an iface stanza, e.g., right after the gateway line.##
dns-nameservers 8.8.8.8 127.0.0.1

A note about RHEL / CentOS / Fedora Linux

Place following code in /etc/dhclient-enter-hooks file:
# vi /etc/dhclient-enter-hooks
Append code:

make_resolv_conf(){
	:
}

Save and close the file. Another option is to modify your interface configuration file such as /etc/sysconfig/network-scripts/ifcfg-eth0 file and append any one of the following option:

# do not overwrite /etc/resolv.conf ##
PEERDNS=no

OR

## use the following nameservers in /etc/resolv.conf ##
PEERDNS=no
DNS1=8.8.8.8
DNS2=1.2.3.4

Save and close the file. Where,

  1. PEERDNS=yes|no - Modify /etc/resolv.conf if peer uses msdns extension (PPP only) or DNS{1,2} are set, or if using dhclient. default to "yes".
  2. DNS{1,2}=<ip address> - Provide DNS addresses that are dropped into the resolv.conf file if PEERDNS is not set to "no".

Option # 3: Configure dhclient.conf

/etc/dhclient.conf or /etc/dhcp/dhclient.conf file contains configuration information for dhclient. You can turn on or off DNS update and other options for specific interface or all interface using this file. The man pages for DHCLIENT.CONF and DHCP-OPTIONS point out that in dhclient.conf, you should add this:

supersede domain-name-servers 202.54.1.2, 199.2.3.4;

OR

prepend domain-name-servers 1.2.3.4, 1.2.3.5;

Here is a sample config for you:

       timeout 60;
       retry 60;
       reboot 10;
       select-timeout 5;
       initial-interval 2;
       reject 192.33.137.209;
       interface "eth0" {
           send host-name "laptop-area51.nixcraft.net.in.home";
           send dhcp-client-identifier 00:30:48:33:BC:32;
           send dhcp-lease-time 3600;
           supersede domain-search "net.in.home", "cyberciti.biz", "vpx.nixcraft.net.in";
           prepend domain-name-servers 8.8.8.8, 127.0.0.1;
           request subnet-mask, broadcast-address, time-offset, routers,
                domain-search, domain-name, domain-name-servers, host-name;
           require subnet-mask, domain-name-servers;
       }
Further readings:
TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 32 comments… read them below or add one }

1 matias September 9, 2008 at 5:14 am

in Debian & *ubuntus resolv.conf is handled by a package called resolvconf. You should modify resolv.conf through it.

Reply

2 Lacey September 10, 2008 at 2:04 am

resolvconf will append whatever’s in your resolvconf files (head, base, tail), but I haven’t figured out a way to stop it from including the DHCP stuff as well, which I don’t want. I will try write-protecting /etc/resolv.conf to see if that works.

Reply

3 James September 12, 2008 at 3:02 am

Note: You are making a big assumption, that being that the user is using ext3. Yes RH and derivatives force this on you. Other linux distro’s recognize the other files systems where chattr is not going to be available.

Take a look at the man page for dhclient.conf (used by dhclient3 btw)

********snip*********

The supersede statement

supersede [ option declaration ] ;

If for some option the client should always use a locally-configured value or values rather than
whatever is supplied by the server, these values can be defined in the supersede statement.

*******end snip ***********

Reply

4 nixCraft September 12, 2008 at 4:19 am

James,

Thanks for your feedback. The faq has been updated.

Reply

5 eli September 21, 2009 at 8:40 pm

Thanks so much for this. It’s been driving me crazy trying to keep resolv.conf from being changed.

Reply

6 yannis t December 20, 2009 at 2:26 am

if you want local values to supersede server values add in /etc/dhclient3/dhclient3.conf
supersede domain-name “google.com”

Reply

7 korhan February 16, 2010 at 1:07 am

At least on the BSD variants, the problem occurs when /sbin/dhclient-script is called by /sbin/dhclient. You could conceivably edit this script to ensure that /etc/resolv.conf does not get overwritten, but I find using the supersede directive works well enough. You would edit /etc/dhclient.conf as follows:

supersede host-name “myhost”;
supersede domain-name “my.domain”;
supersede domain-name-servers 127.0.0.1,192.168.1.1,192.168.1.2;

Which will give generate the following /etc/resolv.conf for you every time:

search mydomain
nameserver 127.0.0.1
nameserver 192.168.1.1
nameserver 192.168.1.2

There really should be a more obvious way to stop this often unwanted behavior.

Thanks for the information – you helped solve this irritating little problem for me.

Reply

8 ozgur March 11, 2010 at 6:27 pm

My OS is kubuntu 9.10 x64. I have followed the procedure described in the 2nd Option, but it didn’t work.. resolv.conf is still being set to its original state everytime I reboot my system. Any of you can help me about it?

Reply

9 Kanda November 19, 2011 at 5:18 pm

when you run dhclient eth0 chek which file is the correct configuration file

/etc/dhclient.conf
/etc/dhcp3/dhclient.conf

put supersede command in the correct configuration file

Reply

10 nixCraft March 11, 2010 at 6:55 pm

Follow option # 3, this should fix it.

Reply

11 ozgur March 15, 2010 at 7:27 pm

Thanks for the help, that did not fix the problem but then I tried using supersede command instead of option, and now it works

Reply

12 Peter April 1, 2010 at 3:28 pm

For RHEL/CentOS the right way to solve this problem is to update /etc/sysconfig/network-scripts/ifcfg-eth0 or whatever interface you have, with:
PEERDNS=no
PEERNTP=no # if you have also problem with overwritten /etc/ntp.conf

check documentation at /usr/share/doc/initscripts-*/sysconfig.txt
or see whats inside script causing all this /sbin/dhclient-script , search for PEER

Reply

13 lifeofguenter December 1, 2010 at 3:05 pm

In Debian Lenny (5.0) you should do this:

# nano /etc/default/dhcpcd
(…)
# Uncomment this to allow dhcpcd to set the DNS servers in /etc/resolv.conf
# If you are using resolvconf then you can leave this commented out.
SET_DNS=’no’

# Uncomment this to allow dhcpcd to set hostname of the host to the
# hostname option supplied by DHCP server.
SET_HOSTNAME=’no’
(…)

Reply

14 Ron January 30, 2011 at 11:40 am

Hi all,
When i use a vpn to my work i want the dns servers from my work to be used for queries to the local domain.

Is there a way to point the client to a specific dns server for domain
“mywork.local” ? When i connect the vpn resolv.conf does not get rewritten with the mywork dns servers…

I use ubuntu 10.10 desktop edition

Reply

15 Michael V. Antosha March 14, 2011 at 1:45 pm

Option # 3 needs correction I think.

In my case there was not dhclient.conf file and I created an empty one with the line you proposed:
option domain-name-servers a.b.c.d

Nothing changed in behaviour and there was an error in logs when dhclient started:
…dhclient: /etc/dhclient.conf line 2: expecting “code” keyword.

Finally this worked for me (choose one of those):
supersede domain-name-servers 8.8.8.8;
or
prepend domain-name-servers a.b.c.d;

‘prepend’ does not replace DNS servers obtained by DHCP, but this makes your name server to be the first one in resolv.conf
‘supersede’ totally replaces the option with your variant.

I hope this will help someone.

Michael.

Reply

16 Martin July 21, 2011 at 4:53 am

The stub resolver (built into libc) can’t handle different directions for multiple domains, but you could always point it at a localhost resolver that does.

For that you will need to learn about BIND or LWres or Unbound or some other DNS server, none of which is within the scope of this question.

Having done that you’ll need to be a bit careful what you put in the “search” path; if you put VPN-only zones in it then there may be delays when you don’t have the VPN connected — not to mention, numerous entries in /var/log/named (or syslog) complaining about the unreachability of the DNS server at the other end of the VPN.

Reply

17 Fernando January 31, 2012 at 5:24 am

Thanks a lot, on slackware 13.37 only the write protection solves the problem.

Reply

18 Nikolay March 14, 2012 at 7:29 am

very helpful !
I usually like to run my own dns on localhost, but from some time I am using DHCP for the IP because I am on Wireless.

Reply

19 William March 15, 2012 at 5:52 pm

Option 3:
option domain-name-servers 202.54.1.2, 199.2.3.4, 124.1.5.22

Is broken (for me). Instead as Michael V. Antosha stated use

supersede domain-name-servers 8.8.8.8, 8.8.4.4;
or
prepend domain-name-servers a.b.c.d;

Then issue a “sudo dhclient wlan0″ from the command prompt. If you don’t know what the name if your interface is try “sudo ifconfig -a”

Reply

20 Ashish Jaiswal March 29, 2012 at 7:30 pm

That is what I was looking for..

Basically we have to let know the dhclient what are nameserver and domain-name ..
I have added like this

supersede host-name “server”;
supersede domain-name “ashish.com”;
prepend domain-name-servers 192.168.122.1;

And have removed domain-name and hostname from request line also.. so dhclient doesn’t have to look for this two parameter.. only just name-server

which give me output of resolve.conf like this

ashish@server:~$ cat /etc/resolv.conf
# Generated by NetworkManager
domain ashish.com
search ashish.com
nameserver 192.168.122.1
nameserver 192.168.5.206

Reply

21 Dan May 16, 2012 at 9:00 am

chattr +i /etc/resolv.conf

And of course this has many great uses.

Reply

22 Christian Bolliger June 23, 2012 at 7:45 am

On RHEL:
The hook script doesn’t replace make_resolv_conf() it will just run additionally. As mentioned before PEERDNS=no is the official solution.
Of course you can use the hook script to rechange your resolv.conf to the values you need.

Reply

23 pouya September 21, 2012 at 8:38 am

EDIT /etc/sysconfig/network-scripts/ifcfg-eth0

ADD PREDNS=no

Reply

24 rohit December 4, 2012 at 7:23 am

In the similar way can i make my dhclient to receive IP on virtual interface also ie on eth0 and eth0:1 ? i tried it with using different client-identifier for each virtual interface and dhcp server also seems to assign them different IP but somehow only the IP offered last is configured on interface and no ip is configured on virtual interface..

Reply

25 LV March 30, 2013 at 7:21 pm

In RHEL/CentOS, you can simply add option: PEERDNS=”no” to your network interface script (/etc/sysconfig/network-scripts/ifcfg-ethX).

Reply

26 simon September 4, 2013 at 5:32 am

under ubuntu 12.04

cat < /etc/network/if-up.d/remove_dhcp_dns.sh
if [ "${METHOD}" != "dhcp" ]; then
return 0;
fi
if [ -f /var/run/resolvconf/interface/${LOGICAL}.dhclient ]; then
resolvconf -d ${LOGICAL}.dhclient
fi
EOF

and in /etc/network/interfaces run the script as a post-up for dhcp interfaces

auto eth0
iface eth0 inet dhcp
pre-up sleep 2
post-up /etc/network/if-up.d/remove_dhcp_dns.sh

Reply

27 simon September 4, 2013 at 5:33 am

the cat line should be:

cat < /etc/network/if-up.d/remove_dhcp_dns.sh

Reply

28 simon September 4, 2013 at 5:35 am

hm. the post is getting mangled … i’ll try html. the cat line once more

cat <<’EOF’ > /etc/network/if-up.d/remove_dhcp_dns.sh

Reply

29 Antonio November 9, 2013 at 2:04 pm
30 Robert January 3, 2014 at 8:54 am

Hello~
I had try all kind of 3 way you said, but I can’t resolve it.
whenever OS connect network it change /etc/resolv.conf file.

most above line is changed like this…
“; generated by /sbin/dhclient-script”

and nameserver ip was changed.

Help…

Reply

31 Vorms June 6, 2014 at 6:22 pm

Hello,
I add a file /etc/dhcp3/dhclient-enter-hooks.d/nodnsupdate with a empty make_resolv_conf() but these function doesn’t repalce the original function.
I don’t undertand why ?

Many thanks for your help,
Best regards.

Thierry

Reply

32 someguy August 7, 2014 at 6:00 pm

Thanks very much for this.

I’ve gone with the “redefine make_resolv_conf” approach in CentOS 6.5 and it works a treat!

Reply

Leave a Comment

Tagged as: , , , , , , , , , ,

Previous Faq:

Next Faq: