BIND can be a real pain to configure if you’re not used to it, but once you get the hang of it, it’s incredibly powerful. Adding SRV and TXT records is a common task, and it’s a good way to get a feel for BIND’s zone file syntax.

Let’s say you want to add an SRV record for a service called _sip._tcp.example.com that points to a server sip.example.com on port 5060, and a TXT record for _dmarc.example.com.

Here’s what your example.com.zone file might look like before you make any changes:

$TTL 86400
@       IN      SOA     ns1.example.com. admin.example.com. (
                        2023102701 ; serial
                        3600       ; refresh
                        1800       ; retry
                        604800     ; expire
                        86400      ; minimum TTL
                        )

@       IN      NS      ns1.example.com.
@       IN      NS      ns2.example.com.

ns1     IN      A       192.0.2.1
ns2     IN      A       192.0.2.2

www     IN      A       192.0.2.3
mail    IN      A       192.0.2.4

To add the SRV record, you’ll need to define the priority, weight, port, and target hostname. For _sip._tcp.example.com, let’s say we want a priority of 10, a weight of 5, and it should point to sip.example.com on port 5060.

The SRV record syntax is: _service._proto.name. TTL CLASS SRV priority weight port target.

So, for our _sip._tcp.example.com record, it will look like this:

_sip._tcp       IN      SRV     10 5 5060 sip.example.com.

Notice the trailing dots. These are crucial in BIND zone files. They signify the end of a fully qualified domain name (FQDN). If you omit the dot after example.com. in sip.example.com., BIND will append the zone’s origin (example.com), making it sip.example.com.example.com, which is probably not what you want.

Now, for the TXT record. TXT records are commonly used for things like SPF, DKIM, and DMARC. Let’s add a DMARC record for _dmarc.example.com. A simple DMARC record might look like this:

_dmarc.example.com. TTL CLASS TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"

The TXT record syntax is: name. TTL CLASS TXT "string"

So, our TXT record entry will be:

_dmarc          IN      TXT     "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"

Here, we’ve omitted the _dmarc. part because BIND will automatically append the zone origin (example.com) to _dmarc, resulting in _dmarc.example.com. If your TXT string is longer than 255 characters, you can split it into multiple quoted strings, and BIND will concatenate them automatically. For example: "first part" "second part".

Putting it all together in our example.com.zone file, it would look like this:

$TTL 86400
@       IN      SOA     ns1.example.com. admin.example.com. (
                        2023102702 ; serial - incremented!
                        3600       ; refresh
                        1800       ; retry
                        604800     ; expire
                        86400      ; minimum TTL
                        )

@       IN      NS      ns1.example.com.
@       IN      NS      ns2.example.com.

ns1     IN      A       192.0.2.1
ns2     IN      A       192.0.2.2

www     IN      A       192.0.2.3
mail    IN      A       192.0.2.4

; SRV Record for SIP
_sip._tcp       IN      SRV     10 5 5060 sip.example.com.

; TXT Record for DMARC
_dmarc          IN      TXT     "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"

Crucially, you MUST increment the serial number in your SOA record every time you make a change to the zone file. If you don’t, BIND’s slave servers won’t pick up the changes. The standard format is YYYYMMDDnn, where nn is a two-digit sequence number for that day.

After saving the zone file, you need to tell BIND to reload its configuration. The command for this depends on your BIND version and system. For systemd systems, it’s usually:

sudo systemctl reload named

Or, if you’re using rndc:

sudo rndc reload example.com.

To verify your changes, you can use dig:

dig SRV _sip._tcp.example.com @localhost
dig TXT _dmarc.example.com @localhost

The output should show your newly added records.

The most surprising thing about BIND’s zone file syntax is how the lack of a trailing dot can silently lead to incorrect FQDNs being registered, often causing services to fail to resolve. BIND interprets a name without a trailing dot as relative to the zone’s origin, which is usually the domain itself. So, if you define sip instead of sip., BIND might try to resolve sip.example.com.example.com.

Once you’ve got SRV and TXT records working, the next logical step is to explore CNAME records for aliasing and understanding how to manage multiple A records for load balancing.

Want structured learning?

Take the full Bind course →