Post

Configuring FreeBSD as authoritative and caching name server

Setting up BIND on FreeBSD to function as both an authoritative DNS server for local development zones and a caching resolver, enabling .local domain testing across multiple devices.

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.

← Back to all posts