DNSSEC and source port randomization are your primary defenses against DNS cache poisoning, a nasty attack where attackers inject fake DNS records into a resolver’s cache, redirecting users to malicious sites.

Let’s see this in action. Imagine a DNS query for www.example.com that’s ripe for poisoning.

The Attack Scenario:

An attacker wants to redirect users querying for www.example.com to their own IP address, say 192.0.2.1. They’ll forge DNS responses that claim www.example.com resolves to 192.0.2.1.

Without Defenses:

A naive DNS resolver, upon receiving a forged response that looks legitimate (correct query ID, correct domain), might happily accept it and cache the fake record. The next user asking for www.example.com gets the poisoned record.

Introducing DNSSEC:

DNSSEC (Domain Name System Security Extensions) adds cryptographic signatures to DNS records. When a DNSSEC-aware resolver receives a response, it can verify the signature using public keys published by the authoritative DNS server.

  • Query: dig www.example.com @8.8.8.8
  • Response (if poisoned and DNSSEC is ignored):
    ;; ANSWER SECTION:
    www.example.com.        300     IN      A       192.0.2.1
    
  • Response (with DNSSEC validation):
    ;; ANSWER SECTION:
    www.example.com.        300     IN      A       93.184.216.34
    ;; AUTHORITY SECTION:
    example.com.            86400   IN      DNSKEY  257 3 8 AwEA... (public key)
    example.com.            86400   IN      RRSIG   DNSKEY 8 2 86400 ... (signature for DNSKEY)
    example.com.            86400   IN      DS      ... (delegation signer)
    example.com.            300     IN      RRSIG   A 8 2 300 ... (signature for A record)
    

If the attacker tries to inject a fake record for www.example.com pointing to 192.0.2.1, the DNSSEC validation process will fail because the forged response won’t have a valid signature from the legitimate example.com zone. The resolver will reject the poisoned response.

Introducing Source Port Randomization:

Even with DNSSEC, a fast attacker might try to win a race against the legitimate DNS server. They send their forged response before the real one arrives. Source port randomization makes this much harder.

Traditionally, DNS resolvers often used predictable source ports for their outgoing queries (e.g., always port 5353, or a small, sequential range). Attackers could guess this port and flood the target resolver with forged responses, hoping one would match the query ID and land in the correct UDP socket.

Source port randomization means the resolver uses a wide, unpredictable range of UDP source ports for its outgoing queries. Instead of guessing one or a few ports, an attacker would have to guess from thousands of possibilities (e.g., ports 1024-65535).

  • Configuring BIND (a common DNS server) for DNSSEC validation and source port randomization:

    In named.conf or a related options file:

    options {
        // ... other options
        dnssec-validation auto; // Enables DNSSEC validation
        // For source port randomization, modern BIND versions do this by default.
        // If you need to explicitly configure it (less common now):
        // listen-on-v6 { any; }; // Ensure IPv6 is enabled if needed for randomization
        // query-source address * port *; // This is often the default behavior for port randomization
        // ...
    };
    

    Why it works:

    1. DNSSEC: Ensures integrity. The cryptographic signatures prove that the DNS record originated from the legitimate authority and hasn’t been tampered with. If the signature doesn’t match the public key, the record is discarded.
    2. Source Port Randomization: Ensures authenticity. By making the source port unpredictable, it becomes exponentially harder for an attacker to guess the correct UDP destination port on the resolver to send their forged response to, especially in a race condition. The resolver only accepts responses on the port it actually used for the query.
  • Checking DNSSEC Validation:

    You can test if your resolver is correctly validating DNSSEC by querying a domain that is known to have DNSSEC records. For example, dig sigfail.verteiltesysteme.net @<your_resolver_ip>. A validating resolver should return SERVFAIL. Conversely, dig sigok.verteiltesysteme.net @<your_resolver_ip> should return the correct record.

  • Checking Source Port Randomization:

    This is harder to "check" directly with a single command as it’s about the absence of predictability. However, you can infer it if your DNS server is reasonably modern and configured with dnssec-validation auto. Running a packet capture (tcpdump -n -i eth0 udp port 53) while your resolver makes queries and observing the source ports used for outgoing UDP queries will show a wide, seemingly random distribution.

The combination of DNSSEC and source port randomization is a powerful defense. DNSSEC validates the content of the response, while source port randomization makes it difficult for attackers to even deliver a forged response to the right place at the right time.

After implementing these, the next common issue you might encounter is dealing with DNS resolution failures due to misconfigured DNSSEC delegation or zone signing issues on authoritative servers.

Want structured learning?

Take the full Dns course →