BIND’s allow-query and allow-transfer directives are your primary tools for controlling access to your DNS zones. These aren’t just about security; they’re about operational hygiene, preventing unauthorized information disclosure, and ensuring your DNS infrastructure remains stable.

Let’s see this in action with a typical named.conf snippet:

zone "example.com" IN {
    type master;
    file "zones/db.example.com";
    allow-query { 192.168.1.0/24; 10.0.0.5; localhost; localnets; };
    allow-transfer { 192.168.1.0/24; 10.0.0.5; };
};

In this example, allow-query permits queries from the entire 192.168.1.0/24 subnet, a specific host 10.0.0.5, and any client on the local network interface (localhost and localnets). allow-transfer is more restrictive, only allowing zone transfers to the same subnet and the specific host.

The allow-query directive dictates which IP addresses or networks are permitted to send any DNS query to this specific zone. This is crucial because even a simple NS record query can reveal information about your DNS infrastructure. allow-transfer is even more sensitive. It controls which IP addresses are allowed to perform a zone transfer (AXFR or IXFR). Zone transfers are typically used by secondary DNS servers to synchronize zone data. Allowing unauthorized zone transfers means an attacker could obtain a complete copy of your zone file, exposing all your internal hostnames, IP addresses, and potentially other sensitive service information.

The keywords localhost and localnets are powerful shorthands. localhost typically resolves to 127.0.0.1 and ::1. localnets refers to all networks configured on the BIND server’s network interfaces. Using localnets is convenient but can be overly broad if your server has many network interfaces and you only want to allow access from specific ones.

You can also use ACLs (Access Control Lists) to simplify complex configurations. Consider this:

acl "internal_networks" {
    192.168.1.0/24;
    10.0.0.0/8;
    172.16.0.0/12;
};

acl "trusted_resolvers" {
    192.168.1.10;
    192.168.1.11;
};

zone "example.com" IN {
    type master;
    file "zones/db.example.com";
    allow-query { internal_networks; trusted_resolvers; localhost; };
    allow-transfer { internal_networks; };
};

Here, we’ve defined internal_networks and trusted_resolvers ACLs. This makes the allow-query and allow-transfer directives much cleaner and easier to manage. If your internal IP ranges change, you only need to update the ACL definition, not every zone stanza.

The most surprising true thing about allow-query and allow-transfer is that they default to allowing all queries and transfers if not specified. This is a common oversight that leaves your DNS zones wide open by default. You must explicitly define these directives to restrict access.

Furthermore, BIND has a default allow-query and allow-transfer for the entire server, specified in the options block. If a zone doesn’t have its own allow-query or allow-transfer directive, it inherits these global settings. However, if a zone does have its own directive, it overrides the global one for that specific zone. This hierarchy is critical for understanding why a change might not take effect as expected.

Consider the interaction between allow-query and allow-transfer with the type directive. For type master zones, allow-transfer is paramount for replicating data to secondaries. For type slave (now type secondary) zones, these directives are less relevant on the secondary itself, as it’s receiving data, not serving it to arbitrary clients (though its own allow-query would still apply).

A common misconception is that allow-query prevents zone transfers. They are distinct. allow-query controls general DNS lookups, while allow-transfer specifically governs the replication of the entire zone file. You might want to allow queries from a wider audience (e.g., the internet for public zones) but restrict transfers only to your designated secondary DNS servers.

The most important thing to remember is that BIND’s default behavior is to be permissive. If you’re serving any zones, especially those containing internal hostnames or sensitive information, you need to implement explicit allow-query and allow-transfer rules. Failure to do so is a significant security vulnerability.

The next step after mastering access control for zones is understanding how to use view clauses to serve different DNS data to different clients.

Want structured learning?

Take the full Bind course →