About DNS
The Domain Name System (DNS) is a hierarchical distributed naming system for computers, services, or any resource connected to the Internet or a private network. It associates various information with domain names assigned to each of the participating entities. Most prominently, it translates more readily memorized domain names to the numerical IP addresses needed for the purpose of locating and identifying computer services and device with the underlying network protocols. By providing a worldwide, distributed directory service, the Domain Name System is an essential component of the functionality of the Internet.
Forwarding DNS Server
A forwarder is a Domain Name System (DNS) server on a network that forwards DNS queries for external DNS names to DNS servers outside that network. You can also forward queries according to specific domain names using conditional forwarders.
Setting Up Forwarder DNS Server
Linux Distro | Debian 8.2 Jessie |
Server IP | 10.42.0.109 |
So, in this post we are going to create a forwarding DNS Server in our Debian server using BIND9, we are going to install it in our server by typing:
# apt-get install bind9 bind9utils
root@debian-server:~# apt-get install bind9 bind9utils Reading package lists... Done Building dependency tree Reading state information... Done Suggested packages: bind9-doc resolvconf The following NEW packages will be installed: bind9 bind9utils 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. Need to get 481 kB of archives. After this operation, 1,458 kB of additional disk space will be used. Get:1 http://security.debian.org/ jessie/updates/main bind9utils amd64 1:9.9.5.dfsg-9+deb8u5 [167 kB] Get:2 http://security.debian.org/ jessie/updates/main bind9 amd64 1:9.9.5.dfsg-9+deb8u5 [314 kB] Fetched 481 kB in 8s (58.8 kB/s) Preconfiguring packages ... Selecting previously unselected package bind9utils. (Reading database ... 35694 files and directories currently installed.) Preparing to unpack .../bind9utils_1%3a9.9.5.dfsg-9+deb8u5_amd64.deb ... Unpacking bind9utils (1:9.9.5.dfsg-9+deb8u5) ... Selecting previously unselected package bind9. Preparing to unpack .../bind9_1%3a9.9.5.dfsg-9+deb8u5_amd64.deb ... Unpacking bind9 (1:9.9.5.dfsg-9+deb8u5) ... Processing triggers for man-db (2.7.0.2-5) ... Processing triggers for systemd (215-17+deb8u2) ... Processing triggers for ufw (0.33-2) ... Setting up bind9utils (1:9.9.5.dfsg-9+deb8u5) ... Setting up bind9 (1:9.9.5.dfsg-9+deb8u5) ... Adding group `bind' (GID 119) ... Done. Adding system user `bind' (UID 111) ... Adding new user `bind' (UID 111) with group `bind' ... Not creating home directory `/var/cache/bind. wrote key file "/etc/bind/rndc.key" # Processing triggers for systemd (215-17+deb8u2) ... Processing triggers for ufw (0.33-2) ... root@debian-server:~#
Now installation is done, we are going to edit the configuration files which is the /etc/bind/named.conf.options which by default looks like this
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. // forwarders { // 0.0.0.0; // }; //======================================================================== // 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 //======================================================================== dnssec-validation auto; auth-nxdomain no; # conform to RFC1035 listen-on-v6 { any; }; };
Then we start our modification, in a situation where we want to only accept DNS queries from clients on our network and some specific IPs, we would prepend this line to the file
acl allowed_clients { localhost; 10.42.0.0/24; };
We have created a list of IPs to accept DNS queries from, now we are going into the options block editing the forwarders to forward DNS queries the server could not resolve locally to an external DNS server and we are using Google DNS. Uncomment this line
// forwarders { // 0.0.0.0; // };
To
forwarders { 8.8.8.8; 8.8.4.4; };
Since we already specified with ACL, clients it should accept queries from, we now use it here in the options block. Adding these lines:
forwarders { 8.8.8.8; 8.8.4.4; }; recursion yes; allow-query { allowed_clients; };
Any request from a client which is not present in the allowed_clients ACL would be refused. Of course this can also be done with IPTABLES too. Our server is a forwarding DNS Server, why not make it clear to the server that it’s job is to forward requests that it can’t resolve to the outside servers. Now we add this line:
forwarders { 8.8.8.8; 8.8.4.4; }; recursion yes; allow-query { allowed_clients; }; forward only;
Save the file, at the end named.conf.options should look like this:
acl allowed_clients { localhost; 10.42.0.0/24; }; 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. forwarders { 8.8.8.8; 8.8.4.4; }; recursion yes; allow-query { allowed_clients; }; forward only; //======================================================================== // 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 //======================================================================== dnssec-validation auto; auth-nxdomain no; # conform to RFC1035 listen-on-v6 { any; }; };
Checking BIND Configuration
We are done with configuration, now to set our DNS Server working. We are going to check if we are having error in our named.conf.options, we type
# named-checkconf
If it returns no result, we are good to go. Restart bind now and make sure its working
# systemctl restart bind9
# systemctl status bind9
root@debian-server:/etc/bind# systemctl status bind9 ● bind9.service - BIND Domain Name Server Loaded: loaded (/lib/systemd/system/bind9.service; enabled) Drop-In: /run/systemd/generator/bind9.service.d └─50-insserv.conf-$named.conf Active: active (running) since Fri 2016-01-22 08:34:18 WAT; 5min ago Docs: man:named(8) Process: 2220 ExecStop=/usr/sbin/rndc stop (code=exited, status=0/SUCCESS) Main PID: 2225 (named) CGroup: /system.slice/bind9.service └─2225 /usr/sbin/named -f -u bind Jan 22 08:34:18 debian-server named[2225]: command channel listening on ::1#953 Jan 22 08:34:18 debian-server named[2225]: managed-keys-zone: loaded serial 2 Jan 22 08:34:18 debian-server named[2225]: zone 0.in-addr.arpa/IN: loaded serial 1 Jan 22 08:34:18 debian-server named[2225]: zone 127.in-addr.arpa/IN: loaded serial 1 Jan 22 08:34:18 debian-server named[2225]: zone 255.in-addr.arpa/IN: loaded serial 1 Jan 22 08:34:18 debian-server named[2225]: zone localhost/IN: loaded serial 2 Jan 22 08:34:18 debian-server named[2225]: all zones loaded Jan 22 08:34:18 debian-server named[2225]: running
Testing Out DNS Server on Client System
On client system we are going to test out our DNS server if it’s actually resolving.
$ dig @10.42.0.109 unixmen.com
; <<>> DiG 9.9.5-9+deb8u5-Debian <<>> @10.42.0.109 unixmen.com ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16997 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;unixmen.com. IN A ;; ANSWER SECTION: unixmen.com. 12032 IN A 158.69.30.189 ;; Query time: 1 msec ;; SERVER: 10.42.0.109#53(10.42.0.109) ;; WHEN: Fri Jan 22 08:48:45 WAT 2016 ;; MSG SIZE rcvd: 56
It resolved, means it’s working
Creating Zones
In our network, we might want to resolve a specific domain locally (i.e only if you are using the DNS Server).
Firstly, we will try to resolve the domain name local.server on a client and see the output
$ host local.server 10.42.0.109
Using domain server: Name: 10.42.0.109 Address: 10.42.0.109#53 Aliases: Host local.server not found: 3(NXDOMAIN)
As it couldn’t resolve the domain name, which is what we are about to solve.
We will be editing the /etc/bind/named.conf.local and we want to resolve local.server to a client on same network, add this line to the file
zone "local.server" { type master; file "/etc/bind/db.local.server"; };
It’s a master zone and the zone file is /etc/bind/db.local.server which we are still about to create. We will copy the example file which is db.empty to db.local.server
# cp /etc/bind/db.empty /etc/bind/db.local.server
And then we edit /etc/bind/db.local.server which by default should look similar to this
; BIND reverse data file for empty rfc1918 zone ; ; DO NOT EDIT THIS FILE - it is used for multiple zones. ; Instead, copy it, edit named.conf, and use that copy. ; $TTL 86400 @ IN SOA localhost. root.localhost. ( 1 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 86400 ) ; Negative Cache TTL ; @ IN NS localhost.
In the first line, replace localhost. to local.server. making it look like this
@ IN SOA local.server. root.localhost. (
Then we start adding records, append these lines to the file
@ IN A 10.42.0.1 sub IN CNAME @
Save the file, in complete the file now looks like this
; BIND reverse data file for empty rfc1918 zone ; ; DO NOT EDIT THIS FILE - it is used for multiple zones. ; Instead, copy it, edit named.conf, and use that copy. ; $TTL 86400 @ IN SOA local.server. root.localhost. ( 1 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 86400 ) ; Negative Cache TTL ; @ IN NS localhost. @ IN A 10.42.0.1 sub IN CNAME @
Restart bind9 once again.
Testing Out Zone
We have successfully added the zones, we should now retry looking up the domain name again on the client and see if it’s actually working
donjajo@jajo-pc:~$ host local.server 10.42.0.109 Using domain server: Name: 10.42.0.109 Address: 10.42.0.109#53 Aliases: local.server has address 10.42.0.1
donjajo@jajo-pc:~$ host sub.local.server 10.42.0.109 Using domain server: Name: 10.42.0.109 Address: 10.42.0.109#53 Aliases: sub.local.server is an alias for local.server. local.server has address 10.42.0.1
And yes, it successfully resolved local.server and it’s CNAME sub.local.server
Now we’ve got our DNS Server working!