What’s up guys! Welcome or welcome back to the blog. Now that our lab environment is up and running, it’s time to start laying down some of the core services that everything else will depend on. First up: DNS.
You’ve probably heard the classic joke: “It’s always DNS.” That’s because DNS is the backbone of your environment—it touches nearly everything. Think of it like a phone book. Without it, your systems wouldn’t know how to find anything by name.
Running your own DNS server isn’t just about speed. It’s about privacy and control. Keeping DNS queries local means you’re not handing your network data to third-party providers. In today’s post, we’re going to set up BIND9—an open-source DNS server that gives you complete control and helps you understand DNS from the inside out.
What is DNS?
DNS (Domain Name System) translates human-friendly names like google.com into IP addresses that machines use to communicate. It’s how you go from typing a name in your browser to loading a website.
In our setup, DNS will help internal devices refer to each other by name. Instead of remembering IP addresses, we’ll use fully qualified domain names (FQDNs). That makes everything cleaner and scalable.
Step 1: Set Up an LXC Container for BIND9
I’m using Proxmox for virtualization and running all my core services—including DNS and certificate authority—inside LXC containers. If you’re not familiar with LXC, check out my Proxmox Core Components video.
Pull down a container template (Ubuntu 25.04 in my case).
Create a new LXC container in Proxmox:
- Give it a descriptive name (e.g. dns-test).
- Use an unprivileged container with nesting enabled for better security and full systemd support.
- Assign a static IP (e.g. 192.168.2.3/24).
- Set the gateway (e.g. 192.168.2.1).
- Make sure “Start at boot” is enabled.
Once your container is created, SSH into it or use the Proxmox console. Make sure it has internet access and run the usual update commands:
- apt update && apt upgrade -y
Step 2: Install BIND9
Inside the container:
- apt install bind9 bind9utils bind9-doc -y
- That will install the DNS server, its utilities, and documentation.
Step 3: Set Proper Permissions
Make sure the bind user owns the following directories:
- chown -R bind:bind /etc/bind
- chown -R bind:bind /var/cache/bind
- mkdir -p /var/log/bind && chown -R bind:bind /var/log/bind
This prevents permission issues when BIND tries to read or write to those folders.
Step 4: Configure the Forward Zone
Edit /etc/bind/named.conf.local to define your forward zone:
zone "testlab.com" {
type master;
file "/etc/bind/db.teslab.com";
allow-update { none; };
};
Then copy the default zone file to match your domain:
- cp /etc/bind/db.local /etc/bind/db.testlab.com
Edit db.ktechlab.com and define your SOA and A records. For example:

Step 5: Configure the Reverse Zone
In the same named.conf.local file, add:
zone "2.168.192.in-addr.arpa" {
type master;
file "/etc/bind/db.192.168.2";
allow-update { none; };
};
Create the reverse zone file:
- cp /etc/bind/db.127 /etc/bind/db.192.168.2
Update the PTR record to match your A record:

Step 6: Set Up a Recursive Resolver.
To make BIND recursive, create a root hints file:
- wget -O /etc/bind/db.root https://www.internic.net/domain/named.cache
Then configure /etc/bind/named.conf.options like this:
options {
directory "/var/cache/bind";
// No forwarders this server will perform full recursion
// forwarders { };
// Allow queries only from your subnet
allow-query {
192.168.2.0/24;
};
// Allow recursive queries only from your subnet
allow-recursion {
192.168.2.0/24;
};
recursion yes;
dnssec-validation auto;
// Listen only on this server's IP
listen-on {
192.168.2.3;
};
// Disable IPv6 completely
//listen-on-v6 { none; };
};
This locks down your DNS server so it only responds to your subnet and queries root servers directly (not public resolvers).
Step 7: Restart and Test
Restart BIND:
- systemctl restart bind9
- systemctl status bind9
Test forward and reverse lookups:
- dig @localhost teslab.com
- dig -x 192.168.2.3 @localhost
Update your container’s /etc/resolv.conf to use the new DNS server:
- nameserver 192.168.2.3
- search ktechlab.com
Final Thoughts
That’s it! You now have a fully functional, recursive BIND9 DNS server running in a Proxmox LXC container. We covered forward zones, reverse zones, and root hint configuration. Manual configuration takes effort, but it teaches you how DNS actually works under the hood.
In future videos, we’ll build on this foundation by setting up a certificate authority to secure internal services and eliminate SSL errors. If you enjoy this kind of content don’t forget to subscribe, and—as always—stay geeking. Peace!