Skip to main content

Name services

Setup

We will be using a virtual machine in the faculty's cloud.

When creating a virtual machine in the Launch Instance window:

  • Name your VM using the following convention: scgc_lab<no>_<username>, where <no> is the lab number and <username> is your institutional account.
  • Select Boot from image in Instance Boot Source section
  • Select SCGC Template in Image Name section
  • Select the m1.large flavor.

In the base virtual machine:

  • Download the laboratory archive from here in the work directory. Use: wget https://repository.grid.pub.ro/cs/scgc/laboratoare/lab-dns.zip to download the archive.

  • Extract the archive. The .qcow2 files will be used to start virtual machines using the runvm.sh script.

  • Start the virtual machines using bash runvm.sh.

  • The username for connecting to the nested VMs is student and the password is student.

  • For ease of use we recommend adding entries in the /etc/hosts file corresponding to the two VMs:

    • 192.168.100.11 dns
    • 192.168.100.12 helper
    • These two lines will allow using dns instead of the IP address of the DNS VM for clarity. Likewise, we can use helper instead of the IP address of the helper VM.

DNS Resolvers

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.

root@dns:~# apt update
[...]
root@dns:~# apt install host dnsutils
[...]

host

Next, we find out the IP address of a website using host.

root@dns:~# 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@dns:~# 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@dns:~# 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@dns:~# host -t mx acs.pub.ro
acs.pub.ro mail is handled by 10 mx.acs.pub.ro.
root@dns:~# 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@dns:~# 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.

dig

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.

important

It is noteworthy, that dig and host do not use /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@dns:~# 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@dns:~# 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).

DNS Servers

Now that we have seen how we can query DNS servers, let's configure our very own DNS server on the dns VM using bind.

root@dns:~# apt install bind9 bind9utils

For Debian-based distributions, bind will have the following configuration files:

  • Main configuration file: /etc/bind/named.conf.options.
  • Zone names file: /etc/bind/named.conf.local.
  • Default zone file location: /var/cache/bind/.

We will set up the dns VM to respond to queries about our very own domain. Use <your_last_name>.scgc.ro as your very own domain name. In the following examples we will be using scgc.ro as our domain.

Simple DNS configuration

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 {
[...]
dnssec-validation no;
[...]
listen-on { 192.168.100.11; localhost; };
[...]
};
caution

Most services do not have automatic configuration reloads. Make sure to restart the DNS service whenever you make a change in the configuration files.

note

The IP address 192.168.100.11, used in the example may not be the IP address that you will use when configuring your server. Replace it with your own IP address, which can be determined by using the ip command:

root@dns:~# 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 192.168.100.11/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@dns:~# 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, like so:

; name servers - A records
ns1.scgc.ro. IN A 192.168.100.11
www.scgc.ro. IN A 192.168.100.11

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 192.168.100.11
www.scgc.ro. IN A 192.168.100.11

Testing our configuration

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@dns:~# 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@dns:~# 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@dns:~# 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@dns:~# host www.scgc.ro localhost
Using domain server:
Name: 192.168.100.11
Address: 192.168.100.11#53
Aliases:

www.scgc.ro has address 192.168.100.11
root@dns:~# host -t ns scgc.ro localhost
Using domain server:
Name: 192.168.100.11
Address: 192.168.100.11#53
Aliases:

scgc.ro name server ns1.scgc.ro.
root@dns:~# host ns1.scgc.ro localhost
Using domain server:
Name: 192.168.100.11
Address: 192.168.100.11#53
Aliases:

ns1.scgc.ro has address 192.168.100.11

Now let's try to query from outside the server. We will test that the helper VM will receive the same response(replace with the appropriate name and IP address):

[root@helper ~]# host www.scgc.ro dns
Using domain server:
Name: 192.168.100.11
Address: 192.168.100.11#53
Aliases:

www.scgc.ro has address 192.168.100.11
note

To install host, dig, nslookup on Alma Linux 8, run the following command:

sudo dnf install bind-utils

Additional records

Add another NS record to the zone corresponding to another IP address and two MX records (one for the dns server with priority 10 and one for the helper server with priority 20).

note

See here how to configure MX records.

Restart your BIND server and test your configurations.

DNS Fine Tuning

Allow only local recursive queries

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 dns and helper VMs:

root@dns:~# host google.com localhost
Using domain server:
Name: localhost
Address: ::1#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@helper ~]# host google.com dns
Using domain server:
Name: 192.168.100.11
Address: 192.168.100.11#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 { 192.168.100.11; 127.0.0.1; ::1; };

options {
[...]
allow-recursion { goodguys; };
recursion yes;
[...]
};

Do not forget to restart the BIND service after changing the configuration.

Now, if we query again for google.com, from the dns VM the query should suceed and from the helper VM it should now fail.

[root@helper ~]# host google.com dns
Using domain server:
Name: 192.168.100.11
Address: 192.168.100.11#53
Aliases:

Host google.com.cloud.grid.pub.ro not found: 5(REFUSED)

Allow recursive queries from a specific host

Change the /etc/bind/named.conf.options file on the dns VM to allow recursive queries from the helper VM.

DNS Zone Transfer

We now want to configure the lab.scgc.ro on the helper server that will work as a slave DNS server (replace with your last name instead of scgc). This domain will be transfered from the master (dns VM) to the slave (helper VM) (DNS zone transfer). In order to correctly configure a zone transfer, we must follow these steps:

  • We setup a new DNS domain on the master VM for lab.scgc.ro.
  • We install a DNS server on the helper VM.
  • We transfer the lab.scgc.ro domain from the dns VM to the helper VM.

Setup master DNS server

Configure a new DNS zone on the dns VM similarly to the previous one, which will answer for queries about lab.scgc.ro. Your DNS zone must have at least an A record and a NS record for this exercise.

Zone transfer

The helper VM has a Alma Linux 8 operating system, which has some differences in the setup of the DNS server.

To install BIND use the following command:

[student@helper ~]$ sudo dnf install bind

On Red-Hat-based distributions bind will have the following characteristics:

  • Service name: named.
  • Main configuration and zone names file: /etc/named.conf.
  • Default zone file location: /var/named.

In order to transfer the zone from the master DNS server, we need to make the following configurations:

  • on the dns VM add the following line in the /etc/bind/named.conf.local file for the zone created in the preceding subtask:
    allow-transfer { 192.168.100.12; }; // replace with the slave VM IP address
  • on the helper VM
zone "lab.scgc.ro." {
type slave;
file "/var/named/slaves/db.lab.scgc.ro"; //the zone file
masters { 192.168.100.11; }; //replace with the master VM IP address
};
important

Do not create the zone file. This file will be created by bind when the zone will be transferred.

After making these configurations restart both servers.

note

To restart the named service on Alma Linux, use the following command:

[root@helper ~]# systemctl restart named.service

To check that everything went well you can check the status on the helper VM:

[root@helper ~]# 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 lab.scgc.ro/IN: Transfer started.
feb 27 14:20:06 slave named[20552]: transfer of 'lab.scgc.ro/IN' from 192.168.100.11#53: connected using 192.168.100.12#57942
feb 27 14:20:06 slave named[20552]: zone lab.scgc.ro/IN: transferred serial 3
feb 27 14:20:06 slave named[20552]: transfer of 'lab.scgc.ro/IN' from 192.168.100.11#53: Transfer completed: 1 messages, 5 records, 156 bytes, 0.001 secs (156000 bytes/sec)
feb 27 14:20:06 slave named[20552]: zone lab.scgc.ro/IN: sending notifies (serial 3)

To test that the zone has indeed been transferred you can now query the helper server for the zone which was transferred.

[root@helper ~]# host -v lab.scgc.ro localhost
Trying "lab.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:
;lab.scgc.ro. IN A

;; ANSWER SECTION:
lab.scgc.ro. 604800 IN A 192.168.100.11

;; AUTHORITY SECTION:
lab.scgc.ro. 604800 IN NS ns.lab.scgc.ro.

;; ADDITIONAL SECTION:
ns.lab.scgc.ro. 604800 IN A 192.168.100.11

Received 79 bytes from ::1#53 in 1 ms
Trying "lab.scgc.ro"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5264
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;lab.scgc.ro. IN AAAA

;; AUTHORITY SECTION:
lab.scgc.ro. 604800 IN SOA lab.scgc.ro. root.scgc.ro. 3 604800 86400 2419200 604800

Received 71 bytes from ::1#53 in 0 ms
Trying "lab.scgc.ro"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24490
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;lab.scgc.ro. IN MX

;; AUTHORITY SECTION:
lab.scgc.ro. 604800 IN SOA lab.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 dns VM.

Paired DNS zone transfer

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.

DNSSEC

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 dns and helper VM.