DNS Response Policy Zone (RPZ), also known as DNS Firewall, is a powerful mechanism for intercepting and rewriting DNS queries based on policy rules. Originally introduced in BIND 9.8, RPZ has become a standard feature across major DNS server implementations. It allows organizations to block malicious domains, enforce content filtering, redirect internal traffic, and implement threat intelligence feeds — all at the DNS layer.

In this guide, we compare three leading open-source DNS servers with robust RPZ support: BIND 9, PowerDNS, and Knot DNS. Whether you’re building a DNS firewall for your enterprise or deploying threat blocking for your home network, you’ll find the right RPZ solution here.

For related reading, see our DNS traffic analysis guide and DNS TTL optimization guide.

What Is DNS RPZ?

DNS RPZ (Response Policy Zone) works by intercepting DNS queries and applying policy rules before returning a response. When a query matches an entry in an RPZ zone, the DNS server can:

  • NXDOMAIN — Return “non-existent domain” to block the query entirely
  • NODATA — Return a valid response with no records (empty answer)
  • CNAME — Redirect the query to a different domain (sinkhole or warning page)
  • DROP — Silently drop the query (client times out)

This makes RPZ ideal for:

  • Blocking malware command-and-control (C2) domains
  • Preventing access to phishing sites
  • Enforcing corporate acceptable-use policies
  • Redirecting internal services to local IPs
  • Implementing threat intelligence feeds

BIND 9 RPZ

BIND 9 is the reference implementation of DNS RPZ, defined by the original RPZ specification. It provides the most mature and feature-complete RPZ implementation.

BIND RPZ Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// named.conf
options {
    response-policy {
        zone "rpz-block";
        zone "rpz-redirect";
    };
    // Optional: set policy action defaults
    response-policy-log yes;
    response-policy-minimum-ttl 300;
};

zone "rpz-block" {
    type master;
    file "/etc/bind/rpz-block.zone";
    allow-transfer { none; };
};

zone "rpz-redirect" {
    type master;
    file "/etc/bind/rpz-redirect.zone";
};

RPZ Zone File Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
; /etc/bind/rpz-block.zone
$TTL 1h
@ SOA localhost. root.localhost. 1 1h 15m 1w 1h
  NS localhost.

; Block malware domains (NXDOMAIN)
malware.example.com CNAME .
*.malware-domain.net CNAME .
evil.example.org CNAME rpz-drop.

; Redirect to sinkhole
ad-tracker.com CNAME rpz-passthru.
tracking.example.com CNAME sinkhole.internal.

BIND RPZ Docker Compose

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
version: "3.8"
services:
  bind9:
    image: ubuntu/bind9:latest
    container_name: bind9-rpz
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "953:953/tcp"
    volumes:
      - ./named.conf:/etc/bind/named.conf:ro
      - ./rpz-block.zone:/etc/bind/rpz-block.zone:ro
      - ./rpz-redirect.zone:/etc/bind/rpz-redirect.zone:ro
      - bind-data:/var/cache/bind
    environment:
      - BIND9_USER=root
    restart: unless-stopped

volumes:
  bind-data:

PowerDNS RPZ

PowerDNS Authoritative Server supports RPZ through its recursor (PowerDNS Recursor). The RPZ implementation in PowerDNS is highly configurable and integrates seamlessly with Lua scripting for advanced policy logic.

PowerDNS Recursor RPZ Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
-- /etc/powerdns/recursor.lua
-- Load RPZ zones
rpzFile("/etc/powerdns/rpz-block.zone")
rpzFile("/etc/powerdns/rpz-custom.zone")

-- Custom RPZ action with logging
function policyEventFilter(event)
    if event.qtype == pdns.A then
        if event.policyType == pdns.policytype.RPZ then
            pdnslog("RPZ blocked: " .. event.qname:toString())
        end
    end
    return true
end

PowerDNS RPZ Zone File

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
; /etc/powerdns/rpz-block.zone
$TTL 300
@ SOA localhost. root.localhost. 1 1h 15m 1w 1h
  NS localhost.

; Block phishing sites
phish-login.example CNAME .
*.fake-bank.com CNAME .
credential-stealer.net CNAME .

; Redirect ad domains to sinkhole
*.ads.example.com CNAME sinkhole.local.

PowerDNS RPZ Docker Compose

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
version: "3.8"
services:
  pdns-recursor:
    image: powerdns/pdns-recursor-49:latest
    container_name: pdns-rpz
    ports:
      - "53:53/tcp"
      - "53:53/udp"
    volumes:
      - ./recursor.conf:/etc/powerdns/recursor.conf:ro
      - ./recursor.lua:/etc/powerdns/recursor.lua:ro
      - ./rpz-block.zone:/etc/powerdns/rpz-block.zone:ro
    restart: unless-stopped

  pdns-authoritative:
    image: powerdns/pdns-auth-49:latest
    container_name: pdns-auth
    ports:
      - "5300:53/tcp"
      - "5300:53/udp"
    environment:
      - PDNS_gmysql_host=pdns-db
      - PDNS_gmysql_user=pdns
      - PDNS_gmysql_password=secret
    depends_on:
      - pdns-db
    restart: unless-stopped

  pdns-db:
    image: mariadb:10.11
    environment:
      - MYSQL_ROOT_PASSWORD=secret
      - MYSQL_DATABASE=pdns
      - MYSQL_USER=pdns
      - MYSQL_PASSWORD=secret
    volumes:
      - pdns-db-data:/var/lib/mysql
    restart: unless-stopped

volumes:
  pdns-db-data:

Knot DNS RPZ

Knot DNS (developed by CZ.NIC) supports RPZ in its resolver component (kresd). Knot’s RPZ implementation is designed for high-performance environments and integrates with its modular resolver architecture.

Knot Resolver RPZ Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
-- /etc/knot-resolver/kresd.conf
-- Enable RPZ module
module.load('policy')

-- Load RPZ zone from file
policy.add(policy.rpz(policy.DENY, '/etc/knot-resolver/rpz-block.zone'))

-- Load RPZ from remote zone (auto-updated)
policy.add(policy.rpz(policy.PASS, 'https://example.com/rpz-feed.zone'))

-- Custom policy rules
policy.add(policy.suffix(policy.DENY, {todname('malware.example.com.')}))
policy.add(policy.suffix(policy.PASS, {todname('*.ads.internal.')}))

Knot RPZ Zone File

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
; /etc/knot-resolver/rpz-block.zone
$TTL 1h
@ SOA localhost. root.localhost. 1 1h 15m 1w 1h
  NS localhost.

; Block cryptojacking domains
coinhive.com CNAME .
*.cryptomining-pool.net CNAME .

; Block telemetry
telemetry.vendor.com CNAME .
*.analytics.tracker.io CNAME .

Knot Resolver Docker Compose

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
version: "3.8"
services:
  knot-resolver:
    image: cznic/knot-resolver:latest
    container_name: knot-rpz
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8053:8053/tcp"
    volumes:
      - ./kresd.conf:/etc/knot-resolver/kresd.conf:ro
      - ./rpz-block.zone:/etc/knot-resolver/rpz-block.zone:ro
      - ./trust-anchors:/etc/knot-resolver/trust-anchors
      - knot-cache:/var/cache/knot-resolver
    restart: unless-stopped

volumes:
  knot-cache:

RPZ Feature Comparison

FeatureBIND 9PowerDNS RecursorKnot Resolver
RPZ ActionsNXDOMAIN, NODATA, CNAME, DROP, PASSTHRUNXDOMAIN, NODATA, CNAME, DROPDENY, PASS, DROP
Multiple RPZ ZonesYesYesYes
Zone Transfer (AXFR/IXFR)YesYesVia HTTP/zone download
Policy PriorityConfigurable orderConfigurable orderRule priority
Lua ScriptingNoYes (full Lua)Yes (Lua-based)
LoggingQuery loggingpdnslog()Module logging
PerformanceGoodExcellentExcellent
RPZ Feed IntegrationManual/file-basedLua scriptingHTTP URL support
DNSSEC ValidationYesYesYes
Docker SupportOfficial imagesOfficial imagesOfficial images

Choosing the Right RPZ Solution

Choose BIND 9 RPZ when:

  • You need the reference implementation with maximum compatibility
  • You’re already running BIND as your authoritative or recursive resolver
  • You require the full set of RPZ actions including PASSTHRU and DROP
  • You want zone transfer (AXFR/IXFR) support for RPZ zone distribution

Choose PowerDNS Recursor when:

  • You need Lua scripting for advanced policy logic
  • You want the highest query throughput for large-scale deployments
  • You need integration with external threat intelligence APIs
  • You’re already using PowerDNS for authoritative DNS

Choose Knot Resolver when:

  • You need high performance with minimal resource usage
  • You want HTTP-based RPZ feed integration
  • You prefer a modular, Lua-driven resolver architecture
  • You need DNSSEC validation built into the RPZ pipeline

Why Self-Host DNS RPZ?

Running your own DNS RPZ infrastructure gives you complete control over what domains are blocked, redirected, or allowed within your network. Unlike commercial DNS firewalls, self-hosted RPZ solutions are free, transparent, and fully customizable.

Data sovereignty: All DNS query logs and policy rules stay within your infrastructure. No third-party vendor sees your browsing patterns or policy decisions. This is critical for organizations handling sensitive data or operating under strict compliance requirements.

Cost savings: Commercial DNS firewall services charge per-user or per-query. With self-hosted RPZ, your only costs are the server hardware and bandwidth. For organizations with hundreds or thousands of users, this translates to significant savings.

Threat intelligence integration: Self-hosted RPZ lets you integrate multiple threat intelligence feeds — from open-source blocklists like Spamhaus and SURBL to commercial feeds — and apply them with custom priority rules. You control what gets blocked and when.

Custom policy rules: Unlike commercial DNS filtering services that offer fixed category-based blocking, RPZ lets you write precise rules for individual domains, wildcard patterns, and even IP-based redirections. You can redirect blocked domains to internal warning pages or sinkhole servers for forensic analysis.

For related reading, see our DNS reconnaissance guide and DNS anycast guide.

FAQ

What is DNS RPZ and how does it work?

DNS Response Policy Zone (RPZ) is a DNS server feature that intercepts queries and applies policy rules before returning responses. When a queried domain matches an entry in an RPZ zone file, the server can block it (NXDOMAIN), redirect it (CNAME), or drop it silently. It works at the DNS layer, making it transparent to applications.

Which DNS servers support RPZ?

BIND 9 (the reference implementation), PowerDNS Recursor, and Knot Resolver all support RPZ. BIND offers the most complete feature set with all five RPZ action types. PowerDNS adds Lua scripting for advanced logic. Knot Resolver provides HTTP-based feed integration and modular policy rules.

Can I use RPZ to block ads and trackers?

Yes. RPZ is commonly used to block advertising and tracking domains by redirecting them to a sinkhole (0.0.0.0) or returning NXDOMAIN. You can load RPZ zone files from open-source blocklists like StevenBlack’s hosts file, Spamhaus, or custom-curated lists.

How do I update RPZ zones automatically?

BIND supports AXFR/IXFR zone transfers from master RPZ servers. PowerDNS can use Lua scripts to fetch and parse remote feeds. Knot Resolver supports loading RPZ zones directly from HTTP URLs, enabling automatic updates from threat intelligence feeds.

Does RPZ work with DNSSEC?

Yes. All three DNS servers validate DNSSEC signatures before applying RPZ rules. If a domain’s DNSSEC validation fails, the RPZ policy can be configured to either block the response or pass it through based on your security requirements.

Can RPZ block encrypted DNS (DoH/DoT)?

RPZ works at the DNS resolution layer. If clients use DNS-over-HTTPS (DoH) or DNS-over-TLS (DoT) to external resolvers (like Google or Cloudflare), RPZ on your local DNS server won’t see those queries. To enforce RPZ policies, you need to block outbound DoH/DoT traffic or redirect clients to your local resolver.