DNS Operations & Record Management
Comprehensive DNS operations runbook for bind-01/bind-02 and VyOS DNS forwarder integration. Covers forward/reverse records, SOA serial updates, zone transfers, and netapi automation.
1. Quick Reference
| Task | Command |
|---|---|
Add A record |
|
Add PTR record |
|
Check forward |
|
Check reverse |
|
Restart BIND |
|
Check zone serial |
|
Zone transfer test |
|
2. Infrastructure
| Host | Role | IP |
|---|---|---|
bind-01 |
Primary DNS (Authoritative) |
10.50.1.90 |
bind-02 |
Secondary DNS |
10.50.1.91 |
VyOS VIP |
DNS Forwarder |
10.50.1.1 |
Zone files location: /var/named/
Forward zone: inside.domusdigitalis.dev
Reverse zone: 1.50.10.in-addr.arpa
3. Zone File Structure Reference
The forward zone file is organized by IP range sections:
; Gateway (.1)
; Network Devices (.10-19)
; Identity Services (.20-29)
; iPSK Manager (.30-39)
; Wireless (.40-49)
; Windows Servers (.50-59)
; Active Directory SRV Records
; PKI Services (.60-69)
; Storage/Git (.70-79)
; IdP/SSO (.80-89)
; DNS Services (.90-99)
; LDAP/Directory (.100-109)
; Load Balancers (.110-119)
; Kubernetes (.120-129)
; IPMI/BMC (.200-209)
; Aliases (CNAMEs)
4. Useful awk Commands for Zone Files
4.1. View Zone File with Line Numbers
sudo awk 'NR<=80 {print NR": "$0}' /var/named/inside.domusdigitalis.dev.zone
4.2. View Specific Line Range
# Lines 70-85 (k3s section)
sudo awk 'NR>=70 && NR<=85 {print NR": "$0}' /var/named/inside.domusdigitalis.dev.zone
4.3. Find Section by IP Range
# Find entries in .120-129 range
sudo awk '/\.12[0-9]/ {print NR": "$0}' /var/named/inside.domusdigitalis.dev.zone
4.4. Find Host by Name
sudo awk '/grafana|prometheus|alertmanager/ {print NR": "$0}' /var/named/inside.domusdigitalis.dev.zone
5. Reverse Zone awk Commands
5.1. View PTR Records with Line Numbers
sudo awk '/IN[[:space:]]+PTR/ {print NR": "$0}' /var/named/10.50.1.rev
5.3. Verify No Leading Whitespace (Critical!)
# Brackets reveal hidden whitespace
sudo awk '/IN[[:space:]]+PTR/ {print NR": ["$0"]"}' /var/named/10.50.1.rev
If output shows [ 120 …] (leading spaces inside brackets), records are broken.
6. Add Host Records (Full Procedure)
6.1. Step 1: Plan the Record
| Field | Value |
|---|---|
Hostname |
k3s-master-01 |
FQDN |
k3s-master-01.inside.domusdigitalis.dev |
IP Address |
10.50.1.120 |
Reverse |
120.1.50.10.in-addr.arpa |
6.3. Step 3: Add Forward (A) Record
6.3.1. Option A: nsupdate (Dynamic Update)
sudo nsupdate -l << 'EOF'
zone inside.domusdigitalis.dev
update add k3s-master-01.inside.domusdigitalis.dev. 3600 A 10.50.1.120
send
EOF
|
If
BIND is not configured for local dynamic updates. Use Option B (manual zone file edit) instead. |
6.3.2. Option B: Manual Zone File Edit (Fallback)
sudo vi /var/named/inside.domusdigitalis.dev.zone
1. Increment SOA serial (near top of file, format YYYYMMDDNN):
@ IN SOA bind-01.inside.domusdigitalis.dev. admin.inside.domusdigitalis.dev. (
2026022301 ; Serial - INCREMENT THIS (today's date + sequence)
...
2. Add A record (in the A records section with other hosts):
k3s-master-01 IN A 10.50.1.120
3. Save and exit (:wq)
4. Validate syntax:
sudo named-checkzone inside.domusdigitalis.dev /var/named/inside.domusdigitalis.dev.zone
zone inside.domusdigitalis.dev/IN: loaded serial 2026022301 OK
5. Reload zone:
sudo rndc reload inside.domusdigitalis.dev
6.4. Step 4: Add Reverse (PTR) Record
6.4.1. Option A: nsupdate (Dynamic Update)
sudo nsupdate -l << 'EOF'
zone 1.50.10.in-addr.arpa
update add 120.1.50.10.in-addr.arpa. 3600 PTR k3s-master-01.inside.domusdigitalis.dev.
send
EOF
6.4.2. Option B: Manual Zone File Edit (Fallback)
sudo vi /var/named/10.50.1.rev
Reverse zone filename is 10.50.1.rev, not 1.50.10.in-addr.arpa.zone.
|
1. Increment SOA serial
2. Add PTR record:
|
CRITICAL: NO leading whitespace! Zone files are whitespace-sensitive:
|
120 IN PTR k3s-master-01.inside.domusdigitalis.dev.
3. Save, validate, reload:
sudo named-checkzone 1.50.10.in-addr.arpa /var/named/10.50.1.rev
sudo rndc reload 1.50.10.in-addr.arpa
6.5. Step 5: Verify SOA Serial Updated
dig SOA inside.domusdigitalis.dev +short | awk '{print "Serial: "$3}'
nsupdate automatically increments the SOA serial. Manual zone file edits require manual serial increment (Step 3B/4B).
|
7. Bulk Record Addition
7.1. Kubernetes Cluster Example
Add all k3s nodes at once:
sudo nsupdate -l << 'EOF'
zone inside.domusdigitalis.dev
update add k3s-master-01.inside.domusdigitalis.dev. 3600 A 10.50.1.120
update add k3s-master-02.inside.domusdigitalis.dev. 3600 A 10.50.1.121
update add k3s-master-03.inside.domusdigitalis.dev. 3600 A 10.50.1.122
update add k3s-worker-01.inside.domusdigitalis.dev. 3600 A 10.50.1.123
update add k3s-worker-02.inside.domusdigitalis.dev. 3600 A 10.50.1.124
update add k3s-worker-03.inside.domusdigitalis.dev. 3600 A 10.50.1.125
send
EOF
Reverse records:
sudo nsupdate -l << 'EOF'
zone 1.50.10.in-addr.arpa
update add 120.1.50.10.in-addr.arpa. 3600 PTR k3s-master-01.inside.domusdigitalis.dev.
update add 121.1.50.10.in-addr.arpa. 3600 PTR k3s-master-02.inside.domusdigitalis.dev.
update add 122.1.50.10.in-addr.arpa. 3600 PTR k3s-master-03.inside.domusdigitalis.dev.
update add 123.1.50.10.in-addr.arpa. 3600 PTR k3s-worker-01.inside.domusdigitalis.dev.
update add 124.1.50.10.in-addr.arpa. 3600 PTR k3s-worker-02.inside.domusdigitalis.dev.
update add 125.1.50.10.in-addr.arpa. 3600 PTR k3s-worker-03.inside.domusdigitalis.dev.
send
EOF
9. Modify Records
Delete then add (atomic update):
sudo nsupdate -l << 'EOF'
zone inside.domusdigitalis.dev
update delete host.inside.domusdigitalis.dev. A
update add host.inside.domusdigitalis.dev. 3600 A 10.50.1.200
send
EOF
10. CNAME Records
sudo nsupdate -l << 'EOF'
zone inside.domusdigitalis.dev
update add k8s.inside.domusdigitalis.dev. 3600 CNAME k3s-master-01.inside.domusdigitalis.dev.
send
EOF
11. SOA Serial Management
11.1. Check Current Serial
dig SOA inside.domusdigitalis.dev +short | awk '{print "Primary:", $1, "| Serial:", $3}'
11.2. Manual Zone File Edit (If Required)
|
Prefer |
If you must edit zone files directly:
sudo vim /var/named/inside.domusdigitalis.dev.zone
Increment SOA serial (format: YYYYMMDDNN):
@ IN SOA bind-01.inside.domusdigitalis.dev. admin.inside.domusdigitalis.dev. (
2026022201 ; Serial - INCREMENT THIS
3600 ; Refresh
600 ; Retry
604800 ; Expire
86400 ; Minimum TTL
)
Reload zone:
sudo rndc reload inside.domusdigitalis.dev
Verify:
sudo named-checkzone inside.domusdigitalis.dev /var/named/inside.domusdigitalis.dev.zone
12. Zone Transfer Operations
12.1. Check Secondary Sync Status
# On bind-01 (primary)
dig SOA inside.domusdigitalis.dev @10.50.1.90 +short | awk '{print "Primary serial:", $3}'
# On bind-02 (secondary)
dig SOA inside.domusdigitalis.dev @10.50.1.91 +short | awk '{print "Secondary serial:", $3}'
Serials should match.
13. VyOS DNS Forwarding
VyOS forwards DNS queries to BIND (bind-01/bind-02). BIND is the authoritative DNS server.
13.3. Configure DNS Forwarding (Reference)
This configuration is already deployed. Reference only:
configure
set service dns forwarding listen-address 10.50.1.1
set service dns forwarding name-server 10.50.1.90
set service dns forwarding name-server 10.50.1.91
set service dns forwarding allow-from 10.50.0.0/16
commit
save
14. Troubleshooting
14.1. Record Not Resolving
Check on BIND directly:
dig +short hostname.inside.domusdigitalis.dev @10.50.1.90
Check zone file:
sudo grep hostname /var/named/inside.domusdigitalis.dev.zone
Check BIND logs:
sudo journalctl -u named --since "5 minutes ago" | grep -i error
14.2. PTR Not Resolving
Verify reverse zone:
dig +short -x 10.50.1.120 @10.50.1.90
If result is empty or NXDOMAIN, check zone file.
Check reverse zone file:
sudo awk '/120/ {print NR": ["$0"]"}' /var/named/10.50.1.rev
Most common cause: Leading whitespace
Zone validated OK but lookup returns NXDOMAIN? Check for leading spaces:
# Show exact characters (brackets reveal whitespace)
sudo awk '/120/ {print NR": ["$0"]"}' /var/named/10.50.1.rev
If output shows [ 120 …] (leading spaces inside brackets), fix with:
# Remove leading whitespace from lines with PTR records
sudo sed -i '/IN[[:space:]]*PTR/s/^[[:space:]]*//' /var/named/10.50.1.rev
# Verify fix
sudo awk '/120/ {print NR": ["$0"]"}' /var/named/10.50.1.rev
# Reload zone
sudo rndc reload 1.50.10.in-addr.arpa
# Test
dig +short -x 10.50.1.120 @localhost
15. Validation Script
Run after adding records:
#!/bin/bash
# dns-validate.sh <hostname> <ip>
HOST=$1
IP=$2
DOMAIN="inside.domusdigitalis.dev"
echo "=== Validating $HOST.$DOMAIN ($IP) ==="
# Forward lookup
FORWARD=$(dig +short $HOST.$DOMAIN)
[ "$FORWARD" = "$IP" ] && echo "✓ Forward: $FORWARD" || echo "✗ Forward: expected $IP, got $FORWARD"
# Reverse lookup
REVERSE=$(dig +short -x $IP | sed 's/\.$//')
[ "$REVERSE" = "$HOST.$DOMAIN" ] && echo "✓ Reverse: $REVERSE" || echo "✗ Reverse: expected $HOST.$DOMAIN, got $REVERSE"
# Primary DNS
P_FWD=$(dig +short $HOST.$DOMAIN @10.50.1.90)
[ "$P_FWD" = "$IP" ] && echo "✓ bind-01: $P_FWD" || echo "✗ bind-01: $P_FWD"
# Secondary DNS
S_FWD=$(dig +short $HOST.$DOMAIN @10.50.1.91)
[ "$S_FWD" = "$IP" ] && echo "✓ bind-02: $S_FWD" || echo "✗ bind-02: $S_FWD"
# VyOS (DNS forwarder)
VYOS_FWD=$(dig +short $HOST.$DOMAIN @10.50.1.1)
[ "$VYOS_FWD" = "$IP" ] && echo "✓ VyOS: $VYOS_FWD" || echo "✗ VyOS: $VYOS_FWD"
Usage:
./dns-validate.sh k3s-master-01 10.50.1.120
16. Chronicle
16.1. 2026-02-23: k3s Monitoring Stack DNS Records
Added DNS records for Prometheus/Grafana/AlertManager (all point to k3s-master-01):
| Hostname | IP |
|---|---|
grafana.inside.domusdigitalis.dev |
10.50.1.120 |
prometheus.inside.domusdigitalis.dev |
10.50.1.120 |
alertmanager.inside.domusdigitalis.dev |
10.50.1.120 |
PTR record: 120.1.50.10.in-addr.arpa → k3s-master-01.inside.domusdigitalis.dev
| Single PTR for shared IP - k3s-master-01 is canonical hostname. |
16.1.1. Troubleshooting: PTR Whitespace Issue (Test Case)
Symptom: Zone validated OK, but reverse lookup returned empty.
sudo named-checkzone 1.50.10.in-addr.arpa /var/named/10.50.1.rev
zone 1.50.10.in-addr.arpa/IN: loaded serial 2026022301
OK
dig +short -x 10.50.1.120 @localhost
# (empty result)
Diagnosis: Use awk with brackets to reveal hidden whitespace:
sudo awk '/120|121|122/ {print NR": ["$0"]"}' /var/named/10.50.1.rev
58: [; Kubernetes (.120-129)]
59: [120 IN PTR k3s-master-01.inside.domusdigitalis.dev.]
60: [121 IN PTR k3s-master-02.inside.domusdigitalis.dev.]
61: [122 IN PTR k3s-master-03.inside.domusdigitalis.dev.]
Records started at column 1 (no leading spaces) - whitespace was NOT the issue here.
Fix: Reload zone (sometimes required after validation):
sudo rndc reload 1.50.10.in-addr.arpa
zone reload queued
dig +short -x 10.50.1.120 @localhost
k3s-master-01.inside.domusdigitalis.dev.
Lesson: Always run rndc reload after zone validation, even if zone was already reloaded.