DNS is a lot like a phone book for the internet, but the same phone book can’t be used by everyone for everything.

Imagine you’re running a company with a public website and internal servers that only employees should access. You need two different phone books: one for the outside world to find your public website, and another for your internal network to find your internal servers. This is exactly what Split DNS with BIND does.

Let’s see it in action. We’ll set up BIND to serve two distinct views: external for the public internet and internal for our private network.

Here’s a simplified named.conf snippet demonstrating the core idea:

// Global options
options {
    directory "/var/named";
    allow-query { any; }; // Default for external, but we'll refine
};

// Define our internal zone
zone "internal.example.com" {
    type master;
    file "db.internal.example.com";
    allow-transfer { internal_clients; };
};

// Define our external zone
zone "example.com" {
    type master;
    file "db.example.com";
    allow-transfer { external_clients; };
};

// ACL for internal clients
acl "internal_clients" { 192.168.1.0/24; 10.0.0.0/8; };

// ACL for external clients (or just 'any' for public access)
acl "external_clients" { any; };

// Define the views
view "internal" {
    match-clients { internal_clients; };
    recursion yes;
    include "/etc/named/zones.internal"; // Contains internal zone definitions
};

view "external" {
    match-clients { external_clients; };
    recursion no; // Typically no recursion for external resolvers
    include "/etc/named/zones.external"; // Contains external zone definitions
};

And within /etc/named/zones.internal and /etc/named/zones.external, you’d have your zone files. For example:

/etc/named/zones.internal:

zone "internal.example.com" {
    type master;
    file "db.internal.example.com";
};

/etc/named/zones.external:

zone "example.com" {
    type master;
    file "db.example.com";
};

Notice how the same domain name (example.com in this case, but often different subdomains or entirely different TLDs are used for internal) can have different IP addresses depending on who’s asking.

Consider a client at 192.168.1.10 (internal) querying for internal.example.com. BIND will match this client against the internal view. The internal view is configured to serve internal.example.com and potentially resolve names within internal.example.com to private IP addresses like 10.0.1.5.

Now, a client from the public internet (say, 203.0.113.5) queries for example.com. BIND matches this client against the external view. The external view serves example.com and resolves it to a public IP address like 198.51.100.20. Crucially, the external view will not see or serve internal.example.com.

The problem Split DNS solves is the need for a single DNS infrastructure to present different information to different audiences. Without it, you’d either:

  1. Expose internal servers to the internet (a huge security risk).
  2. Use a separate, complex DNS infrastructure for internal use, duplicating zones and maintenance.
  3. Force internal users to use public DNS for internal resources, which doesn’t work.

BIND’s view clause is the mechanism. It allows you to define multiple view blocks, each with a match-clients clause. When a query arrives, BIND checks which view’s match-clients criteria the source IP address satisfies. It then uses the zone configurations and options defined within that specific view to answer the query. This provides a clean separation of concerns and security.

The match-clients directive is incredibly powerful. You can match on IP addresses, IP address ranges, or even the interface the query arrived on. This allows for granular control over who sees what. You can also use match-destinations to match on the IP address the query was sent to, which is useful if you have a single BIND server answering queries for multiple IP addresses.

The most surprising thing is how commonly this is misunderstood as simply "having two zone files." It’s not just about the data; it’s about the entire lookup environment. A query within the internal view might have recursion enabled, allowing it to ask other internal DNS servers for further resolution. The external view, however, typically has recursion disabled, meaning it will only answer for zones it is authoritative for and will not forward requests to external resolvers. This prevents your internal DNS server from becoming an open resolver for the internet.

Once you have Split DNS configured, the next logical step is to consider DNSSEC for your external zones to ensure authenticity and integrity for public-facing records, while internal zones might focus more on access control and performance.

Want structured learning?

Take the full Bind course →