If you've spent any time configuring user authentication on... Full Story
By Manny Fernandez
April 19, 2026
Deploying Secondary Bind9 as a DNS Server on Ubuntu Server
You will add ns2 as a secondary (slave) BIND9 server that pulls the infosecmonkey.org zone from NS1 via zone transfers and serves it authoritatively, while also offering recursion to your internal subnets if desired. This is a secondary post to the previous article setting up ns1.
1. Assumptions and Target Design
Assume (adjust IPs/hostnames as needed):
– Primary (NS1): ns1.infosecmonkey.org at 10.1.106.10 (already deployed from previous guide).
– Secondary (NS2): ns2.infosecmonkey.org at 10.1.106.11, fresh Ubuntu with connectivity to NS1.
– Domain: infosecmonkey.org.
– Same recursive policy as NS1 (allowed networks):
10.1.106.0/24, 10.1.105.0/24, 10.240.0.0/15.
High‑level steps:
1. Prepare NS1 to allow zone transfers and send NOTIFY to NS2.
2. Install BIND9 on NS2.
3. Configure NS2 as a secondary for infosecmonkey.org.
4. Configure recursion and ACLs on NS2.
5. Open firewall and test zone transfer and recursion.
6. Update zone file on NS1 to advertise NS2 as a second NS.
2. Configure NS1 (Primary) for Transfers to NS2
2.1 Add ACL for NS2 on NS1 (optional but clean)
On NS1, edit /etc/bind/named.conf.options and add an ACL for the secondary.sudo nano
/etc/bind/named.conf.options
Add near your other ACLs:
acl "secondaries" {
10.1.106.11; // ns2.infosecmonkey.org
};
You can re‑use this ACL in each zone’s allow-transfer later.
2.2 Allow Zone Transfer and NOTIFY for infosecmonkey.org
On NS1, edit /etc/bind/named.conf.local.
sudo vi /etc/bind/named.conf.local
Modify the existing zone definition you created earlier for infosecmonkey.org to include allow-transfer and also-notify:
zone "infosecmonkey.org" {
type master;
file "/etc/bind/db.infosecmonkey.org";
// Allow transfer to NS2 only
allow-transfer { 10.1.106.11; }; // or use: allow-transfer { "secondaries"; };
// Send NOTIFY to NS2 when the zone changes
also-notify { 10.1.106.11; };
};
This lets NS2 pull the zone and receive change notifications.
2.3 Check and Reload NS1
sudo named-checkconf
sudo named-checkzone infosecmonkey.org /etc/bind/db.infosecmonkey.org
sudo systemctl reload bind9
Both named-checkconf and named-checkzone should report no errors.
3. Install BIND9 on NS2
On NS2 (10.1.106.11), install BIND9.
sudo apt update
sudo apt install bind9 bind9-utils bind9-dnsutils -y
Enable and start:
sudo systemctl enable bind9
sudo systemctl start bind9
sudo systemctl status bind9
You should see active (running).
4. Configure NS2 as Secondary for infosecmonkey.org
4.1 Define the Secondary Zone
On NS2, edit /etc/bind/named.conf.local.
sudo vi /etc/bind/named.conf.local
Add:
// Secondary (slave) zone for infosecmonkey.org
zone "infosecmonkey.org" {
type slave; // secondary DNS
masters { 10.1.106.10; }; // NS1 (primary)
file "/var/cache/bind/db.infosecmonkey.org"; // local copy of transferred zone
// Do NOT allow others to transfer from this secondary (tight default)
allow-transfer { none; };
};
Notes:
– type slave (or secondary in newer BIND, but slave is still standard) tells BIND to pull from the master.
– file is where BIND stores its copy; BIND creates and manages this file automatically via AXFR/IXFR.
No manual zone file creation is needed on NS2.
4.2 Create Directory if Needed
On some installs /var/cache/bind may already exist; ensure it’s present and owned by bind.
sudo mkdir -p /var/cache/bind
sudo chown bind:bind /var/cache/bind
sudo chmod 750 /var/cache/bind
5. Configure Recursion and ACLs on NS2
Mirror the recursive policy from NS1 so NS2 can act as a redundant resolver for your internal networks.
Edit /etc/bind/named.conf.options on NS2:
sudo vi /etc/bind/named.conf.options
Replace contents with:
acl "trusted" {
127.0.0.1; // localhost
10.1.106.0/24; // allowed subnet
10.1.105.0/24; // allowed subnet
10.240.0.0/15; // allowed subnet
};
options {
directory "/var/cache/bind";
listen-on port 53 { any; };
listen-on-v6 port 53 { any; };
// Same policy as NS1
allow-query { trusted; };
allow-recursion { trusted; };
allow-transfer { none; }; // no transfers from this secondary by default
recursion yes;
dnssec-validation auto;
auth-nxdomain no;
empty-zones-enable yes;
max-cache-size 512M;
max-cache-ttl 604800;
max-ncache-ttl 3600;
minimal-responses yes;
qname-minimization relaxed;
version "DNS Server (ns2)";
};
This makes NS2:
– Authoritative for infosecmonkey.org (as a secondary).
– Recursive resolver for your three internal networks.
6. Firewall Rules on Both Servers
6.1 On NS1
Ensure NS1 allows DNS from NS2 and clients (if using ufw).
sudo ufw allow from 10.1.106.11 to any port 53 proto tcp
sudo ufw allow from 10.1.106.11 to any port 53 proto udp
You should already have generic DNS allow rules from the first deployment; this just makes it explicit.
6.2 On NS2
Allow DNS from clients and NS1 (for zone transfer).
sudo ufw allow 53/tcp
sudo ufw allow 53/udp
sudo ufw reload
(Optionally restrict to your internal networks and NS1 only.)
7. Validate Configuration and Trigger Zone Transfer
7.1 Check BIND Config on NS2
sudo named-checkconf
sudo systemctl restart bind9
sudo systemctl status bind9
If there is a syntax issue, named-checkconf will complain; fix and retry.
7.2 Inspect Logs During Initial Transfer
On NS2, watch the logs:
sudo journalctl -u bind9 -f
Then reload NS1 to send NOTIFY:
# On NS1
sudo rndc reload infosecmonkey.org
You should see logs on NS2 indicating an AXFR/IXFR transfer from 10.1.106.10 and zone load success.
Alternatively, force a transfer from NS2:
sudo rndc retransfer infosecmonkey.org
# or
sudo rndc refresh infosecmonkey.org
Check that /var/cache/bind/db.infosecmonkey.org now exists on NS2.
8. Update Zone File on NS1 to Advertise NS2
Clients and the parent zone (your registrar) should see two NS records for resilience.
On NS1, edit /etc/bind/db.infosecmonkey.org:
sudo vi /etc/bind/db.infosecmonkey.org
You already have something like:
; Authoritative name servers
IN NS ns1.infosecmonkey.org.
Add NS2 and its A record:
; Authoritative name servers
IN NS ns1.infosecmonkey.org.
IN NS ns2.infosecmonkey.org.
; Nameserver A records
ns1 IN A 10.1.106.10
ns2 IN A 10.1.106.11
Remember to bump the serial:
@ IN SOA ns1.infosecmonkey.org. admin.infosecmonkey.org. (
2026041801 ; Serial (updated)
3600 ; Refresh
1800 ; Retry
1209600 ; Expire
86400 ) ; Minimum TTL
Check and reload on NS1:
sudo named-checkzone infosecmonkey.org /etc/bind/db.infosecmonkey.org
sudo systemctl reload bind9
NS1 will notify NS2, which will pull the updated zone, including the NS2 NS record.
9. Testing Authoritative and Recursive Behavior on NS2
From a client in an allowed subnet (or from NS2 itself using 127.0.0.1).
9.1 Test that NS2 Serves infosecmonkey.org
dig @10.1.106.11 infosecmonkey.org
dig @10.1.106.11 ns1.infosecmonkey.org
dig @10.1.106.11 ns2.infosecmonkey.org
dig @10.1.106.11 www.infosecmonkey.org
Checks:
– status: NOERROR.
– ANSWER section matches NS1.
– AUTHORITY section shows both NS1 and NS2 as NS records.
9.2 Test Recursion on NS2
dig @10.1.106.11 google.com
dig @10.1.106.11 www.cloudflare.com
You should see successful answers with the ra (recursion available) flag.
From a non‑allowed subnet, recursion should be refused:
dig @10.1.106.11 google.com
Expected: status: REFUSED or no answer.
9.3 Failover Behavior (Quick Check)
If possible, temporarily stop BIND on NS1 and ensure NS2 continues to answer for the zone.
# On
NS1(for test only)
sudo systemctl stop bind9# From a client
dig @10.1.106.11 infosecmonkey.org
dig @10.1.106.11 www.infosecmonkey.org
You should still get correct answers from NS2.
10. Optional: Logging on NS2
You can mirror the logging config you used on NS1 to NS2 for troubleshooting AXFR/IXFR and queries.
On NS2, edit /etc/bind/named.conf.local:
sudo vi /etc/bind/named.conf.local
Add at the top:
logging {
channel default_syslog {
syslog daemon;
severity info;
};
channel query_log {
file "/var/log/named/queries.log" versions 3 size 10m;
severity info;
print-time yes;
};
category queries { query_log; };
category default { default_syslog; };
};
Create the log dir:
sudo mkdir -p /var/log/named
sudo chown bind:bind /var/log/named
sudo chmod 750 /var/log/named
sudo systemctl restart bind9
sudo tail -f /var/log/named/queries.log
Recent posts
-
-
DNS is one of those technologies that quietly underpins... Full Story
-
BGP issues on FortiGate firewalls usually trace back to... Full Story
-
Every time your laptop talks to your router, a... Full Story
-
If you've spent any time configuring NAT on a... Full Story
-
If you have spent any time configuring firewall policies... Full Story
-
High availability on FortiGate is one of those features... Full Story
-
If you've configured SD-WAN on a FortiGate, you've almost... Full Story
-
FortiLink is the management protocol that turns a FortiSwitch... Full Story
-
FortiSwitches are pretty rock solid from Mean Time Between... Full Story
-
This is a quicky tip. Have you ever gone... Full Story
-
DNS is one of those quiet pieces of internet... Full Story
-
This article is an updated version of the previous... Full Story
-
You will add ns2 as a secondary (slave) BIND9... Full Story
-
In the process of deploying my lab, I needed... Full Story
-
RFC 8805, used to be known as Self-Correcting IP... Full Story
-
Years back, I wrote an article about certificate pinning. ... Full Story
-
FortiGates have the ability to send alerts to Microsoft... Full Story
-
In this post, I am going to walk through... Full Story
-
Troubleshooting VoIP on a FortiGate can feel like trying... Full Story
-
Prior to FortiOS 7.0, there were three commands to... Full Story
-
In this post, I am going to go over... Full Story
-
What we are going to do: We are going... Full Story
-
Choosing between FGCP (FortiGate Clustering Protocol) and FGSP (FortiGate... Full Story
-
Creating a VLAN on macOS (The "Pro" Move) A... Full Story
-
This blog post explores the logic behind how macOS... Full Story
-
Pretty Fly for a Wi-Fi Tell My Wi-Fi Love... Full Story
-
Part of my daily gig is creating BoMs (Bill-of-Materials)... Full Story
-
ICMP introduces several security risks, but careful filtering, rate... Full Story
-
The command diag debug application dhcps -1 enables full... Full Story
-
In the world of FortiOS, execute tac report is... Full Story
-
LLDP; What is it The Link Layer Discovery Protocol... Full Story
-
What it actually does When you run diagnose fdsm... Full Story
-
Monkey Bites are bite-sized, high-impact security insights designed for... Full Story
-
I have run macOS in macOS with Parallels but... Full Story
-
Don't be confused with my other FortiNAC posts where... Full Story
-
This is the third session in a multi-part article... Full Story
-
Today I was configuring key-based authentication on a FortiGate... Full Story
-
Netcat, often called the "Swiss Army knife" of networking,... Full Story
-
At its core, IEEE 802.1X is a network layer... Full Story
-
In case you did not see the previous FortiNAC... Full Story
-
This is our 5th session where we are going... Full Story
-
Now that we have Wireshark installed and somewhat configured,... Full Story
-
The Philosophy of Packet Analysis Troubleshooting isn't about looking... Full Story
-
DISCLAIMER: Please see link above for the official Fortinet... Full Story
-
The underlying assumption that Let’s Encrypt requires you to... Full Story
-
FortiGate ships with thousands of built-in application signatures, but... Full Story