Skip to content

Week 05 - DNS

Topic

Setting up a recursive DNS resolver using Knot Resolver (kresd) and an authoritative DNS server using Knot DNS (knotd). Students will configure their VM as a caching resolver on port 53, serve their own domain zone on port 5353, add subdomain records for existing web services, configure reverse DNS (ARPA), and set up zone transfer notifications to the central course server.

Company Requests

Ticket #501: Internal DNS Resolver

"Our VM currently relies on external DNS servers for name resolution. IT wants us to run our own caching resolver so we're not dependent on third parties. Set up a recursive resolver on port 53 that works for both local and remote queries, and configure the machine to use it."

Ticket #502: Authoritative DNS for Our Domain

"The central DNS team has delegated <vm_name>.sysadm.ee to our server. We need an authoritative DNS server on port 5353 that serves our domain. Make sure <vm_name>.sysadm.ee, blog.<vm_name>.sysadm.ee, and inventory.<vm_name>.sysadm.ee all resolve to our VM's IP."

Ticket #503: Reverse DNS

"Our mail server setup next week requires that reverse DNS lookups for our IP return our hostname. Set up a PTR record so that querying our IP address returns <vm_name>.sysadm.ee."

Ticket #504: Zone Transfer to Central Server

"The central course DNS server acts as a public secondary for all student domains. Configure your authoritative server to notify the central server when zone data changes, and allow it to perform zone transfers."

Why two ports?

We run the recursive resolver (kresd) on the standard DNS port 53 and the authoritative server (knotd) on port 5353. This separation follows best practice — recursive and authoritative functions should not share the same port to avoid cache poisoning attacks and simplify debugging.

Scoring Checks

  • Check 5.1: Port 53/tcp is open and reachable from the scoring server.
    • Method: TCP connection to your VM on port 53.
    • Expected: Connection succeeds.
  • Check 5.2: Port 5353/tcp is open and reachable from the scoring server.
    • Method: TCP connection to your VM on port 5353.
    • Expected: Connection succeeds.
  • Check 5.3: Recursive DNS resolution works from outside.
    • Method: The scoring server sends a DNS query for google.com to your VM's IP on port 53.
    • Expected: At least one A record is returned.
  • Check 5.4: VM uses its own resolver.
    • Method: The scoring server logs in via SSH and checks /etc/resolv.conf.
    • Expected: nameserver 127.0.0.1 is present.
  • Check 5.5: <vm_name>.sysadm.ee resolves on the authoritative server.
    • Method: The scoring server queries your VM on port 5353 for <vm_name>.sysadm.ee A.
    • Expected: Returns your VM's IP address.
  • Check 5.6: blog.<vm_name>.sysadm.ee resolves on the authoritative server.
    • Method: The scoring server queries your VM on port 5353 for blog.<vm_name>.sysadm.ee.
    • Expected: Returns your VM's IP (A record) or a CNAME pointing to <vm_name>.sysadm.ee.
  • Check 5.7: inventory.<vm_name>.sysadm.ee resolves on the authoritative server.
    • Method: Same as 5.6 but for inventory.<vm_name>.sysadm.ee.
    • Expected: Returns your VM's IP (A record) or a CNAME pointing to <vm_name>.sysadm.ee.
  • Check 5.8: Reverse PTR record for your VM's IP.
    • Method: The scoring server sends a reverse lookup (dig -x <your_ip>) to your VM on port 5353.
    • Expected: Returns <vm_name>.sysadm.ee.

Tasks

Task 1: Install and Configure the Recursive Resolver

Set up Knot Resolver (kresd) as a caching recursive resolver on port 53.

Complete

  1. Install Knot Resolver: dnf install knot-resolver.
  2. Edit /etc/knot-resolver/kresd.conf to listen on both 127.0.0.1 and 0.0.0.0 on port 53.
  3. Open port 53 in firewalld (both TCP and UDP): firewall-cmd --add-service=dns --permanent && firewall-cmd --reload.
  4. Enable and start the service: systemctl enable --now kresd@1.service.
  5. If the service fails with Permission denied, fix directory ownership (see Post-Install Fix).
  6. Verify recursive resolution works locally: dig @127.0.0.1 google.com.

Reference: Technologies: Knot Resolver, SOP: DNS Management — Set Up a Recursive Resolver

Task 2: Use Your Own Resolver

Configure the VM to use its own kresd instance for all DNS resolution.

Complete

  1. Edit /etc/resolv.conf and set nameserver 127.0.0.1.
  2. Prevent NetworkManager from overwriting it: chattr +i /etc/resolv.conf.
  3. Verify with dig google.com — the SERVER: line should show 127.0.0.1#53.

Reference: SOP: DNS Management — Configure the VM to Use Its Own Resolver

Task 3: Install and Configure the Authoritative Server

Set up Knot DNS (knotd) as an authoritative name server on port 5353.

Complete

  1. Install Knot DNS: dnf install knot.
  2. Create the zones directory: mkdir -p /var/lib/knot/zones && chown knot:knot /var/lib/knot/zones.
  3. Edit /etc/knot/knot.conf — configure the server to listen on 0.0.0.0@5353 and define your forward zone.
  4. Open port 5353 in firewalld (TCP and UDP): firewall-cmd --add-port=5353/tcp --permanent && firewall-cmd --add-port=5353/udp --permanent && firewall-cmd --reload.
  5. Enable and start the service: systemctl enable --now knot.

Reference: Technologies: Knot DNS, SOP: DNS Management — Set Up an Authoritative Server

Task 4: Create the Forward Zone

Create the zone file for <vm_name>.sysadm.ee with the required records.

Complete

  1. Create the zone file at /var/lib/knot/zones/<vm_name>.sysadm.ee.zone with:
    • SOA record with proper serial number (use YYYYMMDDNN format)
    • NS record pointing to ns1.<vm_name>.sysadm.ee.
    • A record for @ (zone apex) pointing to your VM's IP
    • A record for ns1 pointing to your VM's IP
    • CNAME records for blog and inventory pointing to <vm_name>.sysadm.ee.
  2. Set file ownership: chown knot:knot /var/lib/knot/zones/<vm_name>.sysadm.ee.zone.
  3. Validate the zone: knotc conf-check (validates the configuration) and after loading, knotc zone-check <vm_name>.sysadm.ee.
  4. Reload knotd: knotc reload.
  5. Verify: dig @127.0.0.1 -p 5353 <vm_name>.sysadm.ee and dig @127.0.0.1 -p 5353 blog.<vm_name>.sysadm.ee.

Reference: SOP: DNS Management — Create a Forward Zone, Concepts: DNS — Key Terminology

Task 5: Create the Reverse (ARPA) Zone

Set up reverse DNS so that looking up your VM's IP returns its hostname.

Complete

  1. Determine your reverse zone name from your VM's IP address. For IP A.B.C.D on a /24 subnet, the zone is C.B.A.in-addr.arpa and your host record name is D.
  2. Create the reverse zone file at /var/lib/knot/zones/C.B.A.in-addr.arpa.zone with:
    • SOA and NS records (same nameserver as the forward zone)
    • PTR record mapping your last octet to <vm_name>.sysadm.ee.
  3. Set file ownership: chown knot:knot /var/lib/knot/zones/C.B.A.in-addr.arpa.zone.
  4. Add the reverse zone to /etc/knot/knot.conf.
  5. Reload and verify: knotc reload && dig @127.0.0.1 -p 5353 -x <VM_IP>.

Reference: SOP: DNS Management — Create a Reverse (ARPA) Zone, Concepts: DNS — Reverse DNS (ARPA)

Task 6: Configure Zone Transfer Notifications

Configure knotd to notify the central course server of zone changes and allow it to transfer your zones.

Complete

  1. Add a remote section to /etc/knot/knot.conf pointing to the central server at 193.40.153.43@53.
  2. Add an acl section allowing the central server to perform zone transfers. The central server connects from its internal IP 172.17.89.217, so include both IPs: [193.40.153.43, 172.17.89.217].
  3. Add notify and acl directives to your forward zone definition only. The reverse (ARPA) zone is served directly by your VM and is not transferred to the central server.
  4. Reload: knotc reload.
  5. Trigger a manual notify: knotc zone-notify <vm_name>.sysadm.ee.
  6. Check the logs for a successful outgoing AXFR: journalctl -u knot --since '1 minute ago'.

Reference: SOP: DNS Management — Configure Hidden Primary with NOTIFY, Concepts: DNS — Zone Transfers and Hidden Primary


Ansible Tips

This section covers tips for automating the tasks in this lab with Ansible. You are not required to automate everything this week, but starting early will save you time later.

Tags

Use tags to run only DNS-related roles:

- { role: dns, tags: dns }

Run only the DNS role: ansible-playbook --tags=dns playbook.yml

Handlers

Use handlers to restart services only when configuration changes:

# roles/dns/handlers/main.yml
- name: restart kresd
  systemd:
    name: kresd@1.service
    state: restarted
    enabled: yes

- name: reload knot
  command: knotc reload

Notify the handler from tasks that modify config files:

- name: Deploy kresd.conf
  template:
    src: kresd.conf.j2
    dest: /etc/knot-resolver/kresd.conf
  notify: restart kresd

- name: Deploy knot.conf
  template:
    src: knot.conf.j2
    dest: /etc/knot/knot.conf
  notify: reload knot

Zone File Templates

Use Jinja2 templates for zone files so that the VM name and IP are substituted automatically.

Use a Unix timestamp as the zone serial

Instead of manually maintaining YYYYMMDDNN serials, use {{ ansible_date_time.epoch }} (Unix timestamp) as the serial. It's always increasing, guaranteed unique per run, and you never have to remember to bump it.

{# forward-zone.j2 #}
$TTL 900
@       IN  SOA  ns1.{{ hostname }}.sysadm.ee. admin.{{ hostname }}.sysadm.ee. (
                  {{ ansible_date_time.epoch }}  ; Serial (unix timestamp)
                  900           ; Refresh
                  300           ; Retry
                  7200          ; Expire
                  600 )         ; Negative Cache TTL

@              IN  NS   ns1.{{ hostname }}.sysadm.ee.
@              IN  A    {{ vm_ip }}
ns1            IN  A    {{ vm_ip }}
blog           IN  CNAME  {{ hostname }}.sysadm.ee.
inventory      IN  CNAME  {{ hostname }}.sysadm.ee.

Deploy it:

- name: Deploy forward zone file
  template:
    src: forward-zone.j2
    dest: "/var/lib/knot/zones/{{ hostname }}.sysadm.ee.zone"
    owner: knot
    group: knot
    mode: '0640'
  notify: reload knot

Useful Modules

  • dnf — install packages (knot-resolver, knot)
  • template — deploy kresd.conf, knot.conf, zone files, resolv.conf
  • systemd — manage kresd@1.service and knot services
  • firewalld — open ports 53 and 5353
  • file — set ownership and permissions on zone directories
  • command — run knotc reload or knotc zone-check for validation