Authoritative DNS on FreeBSD
Purpose
This document explains how to build an authoritative DNS resolver using BIND9 on FreeBSD.
This example uses an example domain (also called a 'zone') and a single internal subnet. Any number of domain names and reverse zones can be added to the resolver.
All systems can use the resolver on your internal network. It will resolve and cache answers from public resolvers and answer queries for names defined on your internal network.
Procedure
Install FreeBSD
Install a recent version of FreeBSD. This guide uses version 14.1.
The system should be configured with a static IP address.
This guide will use these values as examples:
- internal subnet:
192.168.3.0/24
- internal domain:
secure.mydomain.com
- system's static IP address:
192.168.3.5
- system's FQDN:
ns.secure.mydomain.com
Ensure the hostname
property in /etc/rc.conf
is set to an FQDN that uses your 'internal' domain name.
Don't forget to update your /etc/hosts
file with your FQDN and new static IP address.
Finally, install the Package database by running pkg update
as the root user and following the prompts.
If you run:
You should see ICMP replies from the FQDN you configured:
user@ns:~ $ ping -c 3 `hostname`
PING ns.secure.mydomain.com (192.168.3.5): 56 data bytes
64 bytes from 192.268.3.5: icmp_seq=0 ttl=64 time=0.062 ms
64 bytes from 192.268.3.5: icmp_seq=1 ttl=64 time=0.079 ms
64 bytes from 192.268.3.5: icmp_seq=2 ttl=64 time=0.104 ms
--- ns.secure.mydomain.com ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.062/0.081/0.104/0.017 ms
Install BIND
Use the package database to install BIND9:
BIND9 configuration files are in /usr/local/etc/namedb
.
Enable BIND9 and tell it to return only IPv4 addresses to clients by adding these lines to your /etc/rc.conf
file:
BIND9's binary is named named
.
BIND9 can be controlled by using /usr/local/etc/rc.d/named
with the following options:
stop
- stop the named servicestart
- start the named servicerestart
- restart the named service; this flushes all cached entriesreload
- reload the configuration and local zone files, but do not flush any cached entries
Configure BIND
Caching Only Resolver
Most default options in the /usr/local/etc/named/namedb.conf
file are sane and can be left configured as the default values.
After removing all of the comments, the namedb.conf
file should look like this:
options {
directory "/usr/local/etc/namedb/working";
pid-file "/var/run/named/pid";
dump-file "/var/dump/named_dump.db";
statistics-file "/var/stats/named.stats";
zone-statistics yes;
listen-on { any; };
allow-query { any; };
disable-empty-zone "255.255.255.255.IN-ADDR.ARPA";
disable-empty-zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA";
disable-empty-zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA";
};
zone "." { type hint; file "/usr/local/etc/namedb/named.root"; };
Start the resolver:
Check to make sure it started correctly and is running:
Test the resolver by using nslookup
to ask the IP address of your resolver to look up a public DNS name:
root@ns:~ # nslookup - 192.168.3.5
> google.com
Server: 192.168.3.5
Address: 192.168.3.5#53
Non-authoritative answer:
Name: google.com
Address: 142.250.72.46
Name: google.com
Address: 2607:f8b0:400f:804::200e
> exit
The resolver listening on 192.168.3.5 is able to resolve public DNS names.
This DNS server can now be used as an internal DNS resolver instead of something like Google's 8.8.8.8
or Cloudfare's 1.1.1.1
public resolvers.
Forward Authoritative Zone
Now that the resolver is working, you can add a forward zone definition file for your secure.mydomain.com
internal domain.
A forward zone file contains all of the name --> IP mappings for a domain name. The BIND9 Documentation describes the details and syntax of a zone file.
All authoritative zone files go in your resolver's /usr/local/etc/namedb/primary
directory.
Create a file named /usr/local/etc/namedb/primary/secure.mydomain.com.db
and paste the contents:
$ORIGIN secure.mydomain.com.
$TTL 3h
@ SOA ns.secure.mydomain.com. email.address.com. (
2024070401 ; serial
1d ; refresh
12h ; retry
1w ; expire
3h ; TTL
)
NS ns.secure.mydomain.com.
ns A 192.168.3.5
Save the file and exit the editor.
Add the forward zone file to /usr/local/etc/named/namedb.conf
at the end of the file:
// hosted zones
zone "secure.mydomain.com" {
type primary;
file "/usr/local/etc/namedb/primary/secure.mydomain.com.db";
};
Restart named
to pick up the changes:
Try to resolve the DNS name you just defined in the forward zone:
root@ns:~ # nslookup - 192.168.3.5
> ns.secure.mydomain.net
Server: 192.168.3.5
Address: 192.168.3.5#53
Name: ns.secure.mydomain.com
Address: 192.168.3.5
> exit
Your resolver is now answering questions about hostnames in the secure.mydomain.com
zone.
If you run into trouble, check the syslog for errors about named:
Reverse Authoritative Zone
A reverse zone file contains all of the IP --> name mappings for a subnet. APICNET has a guide for reverse zone files that is worth reviewing.
Keep in mind that IP addresses are reversed in DNS zone files. An IP address of 192.168.3.5
would appear in a reverse zone file record as 5.3.168.192.in-addr.arpa.
.
All authoritative zone files go in your resolver's /usr/local/etc/namedb/primary
directory.
Create a file named /usr/local/etc/namedb/primary/3.168.192.in-addr.arpa.db
and paste the contents:
$ORIGIN 3.168.192.in-addr.arpa.
$TTL 3h
@ SOA ns.secure.mydomain.com. email.address.com. (
2024012801 ; serial
1d ; refresh
12h ; retry
1w ; expire
3h ; TTL
)
NS ns.secure.mydomain.com.
5 IN PTR ns.secure.mydomain.com.
Add the reverse zone file to /usr/local/etc/named/namedb.conf
at the end of the file:
// hosted zones
zone "3.168.192.in-addr.arpa." {
type primary;
file "/usr/local/etc/namedb/primary/3.168.192.in-addr.arpa.db";
};
Restart named
to pick up the changes:
Try to resolve the IP address you just defined a name for in the reverse zone:
root@ns:~ # nslookup - 192.168.3.5
> 192.168.3.5
5.3.168.192.in-addr.arpa name = ns.secure.mydomain.com.
> exit
Your resolver is now answering questions about IP addresses in the 3.168.192.in-addr.arpa
zone.
If you run into trouble, check the syslog for errors about named:
Configuring Local Resolver
Now that you have a resolver running on your network, you must tell all your machines to use it. If you don't do this, your systems will not use the resolver you just built, and none of the records you configured in your zones will be resolvable.
Usually, you can edit the /etc/resolv.conf
file and change the IP address of the nameserver
parameter.
If you are using NetworkManager to manage your IP stack configuration, run nmtui
and configure the resolver for your interface(s).
Notes About DNS Zone Files
Important things to remember about DNS zone files:
Terminating Names
Omitting the left-hand side of a resource record in a zone file is shorthand for $ORIGIN
.
For example, this data in a zone file:
would get expanded and parsed as:
All names in zone files that are not terminated with a dot (.
) will get the $ORIGIN
value appended to them. This is a shorthand way to avoid typing in the full domain name for every record.
For example, a record defined in a zone file like this:
will result in the zone file A record being loaded as:
Zone File Serial Numbers
Most of the header data in the zone file can be left alone, but you must update the serial number of the zone file every time the zone file is changed.
The usual format of zone file serial numbers is: YYYYMMDDnn
.
Reverse Zone Naming
Reverse DNS zones that map IP addresses to names are also called 'in-addr.arpa' zones.
All IP addresses in reverse zones appear in reverse order and must end with .in-addr.arpa.
.
For example, the IP address 192.168.3.5
appears in reverse zones files as 5.3.168.192.in-addr.arpa.
.