Setting up a FreeBSD server as a dual-purpose DNS server — both authoritative for your local development zones and a caching resolver for upstream queries — is useful for testing sites across multiple devices on a local network without editing /etc/hosts on every machine.
1. Enable BIND at Startup
Add to /etc/rc.conf:
named_enable="YES"
2. Configure BIND
Edit /etc/namedb/named.conf:
Comment out the listen-on directive (around line 22) to allow the server to respond to queries from the entire network, not just localhost:
//listen-on { 127.0.0.1; };
Uncomment and configure forwarders (around lines 38–42) to set upstream DNS servers for non-local queries:
forwarders {
8.8.8.8;
8.8.4.4;
};
Add zone declarations at the end of the file:
zone "example.local" {
type master;
file "/etc/namedb/master/example.local";
allow-transfer { localhost; };
allow-update { key rndc-key; };
};
zone "0.0.10.in-addr.arpa" {
type master;
file "/etc/namedb/master/example.local.rev";
allow-transfer { localhost; };
allow-update { key rndc-key; };
};
3. Create Zone Files
Forward lookup zone — /etc/namedb/master/example.local:
$TTL 3600
example.local. IN SOA ns2.example.local. root.example.local. (
1 ; Serial
10800 ; Refresh
3600 ; Retry
604800 ; Expire
86400 ; Minimum TTL
)
;DNS Servers
example.local. IN NS ns2.example.local.
;Machine Names - Chris
ns1.example.local. IN A 10.0.0.3
ns2.example.local. IN A 10.0.0.100
*.ca.example.local. IN A 10.0.0.2
;Machine Names - Phil
*.pg.example.local. IN A 10.0.0.6
Reverse lookup zone — /etc/namedb/master/example.local.rev:
$TTL 3600
0.0.10.in-addr.arpa. IN SOA ns2.example.local. root.example.local. (
1 ; Serial
10800 ; Refresh
3600 ; Retry
604800 ; Expire
86400 ; Minimum TTL
)
;DNS Servers
0.0.10.in-addr.arpa. IN NS ns2.example.local.
;Machine Names
2 IN PTR tamaryn.example.local
3 IN PTR ns1.example.local
6 IN PTR trinity.example.local.
100 IN PTR ns2.example.local
4. Generate the RNDC Key
rndc-confgen -a
This creates /etc/namedb/rndc.key with an HMAC-MD5 authentication key used by the zone update directives above.
5. Validate the Configuration
Check the main config file:
named-checkconf /etc/namedb/named.conf
Check each zone file:
named-checkzone example.local /etc/namedb/master/example.local
Fix any errors reported before starting BIND.
6. Configure DHCP to Use the Local DNS Server
DHCP will overwrite /etc/resolv.conf on each lease renewal. Add your local nameserver to /etc/dhclient.conf so it’s always prepended:
interface "em0" {
send dhcp-lease-time 3600;
prepend domain-name-servers 127.0.0.1, 4.4.4.4, 8.8.8.8;
request subnet-mask, broadcast-address, time-offset, routers,
domain-name, domain-name-servers;
require subnet-mask, domain-name-servers;
}
Replace em0 with your actual network interface name. The prepend directive ensures your local DNS server (127.0.0.1) is always queried first, with Google DNS as fallback.
Once started, other devices on your network can be pointed to this server’s IP as their DNS server to resolve your .local development domains.