Stop Sending Users Across the Globe: Building GeoDNS with PowerDNS

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

Why Static DNS Is Killing Your Performance

Static DNS is a silent performance killer. I’ve spent years auditing global stacks where a user in Singapore gets routed to a New York server simply because it’s the only IP configured. This adds roughly 250ms of unnecessary latency to every single request. In a world where 40% of users abandon a site that takes more than three seconds to load, those milliseconds are expensive.

Commercial giants like AWS Route53 or Cloudflare Load Balancing solve this, but they come with recurring monthly bills and vendor lock-in. If you want total control without the “cloud tax,” PowerDNS is the answer. I have deployed this exact setup in production environments handling millions of queries. It works. This guide shows you how to return different IP addresses based on where the query originates.

Quick Start: Up and Running in 5 Minutes

You don’t need a massive cluster for this. A lightweight VPS with 1GB of RAM and Ubuntu 22.04 or 24.04 is more than enough to handle thousands of requests per second. We will focus on the PowerDNS Authoritative Server and its GeoIP backend.

1. Install PowerDNS and the GeoIP Backend

First, grab the core server and the specific backend module. These are available in the standard Ubuntu repositories.

sudo apt update
sudo apt install pdns-server pdns-backend-geoip -y

2. Get the GeoIP Database

PowerDNS needs a map to link IPs to physical locations. MaxMind offers a free version called GeoLite2. Sign up for a free account on their site, get a license key, and download the City and Country .mmdb files. Place them in a dedicated directory.

# Your directory should look like this:
ls /var/lib/GeoIP/
# GeoLite2-City.mmdb  GeoLite2-Country.mmdb

3. Basic Configuration

Open /etc/powerdns/pdns.conf. We need to disable the default bind backend and enable GeoIP. This tells PowerDNS exactly where to look for your location data and your custom routing rules.

launch=geoip
geoip-database-files=/var/lib/GeoIP/GeoLite2-City.mmdb /var/lib/GeoIP/GeoLite2-Country.mmdb
geoip-zones-file=/etc/powerdns/geoip-zones.yaml

The Deep Dive: How PowerDNS Maps IPs to Locations

The geoip-zones.yaml file is the brain of your operation. Unlike old-school Bind files that are rigid and messy, PowerDNS uses YAML for GeoIP. It’s clean, readable, and easy to version control.

When a query hits your server, PowerDNS checks the requester’s IP against the MaxMind database. It identifies the continent or country code and matches it against your YAML rules. If there is no match, it serves a default record. It’s simple logic for a complex problem.

Configuring the Zone File

Create /etc/powerdns/geoip-zones.yaml. Here is a battle-tested structure for a global service with nodes in Asia, Europe, and North America:

domains:
  - domain: example.com
    ttl: 300
    records:
      example.com:
        - a: 1.2.3.4 # Default fallback IP
      
      app.example.com:
        - a: 1.2.3.4 
    
    services:
      app.example.com:
        # Singapore Node for Asia
        as.continent.geo.example.com: ["103.1.2.3"]
        # Frankfurt Node for Europe
        eu.continent.geo.example.com: ["185.1.2.3"]
        # New York Node for North America
        na.continent.geo.example.com: ["192.1.2.3"]

Keep in mind that DNS queries often come from ISP resolvers rather than the user directly. However, PowerDNS supports EDNS Client Subnet (ECS). This allows the resolver to pass along the user’s actual subnet, making your geographic steering incredibly precise.

Advanced Usage: Granular Control and Failover

Continent-level routing is a great start, but you can go deeper. For instance, you might want users in Vietnam to hit a local Ho Chi Minh City node while the rest of Asia continues to use Singapore.

Country-Specific Routing

Use ISO 3166-1 alpha-2 country codes for surgical precision. This is perfect for complying with local data laws or optimizing for specific markets.

services:
  app.example.com:
    vn.country.geo.example.com: ["45.1.2.3"] # Vietnam Node
    as.continent.geo.example.com: ["103.1.2.3"] # Rest of Asia

Weighted Routing and Redundancy

If you have two servers in the same region, list them both. PowerDNS will return both IPs, allowing the client to choose. It’s a basic but effective way to distribute load across multiple servers in a single data center.

services:
  app.example.com:
    eu.continent.geo.example.com: ["185.1.2.3", "185.1.2.4"]

Practical Tips from the Field

Running your own DNS infrastructure is a serious commitment. I’ve learned a few hard lessons managing these setups in high-traffic environments.

1. Automate Database Updates

MaxMind updates their GeoLite2 data twice a week. Outdated databases lead to wrong routing—like sending a London user to a Tokyo server. Use the geoipupdate tool with a simple cron job to keep your files current without manual intervention.

2. Health Checks Are Mandatory

PowerDNS doesn’t natively check if your application servers are alive. If your Frankfurt node goes down, PowerDNS will keep sending European users to a dead IP. I recommend a simple Python or Go script that monitors your nodes and updates the YAML file (followed by a pdns_control reload) if a failure occurs.

3. Harden Your DNS Against Attacks

Open DNS servers are magnets for DDoS amplification attacks. Tighten your security. Use a firewall to limit query rates and ensure you only allow traffic on UDP/53 and TCP/53. Monitoring spikes in query volume can save your server from being used as a weapon.

4. Keep Your TTL Low

For GeoDNS, use a TTL between 60 and 300 seconds. If a regional node fails and you need to shift traffic, a high TTL (like 86400 seconds) will keep users stuck on the broken IP for an entire day. Low TTLs ensure your changes propagate quickly across the internet.

Building your own GeoDNS with PowerDNS offers total control over your traffic flow. It is a cost-effective, high-performance strategy that ensures your users get the fastest experience possible, no matter where they are on the map.

Share: