How to Set Up Cloudflare Internal DNS for Your Network
What Is Internal DNS and Why Does It Matter for Private Networks?
If you've ever managed infrastructure across multiple offices, cloud environments, or remote teams, you've almost certainly wrestled with internal DNS. It's one of those foundational pieces of networking that most developers and sysadmins don't think about until something breaks — and when it breaks, everything breaks.
Internal DNS is the system that resolves hostnames within your private network. While public DNS handles the translation of example.com to an IP address for the entire internet, internal DNS handles names like db.internal.company.com or vpn.corp.local that only exist within your organization's network. These private hostnames need to resolve reliably for employees, services, and automated systems to communicate with each other.
Cloudflare's recent general availability of Internal DNS is a good prompt to step back and understand how internal DNS actually works, why it's harder than it looks to get right, and what modern approaches to private DNS look like — especially in the context of Zero Trust architectures.
How Internal DNS Works: The Basics
DNS, at its core, is a distributed database that maps names to addresses. For internal DNS, there are two key roles:
Authoritative DNS
An authoritative DNS server holds the actual records for a zone. When you create a DNS record like api.internal → 10.0.1.45, that record lives on an authoritative server. Any resolver that needs to look up api.internal will ultimately query this authoritative server to get the answer.
In traditional corporate environments, these were often Microsoft Active Directory DNS servers or BIND instances running on-premises. Every record had to be manually managed, and there was no redundancy unless you explicitly set up secondary servers.
Recursive DNS (Resolvers)
A recursive resolver is what your machines actually talk to when they need to look something up. It takes a query, figures out which authoritative servers to ask, fetches the answer, caches it, and returns it to the client.
In a private network context, your recursive resolver needs to know: "When someone asks for *.internal, query this authoritative server, but for everything else, use the public internet DNS." This split-brain DNS configuration is where complexity starts to compound.
Split-Horizon DNS
Split-horizon (or split-brain) DNS is a configuration where the same hostname resolves to different addresses depending on where the query originates. For example:
- From inside the corporate network:
api.company.com→10.0.1.45(private IP) - From the public internet:
api.company.com→203.0.113.22(public IP)
This is extremely common in organizations that want internal services accessible by a friendly name without exposing internal IP addresses externally. It's also a significant source of operational headaches when misconfigured.
The Classic Internal DNS Setup (And Its Problems)
For decades, the typical internal DNS setup looked something like this:
- Two or three DNS servers running on-premises (primary + secondary for redundancy)
- DHCP configured to hand out internal DNS server IPs to clients
- Forwarders configured to send public DNS queries upstream
- Manual record management, often through a GUI or editing zone files directly
This works fine in a stable, single-location environment. But it falls apart quickly in several modern scenarios:
Remote Workers and VPN
When employees work from home, they connect via VPN. The VPN client typically pushes DNS settings to route internal queries through the tunnel. If the VPN is misconfigured, split tunneling is enabled incorrectly, or the DNS server is unreachable, internal hostnames stop resolving — and the user just sees "server not found" with no clear indication of why.
Multi-Cloud Environments
Modern infrastructure spans AWS, GCP, Azure, and on-premises data centers. Each cloud provider has its own internal DNS system (Route 53 private zones, Azure Private DNS, GCP Cloud DNS). Making these all work together — so that a service in AWS can resolve a hostname that lives in your on-premises DNS — requires careful configuration of DNS forwarding rules, VPC DNS settings, and often third-party solutions.
Latency and Reliability
If your internal DNS servers are in one geographic location and your teams or workloads are distributed globally, DNS resolution latency adds up. A 200ms DNS lookup that happens dozens of times per page load or API call has a measurable impact on application performance.
Zero Trust Transitions
Traditional internal DNS assumes a perimeter. Clients inside the network get access to internal DNS; everyone else doesn't. But Zero Trust architectures eliminate the concept of a trusted perimeter — access is based on identity and context, not network location. This means your DNS infrastructure needs to work for users who are never "inside" the network in the traditional sense.
Modern Approaches to Internal DNS
Given these challenges, organizations have increasingly moved toward more sophisticated DNS architectures. Here's what modern internal DNS looks like in practice.
DNS Over VPN with Split Tunneling
The most common immediate solution is careful VPN configuration. Split tunneling allows you to route only traffic destined for internal networks through the VPN tunnel, while public traffic goes directly to the internet. DNS split tunneling specifically routes internal DNS queries through the VPN while public queries go to the user's local resolver.
A typical configuration in a WireGuard-based VPN might look like:
[Interface]
DNS = 10.0.0.53, 8.8.8.8
[Peer]
AllowedIPs = 10.0.0.0/8, 192.168.0.0/16
But this still depends on the internal DNS server at 10.0.0.53 being reachable, highly available, and correctly configured with all internal records.
DNS Over HTTPS (DoH) for Internal Resolvers
Modern Zero Trust clients increasingly use DNS over HTTPS for internal resolution. Instead of sending DNS queries in plaintext over UDP port 53, queries are sent as HTTPS requests to a resolver endpoint. This has several advantages:
- Queries are encrypted and can't be intercepted on the network
- The resolver endpoint can enforce authentication and access policies
- It works over any network connection, not just VPN tunnels
An example of configuring a DoH-capable resolver in a system like systemd-resolved:
[Resolve]
DNS=https://dns.internal.company.com/dns-query
DNSOverTLS=yes
Domains=~internal.company.com ~corp.local
Conditional Forwarding
For hybrid environments, conditional forwarding lets your resolver make intelligent routing decisions. Here's an example using BIND's configuration syntax:
acl "internal_clients" {
10.0.0.0/8;
192.168.0.0/16;
};
view "internal" {
match-clients { internal_clients; };
zone "internal.company.com" {
type primary;
file "/etc/bind/zones/internal.company.com.db";
};
zone "aws.company.com" {
type forward;
forwarders { 10.1.0.2; }; // Route 53 Resolver inbound endpoint
};
};
view "external" {
match-clients { any; };
zone "company.com" {
type primary;
file "/etc/bind/zones/company.com.external.db";
};
};
This configuration gives internal clients access to private zones while presenting a different view to external resolvers.
DNS in Zero Trust Architectures
Zero Trust networking fundamentally changes how internal DNS needs to work. In a Zero Trust model:
- Users connect from anywhere, on any network
- Access is granted based on identity, device posture, and policy — not network location
- There is no "inside" the network in the traditional sense
This creates a DNS challenge: how do you resolve internal hostnames for users who aren't connected to your internal network, without exposing those DNS records publicly?
The answer is a private DNS resolver that's tied to your identity and access layer. When a user authenticates to your Zero Trust platform, they get access to a resolver that can answer queries for internal zones — but only for the zones and records they're authorized to access.
This is architecturally different from traditional DNS, which is purely network-based. A Zero Trust DNS system might:
- Authenticate the user's device and identity before answering queries
- Return different answers based on the user's access policies
- Log all DNS queries for security monitoring and compliance
- Block resolution of known-malicious domains as a security control
DNS as a Security Control
Internal DNS isn't just about name resolution — it's a powerful security tool. By controlling what your internal resolver will and won't answer, you can:
- Block malware C2 communication: If malware on an internal machine tries to resolve a known-bad domain, your resolver can return NXDOMAIN or a sinkhole IP
- Prevent data exfiltration via DNS tunneling: Monitor for unusually long or high-entropy DNS queries that might indicate data being encoded in DNS requests
- Enforce split-horizon policies: Ensure internal services are only accessible through appropriate paths
Diagnosing Internal DNS Problems
When internal DNS breaks, the debugging process can be frustrating. Here's a systematic approach:
Step 1: Verify Basic Connectivity
Before blaming DNS, confirm the client can reach the DNS server at all:
# Test if the DNS server is reachable
nc -uvz 10.0.0.53 53
# Or with nmap
nmap -p 53 -sU 10.0.0.53
Step 2: Test Resolution Directly
Query the internal DNS server directly, bypassing any system resolver configuration:
# Query specific server for internal hostname
dig @10.0.0.53 api.internal.company.com
# Check what your system resolver is using
cat /etc/resolv.conf
# On macOS, check scoped resolvers
scutil --dns
Step 3: Check for Split-Brain Issues
If a hostname resolves differently from different locations, you may have a split-brain configuration issue:
# Query public resolver
dig @8.8.8.8 api.company.com
# Query internal resolver
dig @10.0.0.53 api.company.com
# Compare results
Step 4: Trace the Resolution Path
For complex forwarding chains, trace where the resolution is actually happening:
# Use +trace to follow the full delegation chain
dig +trace api.internal.company.com @10.0.0.53
# Check TTL values to understand caching behavior
dig +ttl api.internal.company.com
Step 5: Check External DNS Health
For public-facing components of your DNS infrastructure, tools like OpDeck's DNS Lookup let you check your DNS records from external vantage points, verify propagation, and confirm that your public-facing records are resolving correctly across different resolvers globally.
Monitoring and Observability for Internal DNS
DNS is often invisible until it breaks. Building proper observability into your internal DNS infrastructure means:
Query Logging
Enable query logging on your authoritative and recursive resolvers. In BIND:
logging {
channel query_log {
file "/var/log/named/queries.log" versions 5 size 20m;
print-time yes;
print-severity no;
print-category no;
};
category queries { query_log; };
};
In CoreDNS (popular in Kubernetes environments):
.:53 {
log
errors
forward . 8.8.8.8 8.8.4.4
}
internal.company.com:53 {
log
file /etc/coredns/zones/internal.company.com
}
Metrics and Alerting
Key metrics to track for DNS health:
- Query rate: Sudden spikes can indicate a misconfiguration causing retry storms or a security incident
- NXDOMAIN rate: High rates of "name not found" responses often indicate broken application configurations
- Resolution latency: P95 and P99 latency for both internal and forwarded queries
- Cache hit rate: Low cache hit rates can indicate TTL misconfiguration
Security Auditing
For compliance and security purposes, you should also regularly audit your external DNS posture. OpDeck's SSL Certificate Checker helps verify that the certificates on your public-facing services (including any public DNS-over-HTTPS endpoints) are valid and properly configured. Similarly, running an SEO Audit on your public web properties can surface misconfigured canonical URLs that sometimes trace back to DNS split-brain issues affecting how search engines crawl your site.
DNS Record Management Best Practices
Whether you're running traditional internal DNS or a modern cloud-native solution, these record management practices will save you pain:
Use Infrastructure as Code
Manage DNS records in version-controlled code, not through GUIs. Tools like Terraform support multiple DNS providers:
resource "cloudflare_record" "internal_api" {
zone_id = var.zone_id
name = "api.internal"
value = "10.0.1.45"
type = "A"
ttl = 300
proxied = false
}
Set Appropriate TTLs
TTL (Time to Live) determines how long resolvers cache your records. Common mistakes:
- Too high: Changes take forever to propagate (painful during incidents)
- Too low: Excessive query load on your authoritative servers
For internal records that change occasionally: 300-900 seconds (5-15 minutes) is a reasonable balance. For critical records you might need to change quickly: 60 seconds during planned changes, then increase after.
Document Your Zones
Maintain documentation of your internal DNS zones, what they're used for, and who owns them. DNS technical debt accumulates quickly — stale records pointing to decommissioned servers are a security risk as well as an operational headache.
Conclusion
Internal DNS is one of those foundational infrastructure components that deserves far more attention than it typically gets. Whether you're running a traditional on-premises setup, a multi-cloud environment, or a fully Zero Trust architecture, getting your internal DNS right is critical to reliability, security, and operational sanity.
The key takeaways: understand the difference between authoritative and recursive DNS, plan explicitly for split-horizon scenarios, build observability in from the start, and treat DNS configuration as code rather than a manual process.
If you want to audit your public-facing DNS health, verify SSL configurations, or check how your web properties look from the outside, OpDeck offers a suite of tools that make it easy — from DNS lookups and SSL certificate checks to full SEO audits and security scanning. Start with a quick check on your public infrastructure and you might be surprised what you find.
Try these tools
Website Performance
Analyze your website's performance, accessibility, and SEO with Google PageSpeed
Runtime Error Inspector
Detect JavaScript errors, failed requests, and console issues without opening DevTools
Cloudflare Detection
Check if a website is using Cloudflare and its configuration
Vulnerability Scanner
Scan WordPress and Magento sites for known vulnerabilities and security misconfigurations