Configure BIND 9 on Slackware for Web Hosting Service
PREREQUISITES: BIND binary (preinstalled with Slackware).
The installation commands can be run from a Putty window in a "cut-and-paste" style layout or copied to a script. Notes on Putty best practices can be found here.
Create a named.conf configuration and edit to allow zone transfers:
cat > /etc/named.conf << "EOF"
// BIND 9 CONFIGURATION
acl "xfer" {
127.0.0.1;
172.16.101.100;
172.16.202.0/24;
};
options {
directory "/var/named";
pid-file "/var/run/named/named.pid";
allow-transfer { xfer; };
notify yes;
recursion yes;
allow-recursion { xfer; };
allow-query { any; };
};
logging{category "default" { "debug"; };
category "general" { "debug"; };
category "database" { "debug"; };
category "security" { "debug"; };
category "config" { "debug"; };
category "resolver" { "debug"; };
category "xfer-in" { "debug"; };
category "xfer-out" { "debug"; };
category "notify" { "debug"; };
category "client" { "debug"; };
category "unmatched" { "debug"; };
category "network" { "debug"; };
category "queries" { "debug"; };
category "dispatch" { "debug"; };
category "lame-servers" { "debug"; };
channel "debug" {file "/var/log/named.log" versions 2 size 50m;
print-time yes;
print-category yes;};};
zone "." IN {
type hint;
file "named.ca";
};
zone "localhost" IN {
type master;
file "localhost.zone";
allow-update { none; };
};
zone "0.0.127.in-addr.arpa" IN {
type master;
file "named.local";
allow-update { none; };
};
controls {
inet 127.0.0.1 port 953
allow { 127.0.0.1; } keys { "rndc-key"; };
};
// rndc-key
include "/etc/rndc.key";
// WEBHOSTING CONTROL PANEL FILES INCLUDED HERE:
include "/home/webcp/named/include/include.named";
// CONFIGURE ADDITIONAL DOMAINS HERE:
zone "fatpenguinhosting.com" {
type master;
file "/var/named/fatpenguinhosting.com.zone";
allow-update { none; };
};
EOF
chmod 644 /etc/named.conf
mkdir -p /home/webcp/named/include
touch /home/webcp/named/include/include.named
touch /var/log/named.log
The extra /var/named/fatpenguinhosting.com.zone configuration reflects the fact
that you will need to manage your core hosting domain seperately from
the Web-cp hosting control panel due to the need to split master & slave machines onto seperate IP addresses.
You could just as easily do this at http://hn.org
or another offsite DNS service.
The master zone for fatpenguinhosting.com would look something
like this:
cat > /var/named/fatpenguinhosting.com.zone << "EOF"
$TTL 86400
@ IN SOA ns1.fatpenguinhosting.com. servadmin.hostinghacks.net. (
2004060203 ; serial, todays date + todays serial #
10800 ; refresh, seconds
3600 ; retry, seconds
604800 ; expire, seconds
86400 ) ; minimum, seconds
NS ns1.fatpenguinhosting.com.
NS ns2.fatpenguinhosting.com.
MX 10 mx1.fatpenguinhosting.com.
MX 20 mx2.fatpenguinhosting.com.
fatpenguinhosting.com. IN A 111.112.113.114 ; Nohost
www IN A 111.112.113.114
serv1 IN A 111.112.113.114
serv2 IN A 445.446.447.448
serv3 IN A 556.557.558.559
serv4 IN A 667.668.669.666
ns1 IN A 111.112.113.114
ns2 IN A 222.223.224.225
mx1 IN A 111.112.113.114
mx2 IN A 222.223.224.225
webmail IN A 111.112.113.114
secure IN A 111.112.113.114
EOF
chmod 644 /var/named/fatpenguinhosting.com.zone
create rndc.conf + generate rndc.key:
cat > /etc/rndc.conf << "EOF"
options {
default-key "rndc-key";
default-server 127.0.0.1;
default-port 953;
};
// rndc-key
include "/etc/rndc.key";
EOF
chown root.root /etc/rndc.conf
chmod 0640 /etc/rndc.conf
rndc-confgen -a -c /etc/rndc.key -u root
root nameservers:
cat > /var/named/named.ca << "EOF" ; last update: Jan 29, 2004 ; related version of root zone: 2004012900 ; ftp://ftp.rs.internic.net/domain/named.root . 3600000 IN NS A.ROOT-SERVERS.NET. A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4 . 3600000 NS B.ROOT-SERVERS.NET. B.ROOT-SERVERS.NET. 3600000 A 192.228.79.201 . 3600000 NS C.ROOT-SERVERS.NET. C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12 . 3600000 NS D.ROOT-SERVERS.NET. D.ROOT-SERVERS.NET. 3600000 A 128.8.10.90 . 3600000 NS E.ROOT-SERVERS.NET. E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10 . 3600000 NS F.ROOT-SERVERS.NET. F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241 . 3600000 NS G.ROOT-SERVERS.NET. G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4 . 3600000 NS H.ROOT-SERVERS.NET. H.ROOT-SERVERS.NET. 3600000 A 128.63.2.53 . 3600000 NS I.ROOT-SERVERS.NET. I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17 . 3600000 NS J.ROOT-SERVERS.NET. J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30 . 3600000 NS K.ROOT-SERVERS.NET. K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129 . 3600000 NS L.ROOT-SERVERS.NET. L.ROOT-SERVERS.NET. 3600000 A 198.32.64.12 . 3600000 NS M.ROOT-SERVERS.NET. M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33 ; End of File EOF chmod 644 /var/named/named.ca
- local zone info:
cat > /var/named/named.local << "EOF"
$TTL 86400
@ IN SOA localhost. root.localhost. (
1997022700 ; Serial
28800 ; Refresh
14400 ; Retry
3600000 ; Expire
86400 ) ; Minimum
IN NS localhost.
1 IN PTR localhost.
EOF
chmod 644 /var/named/named.local
- localhost zone:
cat > /var/named/localhost.zone << "EOF"
$TTL 86400
$ORIGIN localhost.
@ 1D IN SOA @ root (
42 ; serial
3H ; refresh
15M ; retry
1W ; expiry
1D ) ; minimum
1D IN NS @
1D IN A 127.0.0.1
EOF
chmod +x /etc/rc.d/rc.bind /etc/rc.d/rc.bind start
The output of dig for your locally configured domain should be as follows:
If you see something like this:root@serv1:~# dig @localhost fatpenguinhosting.com; <<>> DiG 9.3.0 <<>> @localhost fatpenguinhosting.com ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6323 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2 ;; QUESTION SECTION: ;fatpenguinhosting.com. IN A ;; ANSWER SECTION: fatpenguinhosting.com. 86400 IN A 64.161.106.197 ;; AUTHORITY SECTION: fatpenguinhosting.com. 86400 IN NS ns2.fatpenguinhosting.com. fatpenguinhosting.com. 86400 IN NS ns1.fatpenguinhosting.com. ;; ADDITIONAL SECTION: ns1.fatpenguinhosting.com. 86400 IN A 64.161.106.197 ns2.fatpenguinhosting.com. 86400 IN A 64.164.208.165 ;; Query time: 25 msec ;; SERVER: 127.0.0.1#53(localhost) ;; WHEN: Sun Mar 27 11:24:46 2005 ;; MSG SIZE rcvd: 119root@serv1:~# dig @192.168.0.10 fatpenguinhosting.com; <<>> DiG 9.3.0 <<>> @192.168.0.10 fatpenguinhosting.com ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64272 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2 ;; QUESTION SECTION: ;fatpenguinhosting.com. IN A ;; ANSWER SECTION: fatpenguinhosting.com. 86400 IN A 64.161.106.197 ;; AUTHORITY SECTION: fatpenguinhosting.com. 86400 IN NS ns1.fatpenguinhosting.com. fatpenguinhosting.com. 86400 IN NS ns2.fatpenguinhosting.com. ;; ADDITIONAL SECTION: ns1.fatpenguinhosting.com. 86400 IN A 64.161.106.197 ns2.fatpenguinhosting.com. 86400 IN A 64.164.208.165 ;; Query time: 2 msec ;; SERVER: 192.168.0.10#53(192.168.0.10) ;; WHEN: Sun Mar 27 11:24:58 2005 ;; MSG SIZE rcvd: 119
;; AUTHORITY SECTION: . 1533 IN SOA A.ROOT-SERVERS.NET. NSTLD.VERISIGN-GRS.COM. 2005032600 1800 900 604800 86400that indicates BIND is looking outward towards the internet for the answer ; usually because of an error like '; connection timed out; no servers could be reached'. To solve this:
- configure logrotate:
cat > /etc/logrotate.d/named << "EOF"
/var/log/named.log {
missingok
create 0644
postrotate
/etc/rc.d/rc.bind restart 2> /dev/null || true
endscript
}
EOF
chmod 644 /etc/logrotate.d/named
watch named logs:
cat > /etc/cron.weekly/watch.named << "EOF" #! /bin/sh tail -100 /var/log/named.log | mail -s "named log" servadmin@localhost EOF chmod +x /etc/cron.weekly/watch.named /etc/cron.weekly/watch.named
- Configure internal or external resolvers. The choice here is whether you want your own server sending queries out on its own (bind should be configured correctly) ; or do you have other servers (provided by your ISP) that have agreed to do the job?
# option 1: external resolvers cat > /etc/resolv.conf << "EOF" nameserver 111.112.113.114 nameserver 111.112.113.115 EOF |
# option 2: internal resolvers cat > /etc/resolv.conf << "EOF" nameserver 127.0.0.1 EOF |
# option 3: combination cat > /etc/resolv.conf << "EOF" nameserver 127.0.0.1 nameserver 111.112.113.114 nameserver 111.112.113.115 EOF |
search fatpenguinhosting.com
option often found in resolv.conf has no real value except to
cause unnecessary lookups and fill the
bind logs with them.
dig @192.168.0.10 hostinghacks.net axfr
allow-recursion
[ allow-recursion { address_match_list }; ]
allow-recursion defines a match list e.g. IP address(es) which are allowed
to issue recursive queries to the server. If the answer to the query already
exists in the cache it will be returned. If not specified all host are
allowed to make recursive queries. This option may only be specified
in a 'global' options statement.
The SOA record includes the first 6 lines and first references the hostname of the master server (which should also be a valid hostname for the local computer). The format of the zone file is a time to live (TTL) field followed by the start of authority (SOA) records.
The TTL instructs non-authoritative DNS servers how long to cache records retrieved from the zone file.
An integer TTL value is interpreted as seconds by default.
A day can be represented by any of the following lines:
$TTL 86400
$TTL 1440m
$TTL 24h
$TTL 1d
BIND resource records allow an explict TTL value that will
override the zone file's TTL for that specific resource
record.
[name][ttl] [class] type data
[name] -
[ttl] -cache time seconds
[class] always IN internet CH,HS never used
type
data
To set the TTL for an A or MX record to 1 use:
forum.hostinghacks.net. 1 IN A 192.168.5.100
hostinghacks.net. 1 IN MX 10 mx1.hostinghacks.net.
BIND 9 enforces strict compliance with the RFC1035 and RFC2308 TTL rules (BIND 8 allowed you to omit all TTLs from a zone file) . The default TTL is the value specified with the $TTL directive, or the previous explicit TTL if there is no $TTL directive. If there is no $TTL directive and the first RR in the file does not have an explicit TTL field, the error message "no TTL specified" is logged and loading the zone file fails. To avoid problems, use a $TTL directive in each zone file.
refresh - every refresh interval the slave server checks serial #. low value is not needed due to dns notify
"Retry" - how long a secondary server should wait before trying to reconnect to primary server if the connection was refused.
"Expire" - how long the secondary server should use its current entry if it is unable to perform a refresh,
a "negative cache TTL". Which is basically a TTL for subdomains that don't exist. So that if you were to query fake.hostinghacks.net the fact that this doesn't exist will be cached http://www.faqs.org/rfcs/rfc2308.html
options {
allow-recursion {64.164/24;};
};
dump the dns cache
ndc dumpdb
/var/named/named_dump.db
ndc stats
/var/named/named.stats
Q: A kill -HUP or ndc reload doesn't clear the nameserver cache
A: Cache is only cleared by killing and restarting named
bind 9 named.conf options
[ additional-from-auth yes | no ; ]
[ additional-from-cache yes | no ; ]
#[ allow-notify { address_match_list }; ]
#[ allow-query { address_match_list }; ]
[ allow-recursion { address_match_list }; ]
#[ allow-transfer { address_match_list }; ]
#[ allow-update-forwarding { address_match_list }; ]
[ allow-v6-synthesis { address_match_list }; ]
#[ also-notify { ip_addr [port ip_port] ; ... ] }; ]
[ auth-nxdomain yes | no; ]
[ blackhole { address_match_list }; ]
[ check-names ] NOT IMPLEMENTED IN BIND 9
[ cleaning-interval number; ]
[ coresize size_spec ; ] NOT YET IMPLEMENTED IN BIND 9
[ datasize size_spec ; ] NOT YET IMPLEMENTED IN BIND 9
[ deallocate-on-exit yes_or_no; ]IGNORED - DEFAULT BEHAVIOUR IN BIND 9
#[ dialup dialup_option; ] NOT YET IMPLEMENTED IN BIND 9
[ directory path_name; ]
[ dump-file path_name; ]
[ fake-iquery yes_or_no; ] IGNORED IN BIND 9
[ fetch-glue yes_or_no; ] OBSOLETE IN BIND 9
[ files size_spec ; ] NOT YET IMPLEMENTED IN BIND 9
#[ forward ( only | first ); ]
#[ forwarders { ipv4_addr | ipv6_addr [port ip_port] ; ... ] }; ]
[ has-old-clients yes_or_no; ] IGNORED IN BIND 9
[ heartbeat-interval number; ] NOT YET IMPLEMENTED IN BIND 9
[ host-statistics yes_or_no; ] NOT YET IMPLEMENTED IN BIND 9
[ hostname hostname_string; ]
[ interface-interval number; ]
#[ key-directory path_name; ]
[ lame-ttl number; ] NOT YET IMPLEMENTED IN BIND 9
[ listen-on [ port ip_port ] { address_match_list }; ]
[ listen-on-v6 [ port ip_port ] { address_match_list }; ]
#[ maintain-ixfr-base yes_or_no; ] OBSOLETE IN BIND 9
[ match-mapped-addresses yes_or_no; ]
[ max-cache-size size_spec ; ]
[ max-cache-ttl number; ]
#[ max-ixfr-log-size number; ] OBSOLETE IN BIND 9
[ max-journal-size size_spec; ]
[ max-ncache-ttl number; ]
#[ max-refresh-time number ; ]
#[ max-retry-time number ; ]
#[ max-transfer-idle-in number; ]
#[ max-transfer-idle-out number; ]
#[ max-transfer-time-in number; ]
#[ max-transfer-time-out number; ]
[ memstatistics-file path_name; ] NOT IMPLEMENTED IN BIND 9
#[ min-refresh-time number ; ]
#[ min-retry-time number ; ]
[ min-roots number; ] NOT YET IMPLEMENTED IN BIND 9
[ minimal-responses yes_or_no; ]
[ multiple-cnames yes_or_no; ] IGNORED BY BIND 9
[ named-xfer path_name; ] OBSOLETE In BIND 9
#[ notify yes_or_no | explicit; ]
#[ notify-source (ip4_addr | *) [port ip_port] ; ]
#[ notify-source-v6 (ip6_addr | *) [port ip_port] ; ]
[ pid-file path_name; ]
[ port ip_port; ]
[ provide-ixfr yes_or_no; ]
[ query-source [ address ( ip_addr | * ) ] [ port ( ip_port | * ) ]; ]
[ random-device path_name ; ]
[ recursion yes | no; ]
[ recursive-clients number; ]
[ request-ixfr yes_or_no; ]
[ rfc2308-type1 yes_or_no; ] NOT YET IMPLEMENTED IN BIND 9
[ rrset-order { order_spec ; [ order_spec ; ... ] ] NOT YET IMPLEMENTED IN BIND 9
[ serial-queries number; ] NOT IMPLEMENTED IN BIND 9
[ serial-query-rate number; ] NOT YET IMPLEMENTED IN BIND 9
#[ sig-validity-interval number ; ]
[ sortlist { address_match_list }];
[ stacksize size_spec ; ] NOT YET IMPLEMENTED IN BIND 9
[ statistics-file path_name; ]
[ statistics-interval number; ] NOT YET IMPLEMENTED IN BIND 9
[ tcp-clients number; ]
[ tkey-domain domainname; ]
[ tkey-dhkey key_name key_tag; ]
[ topology { address_match_list }]; NOT YET IMPLEMENTED IN BIND 9
[ transfer-format ( one-answer | many-answers ); ]
[ transfers-in number; ]
[ transfers-per-ns number; ]
#[ transfer-source (ip4_addr | *) [port ip_port] ; ]
#[ transfer-source-v6 (ip6_addr | *) [port ip_port] ; ]
[ transfers-out number; ]
[ treat-cr-as-space yes_or_no ; ] OBSOLETE BIND 9 READS BOTH FORMATS
[ use-id-pool yes_or_no; ] OBSOLETE IIN BIND 9
[ use-ixfr yes_or_no ; ] OBSOLETE In BIND 9
[ version version_string; ]
#[ zone-statistics yes | no ; ]
Valid TTLs are of the range 0-2147483647 seconds.
slackware init script
cat > /etc/rc.d/rc.bind << "EOF"
#!/bin/sh
# Start/stop/restart the BIND name server daemon (named).
# Start bind. In the past it was more secure to run BIND
# as a non-root user (for example, with '-u daemon'), but
# the modern version of BIND knows how uses to use the
# kernel's capability mechanism to drop all root privileges
# except the ability to bind() to a privileged port and set
# process resource limits, so -u should not be needed. If
# you wish to use it anyway, chown the /var/run/named
# directory to the non-root user.
#
# You might also consider running BIND in a "chroot jail",
# a discussion of which may be found in
# /usr/doc/Linux-HOWTOs/Chroot-BIND-HOWTO.
bind_start() {
if [ -x /usr/sbin/named ]; then
echo "Starting BIND: /usr/sbin/named"
/usr/sbin/named
fi
}
# Stop bind:
bind_stop() {
killall named
}
# Restart bind:
bind_restart() {
bind_stop
sleep 1
bind_start
}
case "$1" in
'start')
bind_start
;;
'stop')
bind_stop
;;
'restart')
bind_restart
;;
*)
echo "usage $0 start|stop|restart"
esac
EOF
chmod +x /etc/rc.d/rc.bind
/etc/rc.d/rc.bind start

Default slackware named.conf:
options {
directory "/var/named";
/*
* If there is a firewall between you and nameservers you want
* to talk to, you might need to uncomment the query-source
* directive below. Previous versions of BIND always asked
* questions using port 53, but BIND 8.1 uses an unprivileged
* port by default.
*/
// query-source address * port 53;
};
//
// a caching only nameserver config
//
zone "." IN {
type hint;
file "caching-example/named.ca";
};
zone "localhost" IN {
type master;
file "caching-example/localhost.zone";
allow-update { none; };
};
zone "0.0.127.in-addr.arpa" IN {
type master;
file "caching-example/named.local";
allow-update { none; };
};

The second include statement points to domain zone files that are being hosted. Using a seperate file that lists the zone records is an optional way to keep everying organized: