|
/etc/resolv.conf managementIt's annoying having to manually edit files in /etc or have changes you want preserved blown away by the DHCP client, isn't it? Here's my quick hack and workaround set I use for my work LAN. Note, I won't go into very much detail at all. For more information on how the DHCP client and BIND works, please view the documentation. It covers the facts far more thoroughly than I can. I use Debian Linux (I refuse to call it GNU/Linux, as most of the stuff on my system are covered under a license other than the GPL) with the dhcp-client package. First, create a dhclient-enter-hooks file under /etc:
#!/bin/sh
make_resolv_conf()
{
echo -e "search $new_domain_name foo.example.com bar.example.com example.com\nnameserver 127.0.0.1" > /etc/resolv.conf
exec > /etc/bind/named.conf
cat /etc/bind/named.baseline
for i in {test.,eng.,}example.com ; do
echo "zone \"$i\" {
type forward;
forward only;
forwarders {"
for j in $new_domain_name_servers ; do
echo -e "\t\t$j;"
done
echo -e '\t};
};'
done
for i in {168.192,10}.in-addr.arpa ; do
echo "zone \"$i\" {
type forward;
forward only;
forwarders {"
for j in $new_domain_name_servers ; do
echo -e "\t\t$j;"
done
echo -e '\t};
};'
done
exec >/dev/null 2>&1
/etc/init.d/bind9 restart
}
Now for a simple explanation. The /etc/dhclient-enter-hooks file is used by dhclient to do automated configuration file modifications. You can override the make_resolv_conf() function in the file to have it generate an /etc/resolv.conf file that you want, instead of the default that the DHCP client creates. A side note, the first exec redirects the output of the commands so all text sent to file descriptor 1 (stdout) goes to the /etc/bind/named.conf instead. The second exec bitbuckets all output to stdout and stderr (fd 2) so the /etc/bind/named.conf doesn't get weird garbage at the end that will cause the daemon to abort with a parse error.
In that file, the $new_domain_name and $new_domain_name_servers variables are passed when the script is sourced. These can be used to create a custom resolv.conf file, as you see above. I prepend the new domain name to the list of domain names to search, and make sure my local name server is the only one listed. After all, there's not much point in having a caching name server that's not used. The new name servers given are added to the BIND configuration files, as explained below: My /etc/bind/named.baseline file:
options {
directory "/var/cache/bind";
// For firewalling purposes
query-source address * port 53;
listen-on { 127.0.0.1; 172.16.0.0/24; };
allow-query { 127.0.0.1; 172.16.0.0/24; };
allow-transfer { 127.0.0.1; 172.16.0.0/24; };
auth-nxdomain no; # conform to RFC1035
};
zone "." {
type hint;
file "/etc/bind/db.root";
};
// be authoritative for the localhost forward and reverse zones, and for
// broadcast zones as per RFC 1912
zone "localhost" {
type master;
file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
type master;
file "/etc/bind/db.127";
};
zone "0.in-addr.arpa" {
type master;
file "/etc/bind/db.0";
};
zone "255.in-addr.arpa" {
type master;
file "/etc/bind/db.255";
};
zone "0.16.172.in-addr.arpa" {
type master;
file "/etc/bind/db.172.16.0";
};
// 1.16.172.in-addr.arpa through 30.16.172.in-addr.arpa deleted for berevity
zone "31.16.172.in-addr.arpa" {
type master;
file "/etc/bind/db.172.16.31";
};
zone "2.0.192.in-addr.arpa" {
type master;
file "/etc/bind/db.192.0.2";
};
zone "254.169.in-addr.arpa" {
type master;
file "/etc/bind/db.169.254";
};
Many of you are wondering at the sheer number of stuff you see above. I removed some of the zones that's in my named.conf in addition to the 172.16 address space. There are many reserved blocks and blocks that I should never see on the wire. My name server has been set up to be authorative for all those domain so I don't waste time with accidental typos with addresses and with rogue traffic on the wire. I'll show an example of one of my forward and one of my reverse files, the rest will be left up to you. :-) You can grab the latest root name server list from:
Now, for my db.172.16.0 file:
;
; BIND reverse data file for the 172.16.0.0/24 interface
;
$TTL 604800
@ IN SOA mysystem.example.com postmaster.example.com. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
1.0 IN PTR hasenpfeffer.example.com.
128.0 IN PTR natto.example.com.
132.0 IN PTR haggis.example.com.
By now I'm sure you've noticed, the addresses are backwards. This convention is necessary due to the way the hostnames are anchored. The most specific part is on the left-hand side, and the least-specific is on the right. So foo.example.com is a host called foo (the most specific) in the example sub-domain (less specific) in the com top-level domain (the least specific). As for what the in-addr.arpa means, well, just take my word for it, that's how you do reverse lookups. (Or I can talk about ARPANET, but I don't think that many people are interested enough to stay on this page for that.) Now, for a forward:
;
; BIND data file for local loopback interface
;
$TTL 604800
@ IN SOA localhost. root.localhost. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
@ IN A 127.0.0.1
There. Pretty simple, no? I won't go over the meaning of the fields right now, might add it later if there's enough demand. After that, you can have your DHCP setup automatically tack on the servers passed to you into /etc/bind/named.conf and still have a fully caching name server setup without the overhead of DNS NAT.Working around Microsoft DHCP stupidityUnfortunately, Microsoft's flagship products, Windows XP/2000/2003/ME/etc., don't understand the DHCP Domain Search option -- 119. Thus, many places work around that with a truly ugly hack -- the domain that the system is told it's part of isn't the actual domain. Instead, multiple domains are shoveled into a single record and seperated by whitespace. So instead of: Look in eng.example.com, then corp.example.com, then test.example.com, then example.com.They're told: Look in "eng.example.com corp.example.com test.example.com example.com" Yes, you read that right. The domain the system is part of, according to DHCP, is a single giant string with spaces. Not multiple domains. Thankfully, most DHCP client software handle this misconfiguration properly. It does cause quite a bit of problems, though, when you want to verify the correct configuration of the DHCP servers. You can't simply assume the servers are accidentally misconfigured because it spits out the incorrect data. If you need to work with Windows, keep in mind that's how you need to give the clients additional domains to search. And expect some subtle breakage in various situations. The order the records are presented gets rather important. For example, in /etc/resolv.conf, the domain and search directives are mutually exclusive. So if you get a multi-record "domain" entry, make sure the search directive gets the list and puts that line after the domain directive. Or remove the domain directive entirely. |