debian
for Debian 10.3student
for CentOS 7/etc/hosts
file corresponding to the slave and master VMs<ip_master> master
<ip_slave> slave
master
instead of the IP address of the master VM for clarity. Likewise, we can use slave
instead of the IP address of the slave VM.In this task we will examine how we ca use two DNS resolvers to query DNS servers. The two DNS resolvers we will use are host and dig. However before we use them, we first have to install them.
root@master:~# apt update [...] root@master:~# apt install host dnsutils [...]
Next, we find out the IP address of a website using host.
root@master:~# host acs.pub.ro acs.pub.ro has address 141.85.227.151 acs.pub.ro mail is handled by 10 mx.acs.pub.ro.
We can see from this output DNS records, such as NS(name server), MX(mail server), AAAA(IPv6 address), SOA(start of authority).
For more information, we can use the -v
parameter.
root@master:~# host -v acs.pub.ro Trying "acs.pub.ro" ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1805 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 3 ;; QUESTION SECTION: ;acs.pub.ro. IN A ;; ANSWER SECTION: acs.pub.ro. 28800 IN A 141.85.227.151 ;; AUTHORITY SECTION: acs.pub.ro. 28800 IN NS ns1.cs.pub.ro. acs.pub.ro. 28800 IN NS ns1.grid.pub.ro. acs.pub.ro. 28800 IN NS ns2.cs.pub.ro. ;; ADDITIONAL SECTION: ns1.cs.pub.ro. 28800 IN A 141.85.226.5 ns1.grid.pub.ro. 3600 IN A 141.85.241.15 ns2.cs.pub.ro. 28800 IN A 141.85.241.113 Received 154 bytes from 141.85.241.15#53 in 1 ms Trying "acs.pub.ro" ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58004 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;acs.pub.ro. IN AAAA ;; AUTHORITY SECTION: acs.pub.ro. 28800 IN SOA ns1.cs.pub.ro. admin.acs.pub.ro. 2017120701 28800 7200 604800 86400 Received 77 bytes from 141.85.241.15#53 in 0 ms Trying "acs.pub.ro" ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 755 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 4 ;; QUESTION SECTION: ;acs.pub.ro. IN MX ;; ANSWER SECTION: acs.pub.ro. 1 IN MX 10 mx.acs.pub.ro. ;; AUTHORITY SECTION: acs.pub.ro. 28800 IN NS ns1.grid.pub.ro. acs.pub.ro. 28800 IN NS ns1.cs.pub.ro. acs.pub.ro. 28800 IN NS ns2.cs.pub.ro. ;; ADDITIONAL SECTION: mx.acs.pub.ro. 28800 IN A 141.85.227.151 ns1.cs.pub.ro. 28800 IN A 141.85.226.5 ns1.grid.pub.ro. 3600 IN A 141.85.241.15 ns2.cs.pub.ro. 28800 IN A 141.85.241.113 Received 173 bytes from 141.85.241.15#53 in 2 ms
In order to request a specific record we can use the -t
parameter and the record we want.
root@master:~# host -t ns acs.pub.ro acs.pub.ro name server ns2.cs.pub.ro. acs.pub.ro name server ns1.cs.pub.ro. acs.pub.ro name server ns1.grid.pub.ro. root@master:~# host -t mx acs.pub.ro acs.pub.ro mail is handled by 10 mx.acs.pub.ro. root@master:~# host -t soa acs.pub.ro acs.pub.ro has SOA record ns1.cs.pub.ro. admin.acs.pub.ro. 2017120701 28800 7200 604800 86400
host will query the DNS servers from /etc/resolv.conf
. If we want to query a specific DNS server, we can use host as such:
root@master:~# host acs.pub.ro 8.8.8.8 Using domain server: Name: 8.8.8.8 Address: 8.8.8.8#53 Aliases: acs.pub.ro has address 141.85.227.151 acs.pub.ro mail is handled by 10 mx.acs.pub.ro.
Now use dig to get the detailed information, the IP address and specific records for a website. Also, use dig to query the Google DNS server 8.8.8.8
/etc/nsswitch.conf
for querying DNS servers and they do not use the system's DNS resolver, which is usually a library. We can see this from the following commands:
root@master:~# strace -e openat host acs.pub.ro [...] openat(AT_FDCWD, "/etc/resolv.conf", O_RDONLY) = 6 acs.pub.ro has address 141.85.227.151 acs.pub.ro mail is handled by 10 mx.acs.pub.ro. [...] root@master:~# strace -e openat ping -c 1 acs.pub.ro [...] openat(AT_FDCWD, "/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 4 openat(AT_FDCWD, "/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 4 openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 4 [...] openat(AT_FDCWD, "/etc/host.conf", O_RDONLY|O_CLOEXEC) = 4 openat(AT_FDCWD, "/etc/hosts", O_RDONLY|O_CLOEXEC) = 4 openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 4 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 4 PING acs.pub.ro (141.85.227.151) 56(84) bytes of data. openat(AT_FDCWD, "/etc/hosts", O_RDONLY|O_CLOEXEC) = 4 64 bytes from acs.pub.ro (141.85.227.151): icmp_seq=1 ttl=62 time=0.688 ms --- acs.pub.ro ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.688/0.688/0.688/0.000 ms
We can see that host will use the /etc/resolv.conf
file directly, while the ping command reads the resolver configuration first: the /etc/nsswitch.conf
and the /etc/resolv.conf
file are opened and then calls are made to the resolving library (libresolv.so.2).
Now that we have seen how we can query DNS servers, let's configure our very own DNS server on the master VM using bind.
root@master:~# apt install bind9 bind9utils
For Debian-based distributions, bind will have the following configuration files:
/etc/bind/named.conf.options
/etc/bind/named.conf.local
/var/cache/bind/
We will set up the master VM to respond to queries about our very own domain. Use <your_last_name>.ro
as your very own domain name. In the following examples we will be using scgc.ro
as our domain.
First, we will configure our DNS server to listen for queries received from outside the server. For this we have to add the following line to the /etc/bind/named.conf.options
file:
options { [...] listen-on { 10.9.107.151; localhost; }; [...] };
root@master:~# ip a [...] 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc pfifo_fast state UP group default qlen 1000 link/ether fa:16:3e:00:7f:98 brd ff:ff:ff:ff:ff:ff inet 10.9.107.151/16 brd 10.9.255.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::f816:3eff:fe00:7f98/64 scope link valid_lft forever preferred_lft forever
Next, we will configure the local file(/etc/bind/named.conf.local
), to specify our DNS zone. Aside from a few comments, the file should be empty.
Add the zone with the following lines (substitute the zone name with your own):
zone "scgc.ro" { type master; file "/etc/bind/db.scgc.ro"; # zone file path };
We will base our zone file on the sample db.local zone file.
cp /etc/bind/db.local /etc/bind/db.scgc.ro
Initially, it will look something like the following: root@master:~# cat /etc/bind/db.scgc.ro
; ; BIND data file for local loopback interface ; $TTL 604800 @ IN SOA localhost. root.localhost. ( 2 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS localhost. ; delete this line @ IN A 127.0.0.1 ; delete this line @ IN AAAA ::1 ; delete this line
First, you will want to edit the SOA record. Replace the “localhost” with your domain name. Also, every time you edit a zone file, you should increment the serial value before you restart the named process–we will increment it to “3”. It should look something like this:
@ IN SOA scgc.ro. root.scgc.ro. ( 3 ; Serial
Now delete the three records at the end of the file (after the SOA record). If you're not sure which lines to delete, they are marked with a “delete this line” comment above.
At the end of the file, add your nameserver record with the following line (replace the name with your own). Note that the second column specifies that these are “NS” records:
; name servers - NS records IN NS ns1.scgc.ro.
Then add the A records for your hosts that belong in this zone. This includes any server whose name we want to end with ”.scgc.ro” (substitute the names and IP addresses). Using our example names and private IP addresses, we will add A records for ns1, and a host corresponding to the www.scgc.ro(which will actually be our master DNS server), like so:
; name servers - A records ns1.scgc.ro. IN A 10.9.107.151 www.scgc.ro. IN A 10.9.107.151
Our final example forward zone file looks like the following:
$TTL 604800 @ IN SOA scgc.ro. root.scgc.ro. ( 3 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; name servers - NS records IN NS ns1.scgc.ro. ; name servers - A records ns1.scgc.ro. IN A 10.9.107.151 www.scgc.ro. IN A 10.9.107.151
Now that we have the a minimal configuration, let us check that it works. Run the following command to check the syntax of the named.conf* files:
root@master:~# named-checkconf
If your named configuration files have no syntax errors, you will return to your shell prompt and see no error messages. If there are problems with your configuration files, review the error message and fix the configuration files.
The named-checkzone command can be used to check the correctness of your zone files. Its first argument specifies a zone name, and the second argument specifies the corresponding zone file, which are both defined in named.conf.local.
For example, to check the “scgc.ro” zone configuration, run the following command (change the names to match your zone and file):
root@master:~# named-checkzone scgc.ro /etc/bind/db.scgc.ro zone scgc.ro/IN: loaded serial 3 OK
When all of your configuration and zone files have no errors in them, you should be ready to restart the BIND service:
root@master:~# service bind9 restart
Now we should be able to test our DNS server. We will be using host, however feel free to use dig or any other command to test your server:
root@master:~# host www.scgc.ro localhost Using domain server: Name: 10.9.107.151 Address: 10.9.107.151#53 Aliases: www.scgc.ro has address 10.9.107.151 root@master:~# host -t ns scgc.ro localhost Using domain server: Name: 10.9.107.151 Address: 10.9.107.151#53 Aliases: scgc.ro name server ns1.scgc.ro. root@master:~# host ns1.scgc.ro localhost Using domain server: Name: 10.9.107.151 Address: 10.9.107.151#53 Aliases: ns1.scgc.ro has address 10.9.107.151
Now let's try to query from outside the server. We will test that the slave VM will receive the same response(replace with the appropriate name and IP address):
[root@slave ~]# host www.scgc.ro master Using domain server: Name: 10.9.107.151 Address: 10.9.107.151#53 Aliases: www.scgc.ro has address 10.9.107.151
yum install bind-utils
Add another NS record to the zone corresponding to the slave IP address and two MX records(one for the master with priority 10 and one for the slave with priority 20). Restart your BIND server and test your configurations.
By default, bind will make recursive queries for any unknown query received. Recursive queries are quite costly, therefore they should only be allowed explicitly. We can check this by quering for google.com
from the master and slave VMs:
root@master:~# host google.com localhost Using domain server: Name: 10.9.107.151 Address: 10.9.107.151#53 Aliases: google.com has address 216.58.214.206 google.com has IPv6 address 2a00:1450:400d:802::200e google.com mail is handled by 40 alt3.aspmx.l.google.com. google.com mail is handled by 50 alt4.aspmx.l.google.com. google.com mail is handled by 30 alt2.aspmx.l.google.com. google.com mail is handled by 10 aspmx.l.google.com. google.com mail is handled by 20 alt1.aspmx.l.google.com. [root@slave ~]# host google.com master Using domain server: Name: 10.9.107.151 Address: 10.9.107.151#53 Aliases: google.com has address 216.58.214.206 google.com has IPv6 address 2a00:1450:400d:802::200e google.com mail is handled by 10 aspmx.l.google.com. google.com mail is handled by 30 alt2.aspmx.l.google.com. google.com mail is handled by 20 alt1.aspmx.l.google.com. google.com mail is handled by 40 alt3.aspmx.l.google.com. google.com mail is handled by 50 alt4.aspmx.l.google.com.
In order to restrict who can make recursive queries, we have to edit the /etc/bind/named.conf.options
file and add the following lines:
acl goodguys { 10.9.107.151; 127.0.0.1; }; options { [...] allow-recursion { goodguys; }; recursion yes; [...] };
Now, if we query again for google.com
, from the master VM the query should suceed and from the slave VM it should now fail.
[root@slave ~]# host google.com master Using domain server: Name: 10.9.107.151 Address: 10.9.107.151#53 Aliases: Host google.com.cloud.grid.pub.ro not found: 5(REFUSED)
Change the /etc/bind/named.conf.options file
on the master VM to allow recursive queries from the slave VM.
We now want to configure the lab1.scgc.ro
on the slave DNS server(replace with your last name instead of scgc). This domain will be transfered from the master to the slave(DNS zone transfer). In order to correctly configure a zone transfer, we must follow these steps:
lab1.scgc.ro
lab1.scgc.ro
domain from the master VM to the slave VM
Configure a new DNS zone on the master VM similarly to the previous one, which will answer for queries about lab1.scgc.ro
. Your DNS zone must have at least an A record and a NS record for this exercise.
The slave VM has a Centos 7 operating system, which has some differences in the setup of the DNS server.
To install BIND use the following command:
yum install bind
On Red-Hat-based distributions bind will have the following characteristics:
In order to transfer the zone from the master server, we need to make the following configurations:
/etc/bind/named.conf.local
file for the zone created in the preceding subtask (4.1):allow-transfer { 10.9.107.152; }; // replace with the slave VM IP address
zone "lab1.scgc.ro." { type slave; file "/var/named/slaves/db.lab1.scgc.ro"; //the zone file masters { 10.9.107.151; }; //replace with the master VM IP address };
After making these configurations restart both servers.
systemctl restart named.service
To check that everything went well you can check the status on the slave VM:
[root@slave ~]# systemctl status named.service named.service - Berkeley Internet Name Domain (DNS) Loaded: loaded (/usr/lib/systemd/system/named.service; disabled) Active: active (running) since Ma 2018-02-27 14:20:06 UTC; 15min ago Process: 20538 ExecStop=/bin/sh -c /usr/sbin/rndc stop > /dev/null 2>&1 || /bin/kill -TERM $MAINPID (code=exited, status=0/SUCCESS) Process: 20500 ExecReload=/bin/sh -c /usr/sbin/rndc reload > /dev/null 2>&1 || /bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS) Process: 20549 ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} $OPTIONS (code=exited, status=0/SUCCESS) Process: 20547 ExecStartPre=/bin/bash -c if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi (code=exited, status=0/SUCCESS) Main PID: 20552 (named) CGroup: /system.slice/named.service └─20552 /usr/sbin/named -u named -c /etc/named.conf feb 27 14:20:06 slave named[20552]: zone localhost/IN: loaded serial 0 feb 27 14:20:06 slave named[20552]: zone 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/IN: loaded serial 0 feb 27 14:20:06 slave named[20552]: all zones loaded feb 27 14:20:06 slave named[20552]: running feb 27 14:20:06 slave systemd[1]: Started Berkeley Internet Name Domain (DNS). feb 27 14:20:06 slave named[20552]: zone lab1.scgc.ro/IN: Transfer started. feb 27 14:20:06 slave named[20552]: transfer of 'lab1.scgc.ro/IN' from 10.9.107.151#53: connected using 10.9.107.152#57942 feb 27 14:20:06 slave named[20552]: zone lab1.scgc.ro/IN: transferred serial 3 feb 27 14:20:06 slave named[20552]: transfer of 'lab1.scgc.ro/IN' from 10.9.107.151#53: Transfer completed: 1 messages, 5 records, 156 bytes, 0.001 secs (156000 bytes/sec) feb 27 14:20:06 slave named[20552]: zone lab1.scgc.ro/IN: sending notifies (serial 3)
To test that the zone has indeed been transferred you can now query the slave server for the zone which was transferred.
[root@slave ~]# host -v lab1.scgc.ro localhost Trying "lab1.scgc.ro" Using domain server: Name: localhost Address: ::1#53 Aliases: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60555 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1 ;; QUESTION SECTION: ;lab1.scgc.ro. IN A ;; ANSWER SECTION: lab1.scgc.ro. 604800 IN A 10.9.107.151 ;; AUTHORITY SECTION: lab1.scgc.ro. 604800 IN NS ns.lab1.scgc.ro. ;; ADDITIONAL SECTION: ns.lab1.scgc.ro. 604800 IN A 10.9.107.151 Received 79 bytes from ::1#53 in 1 ms Trying "lab1.scgc.ro" ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5264 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;lab1.scgc.ro. IN AAAA ;; AUTHORITY SECTION: lab1.scgc.ro. 604800 IN SOA lab1.scgc.ro. root.scgc.ro. 3 604800 86400 2419200 604800 Received 71 bytes from ::1#53 in 0 ms Trying "lab1.scgc.ro" ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24490 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;lab1.scgc.ro. IN MX ;; AUTHORITY SECTION: lab1.scgc.ro. 604800 IN SOA lab1.scgc.ro. root.scgc.ro. 3 604800 86400 2419200 604800 Received 71 bytes from ::1#53 in 0 ms
The command has to produce similar output when run on the master VM.
Pair up with one of your peers. Each student will make the necessary changes in order for his master DNS server to be delegated the DNS zone of his colleague's master DNS server. You should be able to answer for queries about each others DNS domains.
DNS is vulnerable to MITM attacks. An attacker can pretend to be a DNS server and supply an unsuspecting victim with the wrong IP address for a URL. In order to combat this, DNSSEC can be used and configured to validate the identity of the DNS server. Using the instructions from here, setup DNSSEC between the master and slave VM.