Installing and Configuring a Primary Bind9 Server (Master)
Introduction
BIND (Berkeley Internet Name Domain) is the most widely used DNS server on the Internet, especially on Unix-like systems. It is currently maintained by the Internet Systems Consortium.
A new version of BIND (BIND 9) was rewritten to solve some architectural issues in the initial code and to add support for DNSSEC (DNS Security Extensions).
Installation
Installing Bind9 is quite simple:
aptitude install bind9 dnsutils
On OpenBSD, bind is installed by default.
Configuration
host.conf
Here’s how to configure the /etc/host.conf
file:
order hosts,bind
multi on
We are specifying here that requests made from the server should first check the hosts file and then Bind.
Note: This modification is not needed for OpenBSD.
rndc.conf
Introduction to TSIG Keys
Transaction signatures (“TSIG”) are a simpler form of DNS security. They use cryptographic hash functions to generate pseudo-signatures of DNS packets. The hash value is a combination of actual DNS data, timestamps to prevent replay attacks, and a shared secret between client and server. Since both entities involved in the DNS lookup must know the shared secret, TSIG signatures can only really be implemented in environments where systems are under common administrative control and where confidentiality of the shared secret can be absolutely guaranteed. In the case of ENUM, this means they can and should be used among ENUM level 0 name servers. For example, they can be used to validate zone transfers or dynamic update requests, with these functions being restricted to trusted clients because they know the shared secret.
Creating a TSIG Key
If you’re on OpenBSD, we’ll simplify things a bit, and to ensure this tutorial has the same paths everywhere, we’ll create a symbolic link:
ln -s /var/named/etc /etc/bind
Let’s generate a TSIG key:
cd /etc/bind
dnssec-keygen -a hmac-md5 -b 512 -n HOST simba
- Replace the number of bits with whatever you want and use your hostname.
- Replace simba with the name of your server where Bind is installed.
Once generated (this may take a few minutes), you will have 2 files:
- The key that needs to be moved to the bind folder.
- The rndc.conf file to be created.
Here are my 2 generated files:
- Ksimba.+157+18808.key
- Ksimba.+157+18808.private
Let’s first move the key and assign it the correct permissions:
mv Ksimba.+157+18808.key /etc/bind/rndc.key
chmod 640 /etc/bind/rndc.key
For Debian:
chown root:bind /etc/bind/rndc.key
For OpenBSD:
chown root:named /etc/bind/rndc.key
If I display the content of the other file, I will see the key that will be used (the one that will be used to fill in the following files):
$ cat Ksimba.+157+18808.private
Private-key-format: v1.2
Algorithm: 157 (HMAC_MD5)
Key: a4fGtm0fB4zO+4KfqH/zNZ3nPq+ThM5yUCEE7AqzEVI=
Bits: AAA=
Then let’s create the /etc/bind/rndc.conf
file and insert the key:
key "rndc-key" {
algorithm hmac-md5;
secret "a4fGtm0fB4zO+4KfqH/zNZ3nPq+ThM5yUCEE7AqzEVI=";
};
options {
default-key "rndc-key";
default-server 127.0.0.1;
default-port 953;
};
named.conf
// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
// structure of BIND configuration files in Debian, *BEFORE* you customize
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
named.conf.local
The acl section allows you to define reusable access lists in other sections of the configuration file. The following definition defines internal clients:
//
// Do any local configuration here
//
// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";
// Acl definition
acl "zoneinterne" {
// IP range authorized to make DNS requests
192.168.0.0/24;
10.8.0.0/24;
127.0.0.1;
};
acl "srvsecondaires" {
// My secondary server
x.x.x.x;
// Gandi (which offers a secondary DNS)
217.70.177.40;
};
Let’s define the logging part:
// Logs
logging {
channel xfer-log {
file "/var/log/bind.log";
print-category yes;
print-severity yes;
print-time yes;
severity info;
};
category xfer-in { xfer-log; };
category xfer-out { xfer-log; };
category notify { xfer-log; };
};
Let’s add some security to limit remote administration. If you don’t want to authorize anything, leave the controls section empty:
// TSIG Security | RNDC Key
key "rndc-key" {
algorithm hmac-md5;
secret "a4fGtm0fB4zO+4KfqH/zNZ3nPq+ThM5yUCEE7AqzEVI=";
};
controls {
inet 127.0.0.1 port 953
allow { 127.0.0.1; "srvsecondaires"; } keys { "rndc-key"; };
};
named.conf.default-zones
Ideally, build a zone/view file (to include in named.conf for each of your zones). But for simplicity, we’ll leave everything in the same file here.
The view sections define server behaviors based on the IP address of the client sending the request, allowing DNS responses to be differentiated. We define two views:
- One corresponding to clients in the internal and DMZ zone: recursion needs to be re-enabled for these requests, and resolving all possible names (zone “.”) needs to be allowed.
- Another corresponding to requests from outside (e.g. Internet). Only authorize requests for the zone where the DNS server has authority:
view "interne" {
// These are the clients that see this view
match-clients {
zoneinterne;
};
// Recursion permited for zoneinterne ACL subnets
recursion yes;
allow-recursion {
zoneinterne;
};
// prime the server with knowledge of the root servers
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 "deimos.fr" {
type master;
notify no;
allow-update { none; };
file "/etc/bind/db.deimos.fr.local";
};
zone "mavro.fr" {
type master;
notify no;
allow-update { none; };
file "/etc/bind/db.mavro.fr.local";
};
zone "localhost" {
type master;
notify no;
allow-update { none; };
file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
type master;
notify no;
allow-update { none; };
file "/etc/bind/db.127";
};
zone "0.in-addr.arpa" {
type master;
notify no;
allow-update { none; };
file "/etc/bind/db.0";
};
zone "255.in-addr.arpa" {
type master;
notify no;
allow-update { none; };
file "/etc/bind/db.255";
};
zone "0.168.192.in-addr.arpa" {
type master;
notify no;
allow-update { none; };
file "/etc/bind/db.0.168.192.inv.local";
};
};
Now let’s move on to our external zone which will be visible to everyone from outside:
view "externe" {
match-clients {
any;
};
// Recursion not permited for World Wide Web
recursion no;
zone "deimos.fr" {
type master;
notify yes;
allow-update { none; };
allow-transfer { "rndc-key"; };
file "/etc/bind/db.deimos.fr";
};
zone "mavro.fr" {
type master;
notify yes;
allow-update { none; };
allow-transfer { "rndc-key"; };
file "/etc/bind/db.mavro.fr";
};
zone "localhost" {
type master;
notify yes;
allow-update { none; };
file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
type master;
notify yes;
allow-update { none; };
file "/etc/bind/db.127";
};
zone "0.in-addr.arpa" {
type master;
notify yes;
allow-update { none; };
file "/etc/bind/db.0";
};
zone "255.in-addr.arpa" {
type master;
notify yes;
allow-update { none; };
file "/etc/bind/db.255";
};
zone "0.168.192.in-addr.arpa" {
type master;
notify yes;
allow-update { none; };
allow-transfer { "rndc-key"; };
file "/etc/bind/db.0.168.192.inv";
};
};
named.conf.options
Here’s the content:
options {
directory "/var/cache/bind";
// If there is a firewall between you and nameservers you want
// to talk to, you may need to fix the firewall to allow multiple
// ports to talk. See http://www.kb.cert.org/vuls/id/800113
// If your ISP provided one or more IP addresses for stable
// nameservers, you probably want to use them as forwarders.
// Uncomment the following block, and insert the addresses replacing
// the all-0's placeholder.
// Force other DNS to answer
//forwarders {
// 212.27.32.176;
// 212.27.32.177;
//};
//========================================================================
// If BIND logs error messages about the root key being expired,
// you will need to update your keys. See https://www.isc.org/bind-keys
//========================================================================
// Avoid Bind Cache Poisoning
dnssec-enable yes;
dnssec-validation auto;
allow-query {
any;
};
// Security version
// Check with: dig -t txt -c chaos VERSION.BIND @<dns.server.com>
version "Microsoft 2008 DNS Server";
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
};
You can add these types of options to improve security:
allow-recursion { none; }; // disabling recursive queries (and thus DNS cache Poisoning)
allow-transfer { none; }; // disabling zone transfer
notify no; // disabling zone change notifications
zone-statistics no; // disabling statistics
interface-interval 0; // disabling search for new interfaces
max-cache-size 20M; // max cache size
In case you want to redirect domains (e.g., google.com –> a machine on your local network):
zone "google.com" {
type forward;
forwarders {
192.168.0.17; // My primary DNS
192.168.0.30; // My secondary DNS
};
forward only;
};
You can also add this:
zone "128.168.192.in-addr.arpa" {
type forward;
forwarders {
192.168.128.99;
};
forward only;
};
db.deimos.fr
Here is the content of my file that will be available to everyone:
$TTL 604800
@ IN SOA simba.deimos.fr. root.deimos.fr. (
Replace the first field with the FQDN of your machine, and the second corresponds to the admin’s email (here root@deimos.fr). The email address is written in a special way, but it works.
2010301201 ; Serial (date + incrementation)
Note: By convention, the serial is in the form YYYYMMDDNN (YYYY: year, MM: month, DD: day, NN: revision).
7200 ; Refresh
3600 ; Retry
1209600 ; Expire
604800 ; Negative Cache TTL
)
NS mufasa.deimos.fr.
A 88.162.130.192
NS ns6.gandi.net.
NS shenzi.deimos.fr.
MX 5 mufasa.deimos.fr.
MX 10 shenzi.deimos.fr.
TXT "v=spf1 ip4:192.168.0.0/24 a mx ~all exp=getlost.deimos.fr"
getlost TXT "You are not allowed to send a message from this domain"
_deimos.fr TXT "t=y; o=-;"
m1._deimos.fr TXT "g=; k=rsa; p=;...IWWiAyklt5FDmS2U7QIDAQAB..."
For the TXT part, I’ll let you check out other articles that deal with SPF.
localhost A 127.0.0.1
mufasa A 82.232.191.145
shenzi A 88.191.130.125
ns6 A 217.70.177.40
mail CNAME mufasa
jabber CNAME mufasa
server CNAME mufasa
serveur CNAME mufasa
sftp CNAME mufasa
www CNAME mufasa
blocnotesinfo CNAME mufasa
infos CNAME mufasa
webmail CNAME mufasa
nagios CNAME mufasa
All of these correspond to your A records, canonical names, etc.
db.deimos.fr.local
This is for the internal zone, put whatever you want without restrictions…
$TTL 604800
@ IN SOA simba.deimos.fr. root.deimos.fr. (
2010301201 ; Serial (date + incrementation)
7200 ; Refresh
3600 ; Retry
1209600 ; Expire
604800 ; Negative Cache TTL
)
NS simba.deimos.fr.
A 192.168.110.3
MX 5 mufasa.deimos.fr.
MX 10 shenzi.deimos.fr.
localhost A 127.0.0.1
mufasa A 192.168.0.254
shenzi A 192.168.20.4
ns6 A 217.70.177.40
rafiki A 192.168.110.1
simba A 192.168.110.3
sarabi A 192.168.99.10
www CNAME rafiki
www1 CNAME rafiki
www2 CNAME shenzi
blocnotesinfo CNAME www
blog CNAME www
webmail CNAME www
nagios CNAME www
git CNAME www
gitweb CNAME www
phpmyadmin CNAME www
backuppc CNAME sarabi
db.0.168.192.inv
If now we want reverse DNS:
$TTL 604800
@ IN SOA simba.deimos.fr. root.deimos.fr. (
2010301201 ; Serial (date + incrementation)
7200 ; Refresh
3600 ; Retry
1209600 ; Expire
604800 ; Negative Cache TTL
)
NS simba.deimos.fr.
A 88.162.130.192
A 88.191.31.89
NS ns6.gandi.net.
NS shenzi.deimos.fr.
MX 5 simba.deimos.fr.
MX 10 shenzi.deimos.fr.
TXT "v=spf1 ip4:192.168.0.0/24 a mx ~all exp=getlost.deimos.fr"
getlost TXT "You are not allowed to send a message from this domain"
1 PTR localhost
2 PTR simba
3 PTR ns6.gandi.net
4 PTR shenzi.deimos.fr
The PTRs should go from smallest to largest based on priorities.
db.0.168.192.inv.local
Now, the reverse DNS for local:
$TTL 604800
@ IN SOA simba.deimos.fr. root.deimos.fr. (
2010301201 ; Serial (date + incrementation)
3600 ; Refresh
7200 ; Retry
1209600 ; Expire
604800 ; Negative Cache TTL
)
NS simba.deimos.fr.
MX 5 simba.deimos.fr.
1 PTR localhost
2 PTR simba
3 PTR serveur
4 PTR earth
5 PTR wind
6 PTR water
10 PTR kiss
11 PTR imprimante
30 PTR psp
31 PTR pocket
32 PTR ldap
Verification
All that’s left is to restart the service and check the logs:
/etc/init.d/bind9 restart
$ tail -100 /var/log/syslog
Jun 10 22:44:20 deimos named[9641]: starting BIND 9.4.1 -u bind
Jun 10 22:44:20 deimos named[9641]: found 2 CPUs, using 2 worker threads
Jun 10 22:44:20 deimos named[9641]: loading configuration from '/etc/bind/named.conf'
Jun 10 22:44:20 deimos named[9641]: no IPv6 interfaces found
Jun 10 22:44:20 deimos named[9641]: listening on IPv4 interface eth0, 192.168.0.1#53
Jun 10 22:44:20 deimos named[9641]: listening on IPv4 interface lo, 127.0.0.1#53
Jun 10 22:44:20 deimos named[9641]: listening on IPv4 interface tun0, 10.8.0.1#53
Jun 10 22:44:20 deimos named[9641]: listening on IPv4 interface bond0, 192.168.0.2#53
Jun 10 22:44:20 deimos named[9641]: automatic empty zone: view interne: 254.169.IN-ADDR.ARPA
Jun 10 22:44:20 deimos named[9641]: automatic empty zone: view interne: 2.0.192.IN-ADDR.ARPA
Jun 10 22:44:20 deimos named[9641]: automatic empty zone: view interne: 255.255.255.255.IN-ADDR.ARPA
Jun 10 22:44:20 deimos named[9641]: automatic empty zone: view interne: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA
Jun 10 22:44:20 deimos named[9641]: automatic empty zone: view interne: 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA
Jun 10 22:44:20 deimos named[9641]: automatic empty zone: view interne: D.F.IP6.ARPA
Jun 10 22:44:20 deimos named[9641]: automatic empty zone: view interne: 8.E.F.IP6.ARPA
Jun 10 22:44:20 deimos named[9641]: automatic empty zone: view interne: 9.E.F.IP6.ARPA
Jun 10 22:44:20 deimos named[9641]: automatic empty zone: view interne: A.E.F.IP6.ARPA
Jun 10 22:44:20 deimos named[9641]: automatic empty zone: view interne: B.E.F.IP6.ARPA
Jun 10 22:44:20 deimos named[9641]: command channel listening on 127.0.0.1#953
Jun 10 22:44:20 deimos named[9641]: zone 0.in-addr.arpa/IN/interne: loaded serial 1
Jun 10 22:44:20 deimos named[9641]: zone 127.in-addr.arpa/IN/interne: loaded serial 1
Jun 10 22:44:20 deimos named[9641]: zone 0.168.192.in-addr.arpa/IN/interne: loaded serial 2006031801
Jun 10 22:44:20 deimos named[9641]: zone 255.in-addr.arpa/IN/interne: loaded serial 1
Jun 10 22:44:20 deimos named[9641]: zone mavro.fr/IN/interne: loaded serial 2006031801
Jun 10 22:44:20 deimos named[9641]: zone localhost/IN/interne: loaded serial 1
Jun 10 22:44:20 deimos named[9641]: zone deimos.fr/IN/interne: loaded serial 2006110401
Jun 10 22:44:20 deimos named[9641]: zone 0.in-addr.arpa/IN/externe: loaded serial 1
Jun 10 22:44:20 deimos named[9641]: zone 127.in-addr.arpa/IN/externe: loaded serial 1
Jun 10 22:44:20 deimos named[9641]: zone 0.168.192.in-addr.arpa/IN/externe: loaded serial 2006102701
Jun 10 22:44:20 deimos named[9641]: zone 255.in-addr.arpa/IN/externe: loaded serial 1
Jun 10 22:44:21 deimos named[9641]: zone mavro.fr/IN/externe: loaded serial 2007040103
Jun 10 22:44:21 deimos named[9641]: zone localhost/IN/externe: loaded serial 1
Jun 10 22:44:21 deimos named[9641]: zone deimos.fr/IN/externe: loaded serial 2007040101
Jun 10 22:44:21 deimos named[9641]: running
No errors here, so everything is good :-)
FAQ
What folders and permissions for Bind’s chroot?
Here are the commands to execute:
mkdir -p /var/lib/named/etc
mkdir /var/lib/named/dev
mkdir -p /var/lib/named/var/cache/bind
mkdir -p /var/lib/named/var/run/bind/run
mv /etc/bind /var/lib/named/etc
ln -s /var/lib/named/etc/bind /etc/bind
mknod /var/lib/named/dev/null c 1 3
mknod /var/lib/named/dev/random c 1 8
chmod 666 /var/lib/named/dev/null /var/lib/named/dev/random
chown -R bind:bind /var/lib/named/var/*
chown -R bind:bind /var/lib/named/etc/bind
named: invalid command from 127.0.0.1: bad auth
How is it that all my conf files contain the same RNDC key, and yet I get this type of error?
The reason is simple: Bind must already be running. So a quick check with:
netstat -auntp
And there we should realize that it’s already running. So kill the corresponding PIDs and restart the Bind service:
pkill named
Why can’t I make records with “_”?
Bind versions from 9.3 now incorporate more precise control over domain name validity. They can no longer contain _ (0x5f in the ASCII table), as stipulated by RFC 1035. This is however quite unfortunate for me because I have several domains containing _.
Error message produced:
Mar 6 07:48:08 dns3 named[25459]: pri/rags.ch.hosts:25: wisteria_lane.rags.ch: bad owner name (check-names)
Mar 6 07:48:08 dns3 named[25459]: zone rags.ch/IN: loading master file pri/rags.ch.hosts: bad owner name (check-names)
Here’s a small patch that solves the problem:
name_with_underscore.patch:
--- lib/dns/name.c.orig 2006-03-06 17:44:30.000000000 +0100
+++ lib/dns/name.c 2006-03-06 17:45:07.000000000 +0100
@@ -261,7 +261,7 @@
return (ISC_FALSE);
}
-#define hyphenchar(c) ((c) == 0x2d)
+#define hyphenchar(c) ((c) == 0x2d || (c) == 0x5f)
#define asterchar(c) ((c) == 0x2a)
#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
|| ((c) >= 0x61 && (c) <= 0x7a))
zone ‘deimos.fr’ allows updates by IP address, which is insecure
You may have log errors like this:
Oct 2 17:29:03 star1 named[5120]: zone 'deimos.fr' allows updates by IP address, which is insecure
This simply means that your RNDC key is not being used. To use it with ACLs, just add your secondary servers to the “controls” section and only allow updates (at zone level) with the RNDC key:
...
controls {
inet 127.0.0.1 port 953
allow { 127.0.0.1; secondaryinternaldns; } keys { "rndc-key"; };
};
...
zone "deimos.fr" {
type master;
notify yes;
allow-update { key "rndc-key"; };
file "/etc/bind/db.deimos.fr";
};
...
Now restart your DNS server and there are no more problems, exchanges are encrypted :-)
too many timeouts resolving ‘mycompany.com/MX’ (in ’eu’?): disabling EDNS
This error can appear for name resolution that takes too long due to UDP packet size. This can be very annoying, especially for email reception which can take a few hours. The solution is to add this line:
...
edns-udp-size 1460;
...
Then restart the bind service. If the problem persists, try lowering the size (change from 1460 to 500 for example). There are ways to test all this using the dig command.
Use it like this until you no longer have timeouts:
dig +norec +dnssec mycompany.com MX @my_dns_server
dig +dnssec +norec +ignore dnskey MX @my_dns_server
zone deimos.fr/IN/internalview: journal rollforward failed: journal out of sync with zone
The server might have been shut down abruptly, or the zone file was manually edited without the zone being frozen. To solve this problem:
- Stop the bind server
- Delete the journal files (*.jnl in “/etc/bind”)
- Restart the bind server
How do I clear my cache?
To clear your bind cache:
rndc flush
Resources
- DNS Server on OpenBSD
- Installing An Ubuntu DNS Server With BIND
- http://fr.wikipedia.org/wiki/BIND
- http://fr.gentoo-wiki.com/HOWTO_Bind
- http://www.zytrax.com/books/dns/
- http://brocas.org/blog/post/2006/06/22/14-de-la-securite-d-une-architecture-dns-d-entreprise
- http://groups.google.com/group/comp.protocols.dns.bind/browse_thread/thread/cfa8c63ec6bd08d6?pli=1
Last updated 07 May 2013, 09:06 CEST.