Arvutiteaduse instituut
  1. Kursused
  2. 2019/20 kevad
  3. Süsteemihaldus (LTAT.06.003)
EN
Logi sisse

Süsteemihaldus 2019/20 kevad

  • Home
  • Practicals
  • Exam
  • Grades?
  • References

0. Overview of Lab 4 : Welcome to 4th lab. Here the short action list we will do in this lab:

  1. Verifying previous lab tasks
  2. Installing updates
  3. Performing backup
  4. Installing Domain Name Server
  5. Configuring own local resolver server (allowing recursion and caching)
  6. Configuring own domain zone, understanding world and local resolvers

1.Make sure you did finish all the tasks of the previous week.

PS! Before continuing please make sure you have completed all previous labs.

  1. Access to ETAIS was granted and you can login with your UT credentials.
  2. VM was created and is visible in the list of VMs in ETAIS
  3. VM is reachable on External IP (from UT eduroam Wi-Fi, class 2005 PC or UT VPN)
  4. VM has SSH service running and you can login into VM using SSH private key
  5. VM has scoring account created, scoring can login using his SSH private key.
  6. Everything on scoring.sa.cs.ut.ee is green
  7. You have set a root password for your VM.

Additionally - Securing your ssh server

One thing that makes SSH server more secure is disabling password authentication. We disable it since we use our private key to log in and we disable password login, because people often use bad (easy to quess) passwords. We want to eliminate that risk and since we use key, we disable it.

  • Open and edit the file /etc/ssh/sshd_config
    • Change the value of PasswordAuthentication to no.

2. Check for the updates using CentOS package manager

We have worked with package manager yum and/or dnf during Lab1 (installing the system). Moreover, in the Lab3 we did upgrade packages, therefore the exact commands we expect you to know.

  • Update the package index
  • Check if any updates are available
  • Perform the upgrade if needed
  • Reboot the VM in case Linux Kernel or Initial RAM-fs was upgraded
    • This will be visible from the upgrade logs
    • Alternatively you can list the /boot directory to check if any files were updated recently
      • Consider the ls command, please have a look at options -l, -t, -r and -h (those might be helpful to produce detailed, time-ordered output)

We can count the system up-to-date if there is no more updates suggested by the package manager

  • In case you performed a reboot, make sure the VM booted and is back on-line and you can ssh into it.

After upgrading the system, it is wise to clean the left-overs: the downloaded rpm packages. Moreover it is wise to remove the packages that are not used anymore. The are two commands responsible for performing these actions:

# Uninstall the not used packages
yum autoremove -y
yum clean all

Perform the cleaning and remove not used packages

3. Perform backup

We are about to introduce some portion of changes to our system during this lab, therefore it is wise to backup the current state first. Pay attention that one of the changes we do is the Firewall configurations, mistake in firewall syntax or wrong order of the rules in firewall chains might result in locking the network access (deny-all rule). Once network access is lost - you can't control your VM anymore over SSH. There is a recovery console, but that only works if you have set a root user password. The ETAIS infrastructure does allows to perform the snapshots of the hard-drives. By doing the snapshot you literally saving the state of the whole hard drive up to date. Once the snapshot is done you can proceed with dangerous actions knowing that you can always recover to last lab's state in case you misconfigure something.

In ETAIS interface issue the snapshot of the hard-drive

  • ETAIS -> Resources -> VMs -> Your VM -> Backup Tab -> Create

4. Open UDP port 53 for the lab

From this lab onward we need UDP port 53 to be open for our VMs, so that we could build a working DNS solution. To do that, follow these steps:

  • Go to ETAIS -> Resources -> VMs -> Your VM -> Manage security groups -> Create -> Name: DNS (Description: allowing UDP port 53 for DNS) -> Submit -> Actions (for the newly created DNS security group) -> Set rules -> Add rule -> IP protocol (Choose: UDP) -> From port (Choose: 53) -> To port (Choose: 53) -> Submit.

Now the security group has been created. We should add it to our machine also.

  • Go to ETAIS -> Resources -> VMs -> Actions -> Update Security groups -> Add the newly created Security Group DNS to the list of Security Groups -> Submit

5. Disable IPv6

The ETAIS cloud does not suggest any IPv6 network providers, therefore is is pointless to keep the IPv6 stack up in our VMs. In this section we are going to disable the IPv6 stack by alternating kernel runtime parameters.

System wide configuration variables are managed using sysctl utility. Example:

  • To print the whole list of system settings use:
    • # sysctl -A
  • To see specific variable value:
    • # sysctl variableName
  • To set a specific variable to a new value use:
    • # sysctl <variable>=<value>

This will however change only running system setting and will reset to default values after system restart. In order to alter the default values put the corresponding variables in the end of /etc/sysctl.conf file, example content of /etc/sysctl.conf (only few last lines shown):

...

 # My default value of aa.bb.cc_var1 variable
 # NB! This is an example, do not use this!
 aa.bb.cc_var1=1

...

During this Lab we do not configure any service to rely on IPv6 hence we do not need the system wide IPv6 stack. Let's disable it using well studied sysctl utility.

Disable the use of IPv6:

  • Check the value of the following variables:
    • net.ipv6.conf.default.disable_ipv6
    • net.ipv6.conf.all.disable_ipv6
  • Change current system config using sysctl command, set the value of both variables to 1
  • Create the /etc/sysctl.d/70-ipv6.conf file, add the abovementioned variables. Save and close the file file.

Afterwards enter

  • sysctl --load /etc/sysctl.d/70-ipv6.conf

Now if you check your network interfaces using ip addr l command, there should be no inet6 prefixed lines.

  • $ ip addr l

And if you still see inet6 lines in the output, there is something you may have missed in the previous manual.

6. Domain Name System (DNS) using BIND software

DNS (Domain Name Service) is the main name service used in the Internet. Domain name services are used to translate names meaningful to humans into the numerical/binary addresses/numbers (and vice versa). Practically every system relies on a working domain name service. The domain name service has not always to be set up in-house, most often it is provided by the Internet Service Provider (ISP).

Extra materials

  • Wikipedia: Domain Name System
  • DNS for Rocket Scientists
  • BIND 9 Administrator Reference Manual
  • Just a Good BIND9 Manual

Domain Hierarchy for System Administration Labs

For our practicals we will use our own domain hierarchy starting from the top level domains. DNS management is based on strict delegation, so we are unable to introduce our "fake" top level domains into the "real" DNS system used in the Internet.

The domain hierarchy is divided into zones based on authority:

  • The authority over root domain and top level domains will belong to the teaching staff. We will be using top level domain .sa.cs.ut.ee.
  • Every participant/system will have authority over a second-level domain vm_name.sa.cs.ut.ee, under which one or more names may be defined. "vm_name" refers to the name to the machine you've set inside minu.etais.ee. It is mandatory to have a name for every host/sub system in the lab group under each of these second-level domains.
  • The general form for these names is <service>.vm_name.sa.cs.ut.ee Here "<service>" refers to any services we will be setting up in the future.

For example:

  • If student John Doe has his UT study number book B12345 and his VM was named B12345 then full hostname is B12345.sa.cs.ut.ee. If you've named your VM something else, use that name.

Changing hostname

By default all the centos instances are set by ETAIS during VM setup as a host name. During this lab we are going to setup a personal DNS server (serving personal domain <vm_name>.sa.cs.ut.ee). Our VM will join the domain by name <vm_name>.sa.cs.ut.ee. Therefore next we prepare VM by alternating its host name from short notation to full qualified domain notation, Example for B12345 in B12345.sa.cs.ut.ee domain:

* short notation: B12345
* fqdn notation: B12345.sa.cs.ut.ee

To check your current host name consider command hostname ...

  • $ hostname
 ...  and its output is exactly the host name in short notation:
myhost

The host name is held in file /etc/hostname, by altering the single line in this file you will alter the name of your host. In addition there is a /etc/hosts file, which provides fixed host name <-> ip address mappings, and has the following content (only lines we are interested in are shown):

 ...
  • 127.0.0.1 localhost
  • 127.0.1.1 myhost.novalocal myhost
 ... 

The shown mappings allows local resolving of host names to IP address (without any requests to external services like DNS). This especially critical when testing your services locally, if you consider the simple command, like:

  • $ ping localhost
 ... this will actually resolve localhost to  127.0.0.1 using /etc/hosts file.

We need to add another line in /etc/hosts associating your current hostname to 127.0.1.1, in case we change our domain we need to modify this line. Example:

  • my short host name is myhost, and my new domain is .sa.cs.ut.ee, so the full domain name myhost.sa.cs.ut.ee
  • the line to be added should look something like this:
    • 127.0.1.1 myhost.novalocal myhost myhost.sa.cs.ut.ee

Now change your host name as described above, using pattern <vm_name>.sa.cs.ut.ee for the new value. You can do it by editing files:

  • /etc/hostname
    • change the default hostname to your full hostname <vm_name>.sa.cs.ut.ee
      • <vm_name> - your current hostname in short notation ( a result of hostname command)
  • /etc/hosts
    • Add the line
      • 127.0.1.1 <vm_name>.sa.cs.ut.ee <vm_name>

NOW reboot your instance to apply changes

  • The logon screen must display the same hostname
  • When logged in, use the following command to display the hostname:
    • $ hostname --long
      • It should report you hostname in FQDN (<vm_name>.sa.cs.ut.ee)
  • Try to ping yourself using your new hostname

7. Configuring the BIND Name Server

First install the Bind 9 DNS server related packages.

Install packages:

  • bind
  • bind-utils

Let's make sure the DNS service can operate with CentOS firewall turned on.

  • firewall-cmd --add-service=dns --permanent
  • firewall-cmd --add-port=8301/udp --permanent
  • firewall-cmd --add-port=8301/tcp --permanent
  • firewall-cmd --reload

The output of previous commands should be success.

Both firewall-cmd commands should report on a new line: success

Now lets create a directory for logging and necessary files within that directory, that will be populated by the logging confiuration that will be added later in this lab.

  • Create directory log into /var/named.
  • Change the owner (user and group) of the directory to named.
  • Create file default into /var/named/log.
  • Change its owner (user and group) to named.
  • Create file auth_servers into /var/named/log.
  • Change its owner (user and group) to named.
  • Create file zone_transfers into /var/named/log.
  • Change its owner (user and group) to named.
  • Create file client_security into /var/named/log.
  • Change its owner (user and group) to named.
  • Create file queries into /var/named/log.
  • Change its owner (user and group) to named.
  • Create file query-errors into /var/named/log.
  • Change its owner (user and group) to named.

As the BIND name server runs with the rights of the root user and group named (not root), you should always make sure that the main configuration file and zone files have the correct permissions and group ownership. Every file to be read by the BIND DNS server must be readable by named group. If you get "permission denied" errors, use the following commands to set the owner or group ownership, example:

  • # chown root:named /etc/targetConfFile.conf

and following commands to set the correct permissions: (Learn More)

  • # chmod 640 /etc/targetConfFile.conf
    • Will set rights rw- r-- ---
  • # chmod g+rX /etc/targetConfFile.conf
    • Will just set read right for the group
  • Use chown to change owner/group. Use ls -la to check permissions/owner/group.

The main configuration file for BIND is :

  • /etc/named.conf <-- Main configuration file - bind options, logging options, zones. This could be split into smaller segments if necessary, but means you would have to specify the include statement in the main configuration file.

Lets start configuring the DNS server by adding proper logging configuration. Replace the default logging options in the named.conf with the following:

logging {
     channel default_log {
          file "/var/named/log/default" versions 3 size 20m;
          print-time yes;
          print-category yes;
          print-severity yes;
          severity info;
     };
     channel auth_servers_log {
          file "/var/named/log/auth_servers" versions 100 size 20m;
          print-time yes;
          print-category yes;
          print-severity yes;
          severity info;
     };
     channel zone_transfers_log {
          file "/var/named/log/zone_transfers" versions 3 size 20m;
          print-time yes;
          print-category yes;
          print-severity yes;
          severity info;
     };
     channel client_security_log {
          file "/var/named/log/client_security" versions 3 size 20m;
          print-time yes;
          print-category yes;
          print-severity yes;
          severity info;
     };
//
// If you have the category ‘queries’ defined, and you don’t want query logging
// by default, make sure you add option ‘querylog no;’ - then you can toggle
// query logging on (and off again) using command ‘rndc querylog’
//
     channel queries_log {
          file "/var/named/log/queries" versions 600 size 20m;
          print-time yes;
          print-category yes;
          print-severity yes;
          severity info;
     };
//
// This channel is dynamic so that when the debug level is increased using
// rndc while the server is running, extra information will be logged about
// failing queries.  Other debug information for other categories will be
// sent to the channel default_debug (which is also dynamic), but without
// affecting the regular logging.
//
     channel query-errors_log {
          file "/var/named/log/query-errors" versions 5 size 20m;
          print-time yes;
          print-category yes;
          print-severity yes;
          severity dynamic;
     };
//
// This is the default syslog channel, defined here for clarity.  You don’t
// have to use it if you prefer to log to your own channels.
// It sends to syslog’s daemon facility, and sends only logged messages
// of priority info and higher.
// (The options to print time, category and severity are non-default.)
//
     channel default_syslog {
          print-time yes;
          print-category yes;
          print-severity yes;
          syslog daemon;
          severity info;
     };
//
// This is the default debug output channel, defined here for clarity.  You
// might want to redefine the output destination if it doesn’t fit with your
// local system administration plans for logging.  It is also a special
// channel that only produces output if the debug level is non-zero.
//
     channel default_debug {
          print-time yes;
          print-category yes;
          print-severity yes;
          file "named.run";
          severity dynamic;
     };
//
// Log routine stuff to syslog and default log:
//
     category default { default_syslog; default_debug; default_log; };
     category config { default_syslog; default_debug; default_log; };
     category dispatch { default_syslog; default_debug; default_log; };
     category network { default_syslog; default_debug; default_log; };
     category general { default_syslog; default_debug; default_log; };
//
// Log messages relating to what we got back from authoritative servers during
// recursion (if lame-servers and edns-disabled are obscuring other messages
// they can be sent to their own channel or to null).  Sometimes these log
// messages will be useful to research why some domains don’t resolve or
// don’t resolve reliably
//
     category resolver { auth_servers_log; default_debug; };
     category cname { auth_servers_log; default_debug; };
     category delegation-only { auth_servers_log; default_debug; };
//
// Log together all messages relating to authoritative zone propagation
//
     category notify { zone_transfers_log; default_debug; };
     category xfer-in { zone_transfers_log; default_debug; };
     category xfer-out { zone_transfers_log; default_debug; };
//
// Log together all messages relating to client access and security.
// (There is an additional category ‘unmatched’ that is by default sent to
// null but which can be added here if you want more than the one-line
// summary that is logged for failures to match a view).
//
     category client{ client_security_log; default_debug; };
     category security { client_security_log; default_debug; };
//
// If you have the category ‘queries’ defined, and you don’t want query logging
// by default, make sure you add option ‘querylog no;’ - then you can toggle
// query logging on (and off again) using command ‘rndc querylog’
//
     category queries { queries_log; };
//
// This logging category will only emit messages at debug levels of 1 or
// higher - it can be useful to troubleshoot problems where queries are
// resulting in a SERVFAIL response.
//
     category query-errors {query-errors_log; };
};

Now we add the simple caching DNS configuration to our bind server. This in order to get rid of the forwarding the DNS resolv queries to 10.10.10.1. Having the caching DNS server running locally on the same host will to the trick. Instead of forwarding the queries to 10.10.10.1 we will use our own resolver on 127.0.0.1 which has recursive resolving (and also caching) enabled.
Edit the options file named.conf:

Now find the options { ... } declaration in options file and make sure the following lines are there:

listen-on port 53 { any; };
listen-on-v6 port 53 { none; };
...
allow-query     { any; };
...
recursion yes;
...
dnssec-enable no;
dnssec-validation no;

Regarding the previous configuration, we first of all declare, that only anyone should be allowed to send resolve queries to our bind@ server, by having allow-query { any; };@@ defined as such. Secondly, we disable queries from IPv6, which we have disabled previously anyway. In addition we increase the scope of IPv4 by putting bind listen on all interfaces' port 53 listen-on port 53 { any; }; Then we enable recursion, and finally turn off dnssec.

The recursion is needed in order to let bind act as standard caching recursive resolver (like those assigned by DHCP or put manually in /etc/resolv.conf).

  • Example query "where is courses.cs.ut.ee" is then resolved as follows:
    • "where is .ee"
    • "where is ut.ee"
    • "where is cs.ut.ee"
    • "where is courses.cs.ut.ee"
  • The often made queries are cached and answered explicitly

Now you can check your configuration using named-checkconf utility

  • # named-checkconf

No output means configuration is OK.

Start the name server (service named):

  • # service named start (use service named stop if you already started it before)

Now query the service status and if needed, check the log files (those we have created in the beginning)

  • # service named status
  • # systemctl status named
  • # journalctl -xn

If everything works fine and no error is reported, you may check how your local resolver is performing:

  • $ dig @127.0.0.1 courses.cs.ut.ee
  • $ dig @127.0.0.1 www.google.com

If you have an error related to permissions to /var/named/log/default , please run the following command:

  • restorecon -Rv /var/named

This command relabels the security of that folder, allowing Bind to write there properly. Now systemctl start named should work properly.

It should answer with list of IP addresse for courses.cs.ut.ee like this:

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el8 <<>> @127.0.0.1 courses.cs.ut.ee
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53403
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 2, ADDITIONAL: 4

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 4d3b69aaf5aa48ca539139635e63c827c5801f3d6572b073 (good)
;; QUESTION SECTION:
;courses.cs.ut.ee.		IN	A

;; ANSWER SECTION:
courses.cs.ut.ee.	4320	IN	CNAME	web.cs.ut.ee.
web.cs.ut.ee.		4320	IN	A	193.40.36.57
web.cs.ut.ee.		4320	IN	A	193.40.36.55

;; AUTHORITY SECTION:
cs.ut.ee.		4320	IN	NS	ns2.ut.ee.
cs.ut.ee.		4320	IN	NS	ns.ut.ee.

;; ADDITIONAL SECTION:
ns2.ut.ee.		10800	IN	A	193.40.5.76
ns.ut.ee.		10800	IN	A	193.40.5.99
ns2.ut.ee.		10800	IN	AAAA	2001:bb8:2002:500::76

;; Query time: 23 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Mar 07 18:13:27 EET 2020
;; MSG SIZE  rcvd: 218

If you get answer like this for courses.cs.ut.ee then local resolver is performing well. You may want to enable it for auto-starting at the boot time:

Enable auto-starting the named:

  • # systemctl enable named

The /etc/resolv.conf will not be rewritten by DHCP client (next time we reboot) and stays static. So we can safely edit it to rely on your own local resolver for doing DNS queries by replacing the namesever variable value with 127.0.0.1

Edit /etc/resolv.conf

  • Change nameserver option to 127.0.0.1
    • in case you have multiple - you should leave just one
  • Change search option to your personal domain <vm_name>.sa.cs.ut.ee

'''Reboot the VM. After rebooting make sure the /etc/resolv.conf is not modified (you should see your configuration there and nothing should be changed).

Now your local resolver is used system wide, so you can test it by just pinging some hosts by name:

  • $ ping www.google.com

Should resolve www.google.com and start pinging it.

Creating a Personal Domain for named

PS! Before continuing please make sure you have completed all of the previous steps.

This means your Virtual Machine is in System Administration course cluster and accessible over SSH and VPN connection.

  1. /etc/hostname file has your hostname in FQDN format <host>.sa.cs.ut.ee
    • <host> refers the host name of your VM that was chosen chosen during VM setup dialog in ETAIS web interface
  2. You can access your Virtual Machine over SSH with Putty or any other SSH client
  3. You can access your Virtual Machine with an SSH key over SSH
  4. Service bind is running and enabled systemctl status named.service -l
  5. Local DNS resolver is capable of resolving world addresses
    • dig @127.0.0.1 www.ut.ee
    • dig @127.0.0.1 www.google.com
  6. /etc/resolv.conf has a line nameserver 127.0.0.1
    • /etc/resolv.conf is not getting rewritten after next reboot
  7. The OS can use the local DNS resolver to resolve any DNS host name
    • nslookup www.ut.ee
    • nslookup www.google.com

Adding zone definition to the local resolver

Creating a new zone is a two step process:

  • First, the records for the zone must be entered into the zone file
  • Second, the zone must be described/declared in the /etc/named.conf file.

Understanding the zone record files

The typical Zone file contains information about associations between host names and IP addresses within the domain of responsibility. The records inside the Zone file can be of different types:

  • SOA - Start of Authority. Defines the zone name, an e-mail contact and various time and refresh values applicable to the zone.
  • A - IPv4 Address record. An IPv4 address for a host.
  • AAAA - IPv6 Address record. An IPv6 address for a host. Current IETF recommendation for IPv6 forward-mapped zones.
  • NS - Name Server. Defines the authoritative name server(s) for the domain (defined by the SOA record) or the sub-domain.
  • MX - Mail Exchange. A preference value and the host name for a mail server/exchange that will service this zone. RFC 974 defines valid names.
  • PTR - IP address (IPv4 or IPv6) to host. Used in reverse maps.
  • CNAME - Canonical Name. An alias name for a host. Causes redirection for a single RR at the owner-name.

More details about record types you can find here.

Example Zone file content looks as follows:

NB! In Zone file ; denotes comments in configuration

;
; Zone file for domain-example.org
$ORIGIN domain-example.org.  ; Zone starting point in the name-space tree
                     ; (if skipped - the origin is inferred by the DNS server based on
                     ; zone declaration in name.conf.local file
$TTL 15M             ; Default expiration time for all resources
@ IN SOA ns.domain-example.org. root.domain-example.org.(
	 2012020101       ; Serial
		15M       ; Refresh (15 minutes)
		5M        ; Retry (5 minutes)
		604800    ; Expire (7 days in seconds)
		600 )     ; Negative Cache TTL
@       IN      NS      ns            ; name server for domain-example.org
@       IN      A       172.17.6.1    ; IPv4 address for domain-example.org
ns      IN      A       172.17.6.1    ; IPv4 address for ns.domain-example.org
@       IN      MX  10  mail          ; mail server for domain-example.org
myhost  IN      A       172.17.6.5    ; IPv4 address for myhost.domain-example.org
mail    IN      A       172.17.6.6    ; IPv4 address for mail.domain-example.org
myhost2 IN      A       172.17.6.7    ; IPv4 address for myhost2.domain-example.org
www     IN      CNAME   myhost        ; www is an alias for myhost in domain-example.org
ftp     IN      CNAME   myhost        ; ftp is an alias for myhost in domain-example.org
www.other-domain.org. IN A 192.168.1.11 ;  www.other-domain.org. is outside of domain-example.org
                                      ; and therefore needs to be declared using FQDN

The syntax explained here:

  • ; - Comment, disabled line
  • $ORIGIN - Zone starting point in the name-space tree, (if skipped - the origin is inferred by the DNS server based on zone declaration in name.conf.local file
  • $TTL - Default expiration time for all resources (cache time, specified in seconds)
    • (alternatively M, H might be appended to denote minutes or hours)
  • @ IN SOA ns.domain-example.org. root.domain-example.org.( 2012020101 15M 5M 604800 600) :
    • @ - Will be expanded to $ORIGIN if specified or assigned by DNS server
      • (in current example to domain-example.org)
    • IN - Protocol family:
      • IN - Internet protocol (IP)
      • HS and CH - historic MIT protocols from the times there was DNS but there was no IP
    • SOA - Zone authority info:
    • ns.domain-example.org - Address of name-server
    • root.domain-example.org - Will be expanded to root@domain-example.org and will correspond to email address of DNS master in the domain-example.org
    • 2012020101 - Serial Number (as specified here):
      • Unsigned 32 bit value in range 1 to 4294967295 with a maximum increment of 2147483647. In BIND implementations this is defined to be a 10 digit field. This value MUST increment when any resource record in the zone file is updated. A slave (Secondary) DNS server will read the master DNS SOA record periodically, either on expiry of refresh (defined below) or when it receives a NOTIFY and compares, arithmetically, its current value of sn with that received from the master. If the sn value from the master is arithmetically HIGHER than that currently stored by the slave then a zone transfer (AXFR/IXFR) is initiated by the slave. If the value of sn from the master DNS SOA is the same or LOWER then no zone transfer is initiated.
      • The convention is to use a date based sn value to simplify the task of incrementing the sn - the most popular convention being yyyymmddss where yyyy = year, mm = month and dd = day ss = a sequence number in case you update it more than once in the day!

As you can see after declaring SOA Zone authority, the actual Zone related data is added: the zone records:

  • <name> <ttl> <class> <type> <data>
    • name record name
    • ttl time to live in seconds, how long cache lives, if skipped $TTL variable is used.
    • class record class, the protocol family (in modern world only IN remains)
    • type record type
    • data type related value of the record

Record name can be one of three:

  • Short host name (inside current domain), like ns or mail , which will be then automatically extended to ns.domain-example.org and mail.domain-example.org .
  • FQDN (Fully-Qualified Domain Name), like www.otherd-domain.org.
    • '''In this case we have to terminate FQDN with . in order to avoid auto-expansion to www.otherd-domain.org.domain-example.org
  • @ sign which will be expanded to domain-example.org denoting the domain itself.

Create your zone file

You need to create the zone file in /etc/named/ , but first let's make sure you know your domain:

Personal student domain is a sub-domain of sa.cs.ut.ee zone and has your VM's name as the domain name; therefore, if my VM's name is student-test , then my domain would be student-test.sa.cs.ut.ee

Here we assume you got your domain name correctly and we proceed with Zone file creation:

Create the file:

  • <student_zone>.sa.cs.ut.ee in the /etc/named directory
    • here <student_zone> is your domain name
    • example: if my domain name is student-test.sa.cs.ut.ee then the file is student-test.sa.cs.ut.ee
  • If you setup the named directory properly, it should be automatically assigned to named group, and if not, please make sure you did assigned the ownership and permissions properly to the named directory.

If the file was created properly you may edit the zone and add the bare minimal amount of zone records to your zone file.

Edit the zone file you have just created, add following:

  • Default time-to-live value of 15 minutes
  • SOA Authority record of your domain
    • having ns1.<your_domain>. as the name server
    • having root.<your_domain>. as the email of DNS master
    • having serial properly specified
    • having refresh interval of 15 minutes
    • having retry interval of 5 minutes
    • having expiry interval 2 hours
    • having negative cache TTL 600 seconds
  • NS record of your domain pointing to host ns1 in your domain
  • A records:
    • ns1 pointing to your External IP address
    • <your_domain> pointing to your External IP address
    • <your_hostname> pointing to your External IP address

Example file of ours /etc/named/student-test.sa.cs.ut.ee , domain student-test.sa.cs.ut.ee and IP 172.17.64.a :

;
; BIND data file for local zone student-test.sa.cs.ut.ee;
$TTL    15M
@       IN      SOA     ns1.student-test.sa.cs.ut.ee. root.student-test.sa.cs.ut.ee. (
                     2012020201         ; Serial
                            15M         ; Refresh
                             5M         ; Retry
                           120M         ; Expire
                            600 )       ; Negative Cache TTL
@              IN      NS      ns1
@              IN      A       172.17.64.a
ns1            IN      A       172.17.64.a
student-test   IN      A       172.17.64.a

If you did edit the file properly the following command may be used to test if the Zone file is valid

  • # named-checkzone <your_domain> /etc/named/<your_domain>.sa.cs.ut.ee
    • here <your_domain> is your personal domain name

If command reports no error, the Zone file is correct

If the zone file is correct we may add the defined zone into bind configuration.

Edit the named configuration, the one containing the declared zone "." IN .

  • Underneath the zone "." IN declaration add a new zone clause
    • having zone name set to your personal domain
    • pointing to the previously defined
    • having type master

In our examples we made it as follows:

...
zone "student-test.sa.cs.ut.ee" IN {
        type master;
        file "/etc/named/student-test.sa.cs.ut.ee";
        allow-update { none; };
};

After editing configuration, do not forget to check if it is valid, using named-checkconf command

If the configuration is OK:

  • Restart the named service
  • Make sure it did load the new zone (check the named log file)
    • /var/named/log/default

The log has to have line like:

...
08-Mar-2020 16:35:58.841 general: info: zone student-test.sa.cs.ut.ee/IN: loaded serial 2020030804
08-Mar-2020 16:35:58.841 general: notice: all zones loaded
08-Mar-2020 16:35:58.841 general: notice: running...
...

Afterwards you should be able to use dig or nslookup commands for testing:

  • $ dig @127.0.0.1 <your_domain>
  • $ dig @127.0.0.1 ns1.<your_domain>
  • $ dig @127.0.0.1 <your_domain> NS

Why do some of the queries return ANSWER: 0? Can you explain that?

  • Add notify explicit; to your zone declaration.
  • Add also-notify { 172.17.66.134; }; to the configuration file under options.
  • Increment your zone's serial by one.
  • Restart your named service.

Rerun the queries:

  • $ dig @127.0.0.1 <your_domain>
  • $ dig @127.0.0.1 ns1.<your_domain>
  • $ dig @127.0.0.1 <your_domain> NS

The dig should show result properly:

Example dig result of the command:

  • dig @127.0.0.1 student-test.sa.cs.ut.ee
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el8 <<>> @127.0.0.1 student-test.sa.cs.ut.ee
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64197
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 5b6c2462c45d2d8c86684aec5e65045a42fab1a5ec27af6a (good)
;; QUESTION SECTION:
;student-test.sa.cs.ut.ee.		IN	A

;; ANSWER SECTION:
student-test.sa.cs.ut.ee.	900	IN	A	172.17.65.65

;; AUTHORITY SECTION:
student-test.sa.cs.ut.ee.	900	IN	NS	ns1.student-test.sa.cs.ut.ee.

;; ADDITIONAL SECTION:
ns1.student-test.sa.cs.ut.ee.	900	IN	A	172.17.65.65

;; Query time: 2 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sun Mar 08 16:42:34 EET 2020
;; MSG SIZE  rcvd: 125

Understanding reverse mapping Zone files

The interesting fact about records in Zone file configurations:

  • all the associations are unidirectional

which means if we have

  • ns1.example.org. A IN 10.10.10.5

it is equivalent to the link

  • ns1.example.org. -> 10.10.10.5

and not opposite way around:

  • 10.10.10.5 -> ns1.example.org.

The secondary link from IP to the host name has to be added by introducing the PTR records. The PTR records are organized and collected in separate Zone file called Reverse Mapped Zone.

Why can't we just put PTRs in same Zone file we created in previous tasks?

You already know the DNS name space is organized in hierarchical structure:

The whole domain name space is first addressed from root(.) which is the root of the whole DNS tree, then it's divided across number of TLDs, like .com, .org, .net etc. You can check the full list of TLDs here. Next, each TLD has a number of sub-domain and for us we did introduce additional TLD <name>.sa.cs.ut.ee with sub-domains for each student. Following the divide and conquer idea each of the sub-domains can further be divided in sub-domains (each student can potentially create an infinite amount of sub-domains).

Considering the TLDs once again there is one specific: .arpa which currently isn't serving any of the domains, but is holding routing and addressing parameters and is therefore called Infrastructure TLD.

  • The DNS architecture was designed by US Advanced Research Project Agency (ARPA)
  • .arpa was originally domain name of the ARPA agency, and it was the first domain introduce in DNS name space.
  • as it turned to be Infra-TLD the .arpa is referred as Addressing and Routing Parameter Area.

The idea behind .arpa Infra-TLD is to provide reverse mappings (from IP to host name), and is mainly used by humans for such things as tracking where a web-site visitor came from, or where an e-mail message originated etc.

However reverse DNS is important for one particular application. Many e-mail servers on the Internet are configured to reject incoming e-mails from any IP address which does not have reverse DNS. So if you run your own e-mail server, reverse DNS must exist for the IP address that outgoing e-mail is sent from. Reverse DNS mappings are also an important part of keeping the trust-based DNS working. A simple check any service provider can run is looking for mismatches in PTR and A type records, and usually if these don't match data is marked as spam.

The IPv4 address space is of course not infinite but the idea of hierarchy is followable if we consider how the IPv4 space is divided into subnets. Each organization is assigned with a big subnet (A class or B class dependent on the size of the organization). Dependent on the inner structure of the organization the big subnet can be divided again and again till there are free unused IPv4 addresses.

As you can see, the bigger subnets can still be broken into smaller ones, the simple example is explained here (if you struggle understanding concepts of IP addressing you may first read the IP Basics). Now, taking this into account, all of the IP address space was structured and reduced into reverse mapping Zones under the .arpa TLD. Therefore the .arpa is broken into sub-domains as follows:

  • in-addr.arpa domain contains all the reverse mappings for IPv4 address space (in-addr stands for Internet Address)
  • in-ip6.arpa domain contains all the reverse mappings for IPv6 address space

Now each of them is broken down into sub-domains denoting subnets of IPv4 or IPv6. The domain name for the subnet is then constructed as follows:

  • For the IPv4 subnet:
    • Consider your subnet (for example you have 172.17.6.0/24)
    • The non-changeable part is 172.17.6. (by subnet 172.17.6.0) and only the last octet can change (by netmask 255.255.255.0)
    • Non-changeable part is then reversed (so we get 6.17.172)
    • in-addr.arpa is appended to the reversed subnet (we get 6.17.172.in-addr.arpa)
    • 6.17.172.in-addr.arpa is then our domain for reverse mapping:
      • This will be the $ORIGIN for the reverse mapping Zone file
  • For the IPv6 subnet:
    • ... to be added ...

Now the reverse mapping Zone files are similar to regular Zone files, here is an example:

$ORIGIN 6.17.172.in-addr.arpa.   ; Zone starting point in the name-space tree
                     ; (if skipped - the origin is inferred by the DNS server based on
                     ; zone declaration in name.conf.local file
$TTL 15M             ; Default expiration time for all resources
@ IN SOA ns.domain-example.org. root.domain-example.org.(
	 2012020101       ; Serial
		15M       ; Refresh (15 minutes)
		5M        ; Retry (5 minutes)
		604800    ; Expire (7 days in seconds)
		600 )     ; Negative Cache TTL
@              IN      NS      ns.domain-example.org.       ; Name Server for domain-example.org
1             IN      PTR     ns.domain-example.org.       ; 172.17.6.1 has name ns.domain-example.org
5             IN      PTR     myhost.domain-example.org.   ; 172.17.6.5 has name myhost.domain-example.org
6             IN      PTR     mail.domain-example.org.     ; 172.17.6.6 has name mail.domain-example.org
7             IN      PTR     myhost2.domain-example.org.  ; 172.17.6.7 has name myhost2.domain-example.org

As you can see there is not much changed in the headers:

  • $ORIGIN - pointing to 17.172.in-addr.arpa
    • we can omit specifying origin, leaving it for bind9 to specify it (inferring named.conf.local configurations
  • TTL and SOA records remain the same as in regular Zone file (we are still in domain-example.org)
  • NS record is the same (we are still having DNS server's FDQN: ns.domain-example.org.)
  • Next we have the PTR record for each A or AAAA type of records from the regular Zone file of our domain
    • Each host name -> IP association should have a reverse association IP -> host name.

Please note, that it is possible to specify multiple A or AAAA types of record pointing to the same IP address, however in reverse mapping only one of the host names may be pointed by the PTR type of record. For example, in the regular Zone file we have:

@       IN      A       172.17.6.1    ; IPv4 address for domain-example.org
ns      IN      A       172.17.6.1    ; IPv4 address for ns.domain-example.org

Both domain-example.org and ns.domain-example.org are having the A type of record pointing to the same IP of 172.17.6.1. In the reverse mappings however we have only one record:

1             IN      PTR     ns.domain-example.org.

... saying 172.17.6.1 has name ns.domain-example.org Please keep in mind this is an example. For you it needs to be a different IP address.

The content of reverse mapping Zone file is then stored similar to regular Zone:

  • Zone example-domain.org was stored in file example-domain.org.zone
  • Zone 6.17.172.in-addr.arpa should be stored in file 6.17.172.in-addr.arpa.zone

The file name convention is not important to follow (you can use other names if you wish), the idea of this convention is to keep named.conf.local configuration file more clear and followable.

The last thing to understand is how the reverse mapping Zone file is embedded into existing bind9 configuration, and this is fact 1-to-1 similar to how we declared the regular Zone in bind9 configuration (we have to add another zone clause in the configuration file):

  • We cannot reuse existing zone clause domain-example.org for the reversed one 6.17.172.in-addr.arpa

Can you now explain why ? If you struggle with an answer think about the following: What is the $ORIGIN variable? How is it assigned? How is it related to domain name? How does the DNS name space look like? What is TLD? What is Infrastructure TLD? Which part of DNS name space is responsible for direct lookup queries? Which part of DNS name space is responsible for reverse lookup queries?

After answering those questions it should be clear - the reverse mappings we can only specify under .arpa infrastructure TLD; which separate branch of DNS name space (not overlapping with .org TLD). Therefore the $ORIGIN is different too, and has to be declared separately.

Declaring the zone clause for reverse mapping Zone is then looking like:

zone "65.17.172.in-addr.arpa" IN {
        type master;
        file "/etc/named/reverse.student-test.sa.cs.ut.ee";
        allow-update { none; };
};

Is it by the way important to specify

  • allow-update { none; };

After the reverse mapping Zone file is included in bind configuration, the standard check-routines should follow:

  • Checking the reverse mapping Zone file:
    • named-checkzone ''65.17.172.in-addr.arpa'' <path to reverse.student-test.sa.cs.ut.ee file>
  • Checking the named configuration using named-checkconf command

Now we are ready to add the reverse mapping Zone to our bind9 configuration for our network and to populate it with PTR records.

Create the reverse mapping Zone file for 172.17.X.X/24 or 193.40.X.X/24 (depending on which external-IP you have):

  • use the same $TTL and $SOA as in the regular Zone file you created for your domain
  • add the required PTR records
    • if you do not know what to add, please refer to the Understanding reverse mapping Zone files'
  • save the reverse mapping file
    • into the same directory as the regular Zone file you created for your domain
    • select the proper file name, try to follow the conventions we have explained
    • make sure the Zone file has proper ownership and permissions
  • check the Zone file using named-checkzone command
    • the example was given before

If the reverse mapping Zone is OK, construct the reverse mapping domain name:

  • The example how to get reverse domain name from IPv4 subnet was given before

If you have calculated the reverse mapping name for your subnet:

Edit the bind9 local configuration file:

  • find the proper place to add new zone clause
  • add new zone clause having:
    • zone name properly assigned with reverse mapping domain name you have calculated
    • file - assigned with absolute path of the corresponding file containing reverse mappings
    • type - assigned to master
  • save the configuration file

Check the configuration using corresponding command

If the configuration is OK:

Restart the DNS service

Check if reverse mapping is working properly using the following command:

  • host <your external-IP address>
  • nslookup <your external-IP address>
    • It should give you back the FQDN you assigned to IP address
  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Õppematerjalide varalised autoriõigused kuuluvad Tartu Ülikoolile. Õppematerjalide kasutamine on lubatud autoriõiguse seaduses ettenähtud teose vaba kasutamise eesmärkidel ja tingimustel. Õppematerjalide kasutamisel on kasutaja kohustatud viitama õppematerjalide autorile.
Õppematerjalide kasutamine muudel eesmärkidel on lubatud ainult Tartu Ülikooli eelneval kirjalikul nõusolekul.
Courses’i keskkonna kasutustingimused