Skip to content

dns/bind: add Response Policy Zone (RPZ) support#5399

Open
mbedworth wants to merge 1 commit intoopnsense:masterfrom
mbedworth:bind-rpz-support
Open

dns/bind: add Response Policy Zone (RPZ) support#5399
mbedworth wants to merge 1 commit intoopnsense:masterfrom
mbedworth:bind-rpz-support

Conversation

@mbedworth
Copy link
Copy Markdown
Contributor

@mbedworth mbedworth commented Apr 13, 2026

Important notices

Before you submit a pull request, we ask you kindly to acknowledge the following:

If AI was used, please disclose:

  • Model used: Claude Sonnet (Anthropic)
  • Extent of AI involvement: AI assisted with code generation and structure; all logic reviewed and tested manually on live OPNsense.

Describe the problem

The BIND plugin already supports DNSBL-based response-policy zones, but there is no way to configure a standalone RPZ (e.g. a local blocklist maintained by an external update script) without manually editing named.conf. Because named.conf is regenerated by the configd template engine on every service restart and OS update, manual edits do not survive.

The response-policy directive must appear inside the options {} block, which means it cannot be injected via a top-level include file from named.conf.d/.


Describe the proposed solution

Adds a native RPZ settings tab to the BIND GUI (between DNSBL and ACLs) and wires it through the standard OPNsense MVC/API stack:

File Role
models/OPNsense/Bind/Rpz.xml Model — mounted at //OPNsense/bind/rpz
models/OPNsense/Bind/Rpz.php BaseModel subclass
Api/RpzController.php REST controller (/api/bind/rpz/get, /api/bind/rpz/set)
forms/rpz.xml GUI form
GeneralController.php Exposes rpzForm to the view
general.volt RPZ tab + JS wiring
named.conf (template) Emits response-policy inside options {} and zone declaration

Configuration fields

  • Enabled — on/off toggle
  • Zone name — zone name; zone file expected at /usr/local/etc/namedb/primary/<zone>.db
  • Policy — override policy: nxdomain | nodata | passthru | drop | tcp-only (optional; omit to use zone's own CNAME records)
  • Break DNSSEC — allow RPZ rewrites over DNSSEC-signed responses

Coexistence with DNSBL

When both DNSBL and RPZ are enabled, two separate response-policy statements are emitted — one for DNSBL zones and one for the RPZ zone. BIND supports multiple response-policy statements.

Testing

Tested on OPNsense 25.1 with BIND 9.20:

  • Enabled RPZ with rpz.local zone and Hagezi Light blocklist (137,674 entries)
  • named-checkconf passes cleanly
  • Blocked domains return NXDOMAIN with rpz.local in the authority section
  • Normal resolution is unaffected
  • Configuration survives service restart and configctl bind restart
  • DNSBL continues to function when both features are enabled simultaneously

Related issue

N/A

Adds native RPZ configuration to the os-bind plugin with a dedicated
settings tab in the GUI.

The DNSBL feature already uses response-policy inside options{}, but
there is no way to configure a standalone RPZ (e.g. a local blocklist
fed by an external updater) without manually editing named.conf, which
is overwritten on every service restart.

New files:
- Rpz.xml / Rpz.php: model mounted at //OPNsense/bind/rpz
- RpzController.php: REST API via ApiMutableModelControllerBase
  (GET /api/bind/rpz/get, POST /api/bind/rpz/set)
- forms/rpz.xml: GUI form definition

Modified files:
- GeneralController.php: expose rpzForm to the view
- general.volt: add RPZ tab between DNSBL and ACLs; wire up
  mapDataToFormUI and saveAct_rpz click handler
- named.conf template: emit response-policy inside options{} and
  the zone declaration when RPZ is enabled and a zone name is set

Configuration fields:
- enabled: on/off toggle
- zone: zone name (file resolved to /usr/local/etc/namedb/primary/<zone>.db)
- policy: nxdomain | nodata | passthru | drop | tcp-only (optional override)
- break_dnssec: allow RPZ rewrites over DNSSEC-signed responses

Tested on OPNsense 25.1 with BIND 9.20 and Hagezi Light blocklist
(137,674 entries). NXDOMAIN confirmed for blocked domains; normal
resolution unaffected.
@AdSchellevis
Copy link
Copy Markdown
Member

@mbedworth can you please use our PR template?

@mbedworth
Copy link
Copy Markdown
Contributor Author

The PR description has been updated to use the standard template (checkboxes, "Describe the problem" / "Describe the proposed solution" sections). Let me know if anything else needs adjusting before review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants