Type something to search...
What is a DNS zone transfer (AXFR) and why should you restrict it?

What is a DNS zone transfer (AXFR) and why should you restrict it?

A DNS zone transfer is the mechanism that copies a DNS zone from a primary nameserver to its secondary nameservers, so they can all answer for the domain with identical data. AXFR (authoritative zone transfer) sends the entire zone, every record, in one go over TCP, while IXFR (incremental zone transfer) sends only the changes since a given version. You should restrict zone transfers because a server that allows AXFR to anyone hands a complete map of your domain, including internal hostnames, test systems and forgotten services, to whoever asks. The fix is to allow transfers only to your own secondaries, ideally authenticated with TSIG keys.

Zone transfers are a normal and necessary part of running DNS with more than one server, so the goal isn't to disable them. It's to make sure only the servers that should receive your zone can. In this article you'll learn how zone transfers work, what the SOA serial and NOTIFY messages have to do with them, why open transfers are a security risk, how to test your own nameservers, and how to configure BIND and NSD to allow transfers safely with TSIG.

Why Zone Transfers Exist

Every domain should have at least two authoritative nameservers, ideally in different networks, so it stays online if one fails. Those servers need the same data. One common way to achieve that is the primary-secondary model:

  • The primary (historically called the master) holds the editable copy of the zone, loaded from a zone file, a database, or a DNS provider's control panel.
  • The secondaries (historically called slaves) hold read-only copies that they fetch from the primary and refresh automatically.

The zone transfer is how a secondary fetches its copy. It's also how many organisations use a secondary DNS provider: the provider's servers act as secondaries and pull the zone from your primary.

Many managed DNS providers sync their own nameservers internally using other methods, so you may never see AXFR unless you run your own servers or use a second provider.

How a Zone Transfer Works

The SOA Serial

Every zone has an SOA (start of authority) record, which includes a serial number. Each time the zone changes, the serial must increase. Secondaries compare their serial with the primary's to decide whether they need an update.

dig example.com SOA +short
ns1.example.com. hostmaster.example.com. 2026101901 7200 3600 1209600 3600

The fields, in order, are the primary nameserver, the responsible mailbox, the serial (2026101901), the refresh interval, the retry interval, the expire time, and the negative caching TTL.

The Refresh Cycle

A secondary keeps its copy current like this:

  1. Every refresh interval (7200 seconds above), it asks the primary for the SOA record.
  2. If the primary's serial is higher than its own, it requests a transfer.
  3. If the primary can't be reached, it retries every retry interval.
  4. If it can't reach the primary for the whole expire period (14 days above), it stops answering for the zone, rather than serving data that may be badly out of date.

NOTIFY

Waiting for the refresh interval would make changes slow to spread, so primaries also send a NOTIFY message (defined in RFC 1996) to their secondaries whenever the zone changes. The secondary then checks the serial straight away and transfers the zone if it has changed. In practice, NOTIFY means secondaries update within seconds.

AXFR vs IXFR

AXFRIXFR
What is sentThe entire zoneOnly the changes between two serials
Defined inRFC 5936RFC 1995
TransportTCPTCP, or UDP for small responses
Best forInitial load, or small zonesLarge zones with frequent small changes
FallbackNot applicableFalls back to AXFR if the primary can't provide the changes

An AXFR response starts and ends with the zone's SOA record, with every other record in between. An IXFR response describes what was removed and added between the secondary's serial and the current one.

Why Open Zone Transfers Are a Risk

If a nameserver allows AXFR from anyone, any person on the internet can download the whole zone with a single command. Normally, people only learn about the names you publish or that they guess. A full transfer reveals everything:

  • Internal or forgotten hostnames, such as vpn, jenkins, staging-db or old-admin.
  • Infrastructure details, such as IP ranges, mail servers and naming conventions.
  • Third-party services you use, revealed by CNAME and TXT verification records.
  • Records that should never have been public, such as internal addresses in a zone that was meant to be split-horizon.

None of this is a vulnerability on its own, but it's exactly the reconnaissance an attacker wants before choosing a target. It also makes it trivial to find dangling records or neglected test systems. Open transfers are a classic finding in security audits and penetration tests for that reason.

A related but separate issue is zone walking. Zones signed with DNSSEC using plain NSEC records let someone list every name by following the chain of NSEC records. NSEC3 hashes the names to make this harder. That's a property of the signing method, not of zone transfers, but it's worth knowing that restricting AXFR doesn't hide names in an NSEC-signed zone.

How to Test Your Own Nameservers

You can check whether your nameservers allow public transfers with dig. Only test domains you own or are authorised to test.

First, list the authoritative nameservers:

dig example.com NS +short
ns1.example.com.
ns2.example.net.

Then request a transfer from each one from a machine that isn't one of your secondaries:

for ns in $(dig example.com NS +short); do
  echo "== $ns"
  dig @"$ns" example.com AXFR +time=5 +tries=1 | tail -n 3
done

A properly restricted server refuses:

== ns1.example.com.
; Transfer failed.
== ns2.example.net.
; Transfer failed.

If you instead see your records scrolling past, ending with a summary line such as ;; XFR size: 48 records (messages 1, bytes 1764), that server allows anyone to transfer your zone.

Check every nameserver separately. A common mistake is locking down the primary while a secondary, often one added years ago, still allows transfers to anyone.

You can also test IXFR, which needs the serial you claim to have:

dig @ns1.example.com example.com IXFR=2026101801

The same access rules should apply to IXFR as to AXFR.

How to Restrict Zone Transfers in BIND

Restrict by IP Address

The simplest restriction is an IP allowlist. Global defaults go in options, and per-zone settings override them:

options {
    // Deny transfers by default
    allow-transfer { none; };
};

zone "example.com" {
    type primary;
    file "/etc/bind/zones/db.example.com";
    allow-transfer { 198.51.100.53; 2001:db8:53::53; };
    also-notify { 198.51.100.53; 2001:db8:53::53; };
    notify yes;
};

allow-transfer lists the secondaries that may request the zone, and also-notify makes sure they receive NOTIFY messages even if they aren't listed in the zone's NS records. Recent BIND versions use primary and secondary as the zone types, with master and slave still accepted as synonyms.

IP-based rules are a good start, but they rely on source addresses, which can be spoofed in some network conditions. TCP makes spoofing much harder, but adding TSIG gives you proper authentication.

Add TSIG Authentication

TSIG (transaction signature, RFC 8945) uses a shared secret key to sign DNS messages. The primary only allows a transfer if the request is signed with the right key, and the secondary can check that the transfer really came from the primary.

Generate a key with tsig-keygen, which ships with BIND:

tsig-keygen -a hmac-sha256 xfr-example > /etc/bind/xfr-example.key
cat /etc/bind/xfr-example.key
key "xfr-example" {
	algorithm hmac-sha256;
	secret "325m5LDRJYQpCd5xdvnzoSnD9qjk98IFG++cPEhxNO0=";
};

The secret above is only an example. Generate your own, keep the file readable only by the bind user, and share it with the secondary over a secure channel.

On the primary, include the key and require it for transfers:

include "/etc/bind/xfr-example.key";

zone "example.com" {
    type primary;
    file "/etc/bind/zones/db.example.com";
    allow-transfer { key "xfr-example"; };
    also-notify { 198.51.100.53; };
    notify yes;
};

On the secondary, include the same key and tell BIND to use it when talking to the primary:

include "/etc/bind/xfr-example.key";

server 192.0.2.53 {
    keys { "xfr-example"; };
};

zone "example.com" {
    type secondary;
    file "/var/cache/bind/db.example.com";
    primaries { 192.0.2.53; };
};

The server statement means every request from this secondary to 192.0.2.53 is signed with the key, including SOA checks and transfers.

You can combine both conditions. The following allows a transfer only from the secondary's address and with the correct key, by using a nested address match list:

acl secondaries { 198.51.100.53; };

zone "example.com" {
    type primary;
    file "/etc/bind/zones/db.example.com";
    allow-transfer { !{ !secondaries; any; }; key "xfr-example"; };
};

The nested expression rejects any address that isn't in secondaries, and the remaining requests must then present the key. It's a well-known BIND idiom, but it's harder to read, so leave a comment in your configuration explaining it.

After changing the configuration, check and reload it:

sudo named-checkconf
sudo rndc reload

Test a Signed Transfer

From the secondary, dig can sign a request with the key file:

dig @192.0.2.53 example.com AXFR -k /etc/bind/xfr-example.key | tail -n 2
;; Query time: 3 msec
;; XFR size: 48 records (messages 1, bytes 1764)

The same command without -k should fail with ; Transfer failed.

How to Restrict Zone Transfers in NSD

NSD, an authoritative-only server from NLnet Labs, uses provide-xfr and notify on the primary and allow-notify and request-xfr on the secondary. A key is defined once and referenced by name:

key:
    name: "xfr-example"
    algorithm: hmac-sha256
    secret: "325m5LDRJYQpCd5xdvnzoSnD9qjk98IFG++cPEhxNO0="

zone:
    name: "example.com"
    zonefile: "/etc/nsd/zones/example.com.zone"
    notify: 198.51.100.53 xfr-example
    provide-xfr: 198.51.100.53 xfr-example

Only 198.51.100.53 presenting the xfr-example key may transfer the zone. NSD refuses transfers for zones that don't have a matching provide-xfr line, so the safe behaviour is the default. Check the configuration with:

sudo nsd-checkconf /etc/nsd/nsd.conf

Other Good Practices

Firewall TCP Port 53 Thoughtfully

Zone transfers use TCP port 53, but so do normal DNS queries with large responses, so you can't simply block TCP 53 on an authoritative server. Rely on the server's access controls and TSIG, and use the firewall only as an extra layer if your secondaries have fixed addresses.

Encrypt Transfers If They Cross Untrusted Networks

TSIG authenticates a transfer but doesn't encrypt it, so the zone contents still cross the network in plain text. RFC 9103 defines XoT, zone transfer over TLS, which encrypts the transfer as well. Support is available in recent versions of BIND, NSD and other servers. If your secondaries are at another provider across the public internet and your zone contains anything sensitive, it's worth considering.

Keep Internal Names Out of Public Zones

The safest data is data that isn't in a public zone at all. Put internal hostnames in a separate internal zone or a split-horizon view that's only served to your own network. Then even an accidental open transfer reveals far less.

Monitor Transfer Attempts

BIND logs transfer requests in the xfer-out category. Logging it to a dedicated file makes it easy to spot unexpected attempts:

logging {
    channel xfer_log {
        file "/var/log/named/xfer.log" versions 5 size 10m;
        print-time yes;
        severity info;
    };
    category xfer-out { xfer_log; };
    category security { xfer_log; };
};

Refused transfers appear as messages such as zone transfer 'example.com/AXFR/IN' denied. A steady trickle is normal internet background noise, but a new source you don't recognise succeeding is worth investigating immediately.

Keep Secondaries in Sync

Restricting transfers shouldn't stop your own secondaries from updating. After any configuration change, compare SOA serials across all nameservers:

for ns in $(dig example.com NS +short); do
  printf '%-22s' "$ns"
  dig @"$ns" example.com SOA +short | awk '{print $3}'
done

All of them should report the same serial within a short time of a change.


FAQ: DNS Zone Transfers

AXFR transfers the entire zone, every record, in one operation. IXFR transfers only the changes between the secondary's serial and the primary's current serial, which is more efficient for large zones that change frequently.

It's an information disclosure rather than a direct way in. It reveals every name and address in your zone, including internal and forgotten systems, which gives attackers a complete map for reconnaissance. It should always be fixed.

Run dig with the AXFR query type against each of your authoritative nameservers from a machine that isn't one of your secondaries. A properly restricted server responds with Transfer failed.

TSIG is a way of signing DNS messages with a shared secret key. When used for zone transfers, the primary only sends the zone to requests signed with the right key, and the secondary can verify the transfer really came from the primary.

AXFR always uses TCP. IXFR normally uses TCP too, although a small incremental response can be sent over UDP. That's one reason authoritative servers must accept TCP connections on port 53.

Not completely. Names can still be discovered through guessing, Certificate Transparency logs, and, for zones signed with plain NSEC, by walking the NSEC chain. Restricting transfers removes the easiest route to a full list.

Usually not, because the provider keeps its nameservers in sync internally. You'll use zone transfers if you run your own primary, or if you add a secondary DNS provider that pulls your zone from another provider or your own server.


Conclusion

A zone transfer is how secondary nameservers get their copy of your zone, using AXFR for the full zone or IXFR for just the changes, triggered by SOA serial changes and NOTIFY messages. It's an essential part of running redundant DNS, but a nameserver that allows transfers to anyone gives away a complete inventory of your domain in a single query.

Restrict transfers to your own secondaries, authenticate them with TSIG keys, and test every authoritative server from outside to confirm that a public AXFR request fails. Keep internal names out of public zones, log transfer attempts, and consider zone transfer over TLS when transfers cross the internet. Those steps keep your secondaries in sync without handing your DNS map to anyone who asks.

Tags :
Share :

Related Posts

What is the difference between an A record and a CNAME record?

What is the difference between an A record and a CNAME record?

The difference between an A record and a CNAME record is what they point to. An A record points a hostname directly at an IPv4 address, such

Dive Deeper
What are the best DNS providers for websites?

What are the best DNS providers for websites?

The best DNS providers for most websites are Cloudflare for a fast, free, easy starting point, Amazon Route 53 if you already run on AWS, **G

Dive Deeper
What are the best public DNS resolvers?

What are the best public DNS resolvers?

The best public DNS resolvers for most people are Cloudflare (1.1.1.1) for speed and privacy, Google Public DNS (8.8.8.8) for reliability and

Dive Deeper