Skip to content

Add support for blocked replies with NOERROR code and empty answer - #8245

Open
agross wants to merge 1 commit into
AdguardTeam:masterfrom
agross:fix-8024
Open

Add support for blocked replies with NOERROR code and empty answer#8245
agross wants to merge 1 commit into
AdguardTeam:masterfrom
agross:fix-8024

Conversation

@agross

@agross agross commented Feb 11, 2026

Copy link
Copy Markdown

Hello,

I'm not a Go developer by trade and not a DNS expert; please be gentle.

I found #8024 is affecting me.

The default behavior of returning the null address makes localhost reachable under blocked names. This causes errors and unwanted behavior, like being able to ping blocked hosts (by talking to localhost).

Returning NXDOMAIN or REFUSED, on the other hand, will cause extra DNS queries with the search domain appended, i.e., blocked.example.com becomes blocked.example.com.local.domain.com.

By returning NOERROR without an answer section, these problems go away.

With this patch, AdGuard will return a response similar to resolving a non-existing name, i.e., asking a question but not getting an answer:

$ dig doesntexist.example.com # not blocked
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52361
...
;; QUESTION SECTION:
;doesntexist.example.com.       IN      A

;; AUTHORITY SECTION:
example.com.            1708    IN      SOA     elliott.ns.cloudflare.com. dns.cloudflare.com. 2395194487 10000 2400 604800 1800

If NOERROR is selected and a blocked name is requested, it looks like this:

$ dig ogads-pa.clients6.google.com # blocked by AdGuard DNS filter
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8474
...
;; QUESTION SECTION:
;ogads-pa.clients6.google.com.  IN      A

;; AUTHORITY SECTION:
ogads-pa.clients6.google.com. 10 IN     SOA     fake-for-negative-caching.adguard.com. hostmaster.ogads-pa.clients6.google.com. 100500 1800 900 604800 86400

Closes #8024

@windsurf-bot windsurf-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 To request another review, post a new comment with "/windsurf-review".

filtering.BlockingModeDefault,
filtering.BlockingModeNXDOMAIN,
filtering.BlockingModeREFUSED,
filtering.BlockingModeNOERROR,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR adds filtering.BlockingModeNOERROR to the list of valid blocking modes, but I don't see a corresponding implementation in the filtering package. Make sure this mode is properly implemented in the filtering package to handle blocked domains with NOERROR responses without answer sections.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new approach to responding to filtered queries, not a new method for filtering.

@agross
agross force-pushed the fix-8024 branch 2 times, most recently from 4deb43d to f53fdba Compare March 5, 2026 00:37
@github-actions
github-actions Bot force-pushed the fix-8024 branch 3 times, most recently from 8793a81 to 524f303 Compare March 12, 2026 04:57
@github-actions
github-actions Bot force-pushed the fix-8024 branch 3 times, most recently from 3d04800 to 2576ed7 Compare March 21, 2026 04:47
@github-actions
github-actions Bot force-pushed the fix-8024 branch 5 times, most recently from 63d944c to 3c7d59d Compare April 2, 2026 05:14
@github-actions
github-actions Bot force-pushed the fix-8024 branch 6 times, most recently from 791c59e to d303033 Compare April 11, 2026 05:04
@github-actions
github-actions Bot force-pushed the fix-8024 branch 4 times, most recently from a6a6155 to d1cec80 Compare April 18, 2026 05:17
@github-actions
github-actions Bot force-pushed the fix-8024 branch 3 times, most recently from de66c70 to 7098c29 Compare April 25, 2026 05:22
@agross
agross force-pushed the fix-8024 branch 2 times, most recently from a03dc9d to e584b53 Compare July 11, 2026 09:02
@agross

agross commented Jul 11, 2026

Copy link
Copy Markdown
Author

5 months later, and not a single reply from the team. Is this of no interest, @KirillCAdGuard, @kpokas-adguard, @AleksandrKalininAdGuard?

@agross

agross commented Jul 17, 2026

Copy link
Copy Markdown
Author

@github-actions
github-actions Bot force-pushed the fix-8024 branch 5 times, most recently from 1afb685 to b372707 Compare July 28, 2026 06:05
@github-actions
github-actions Bot force-pushed the fix-8024 branch 3 times, most recently from 4d25df9 to 3bf55c9 Compare August 1, 2026 06:11

@Sil3ntVip3r Sil3ntVip3r left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found one confirmed integration omission and one material regression gap on current head 3bf55c966b07fc358e888bd33803be1dd59df903:

  • The runtime now accepts and returns blocking_mode: "noerror", but the blocking-mode enums in openapi/openapi.yaml and openapi/next.yaml still omit it. Consequently, schema-generated clients cannot represent the new value, and client_v2's generated type, constants, summary, and options do not expose it. Please update the API schemas/documentation and the generated/current-UI integration along with the legacy UI.
  • No backend test on this head exercises the new mode through configuration or DNS response construction. The smallest regression coverage would round-trip noerror through the DNS config set/get path, then assert that blocked A, AAAA, and HTTPS queries return RcodeSuccess, an empty Answer section, and exactly the expected SOA in Authority (including the configured blocked-response TTL).

I do not see a demonstrated DNS response bug in the current implementation; this is an API/UI integration defect plus unprotected externally visible behavior.

@agross

agross commented Aug 3, 2026

Copy link
Copy Markdown
Author

@Sil3ntVip3r Thanks for your review and token spend.

@Sil3ntVip3r Sil3ntVip3r left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I re-reviewed exact head
656965535fc2bb249052de4e59d47ada7f9579af. The functional concerns from my
previous review are resolved: both OpenAPI schemas and UIs expose noerror, the
configuration test round-trips it, and backend regressions cover blocked A,
AAAA, and HTTPS responses with NOERROR, an empty Answer section, one SOA,
and the configured TTL.

One small documentation update remains before this public behavior is ready:

  • CHANGELOG.md does not mention the new user-facing blocking mode under
    Unreleased. client_v2/AGENTS.md requires the root changelog to be updated
    for user-facing changes.
  • openapi/CHANGELOG.md does not record that DNSConfig.blocking_mode now
    accepts "noerror".
  • AGHTechDoc.md still lists only the old blocking-mode values in both request
    examples and the mode description.

The smallest fix is an Added entry referencing #8024, one v0.107.79 API
changelog bullet, and noerror plus its empty-answer behavior in the two
technical-document examples/description. Please run make md-lint and
make txt-lint after those edits; no additional production test is needed for
this documentation-only change.

Independent validation on this clean exact head:

PASS: focused NOERROR/configuration backend tests under -race
PASS: go test -race -count=1 ./internal/dnsforward
PASS: make go-check
PASS: focused current-UI helper test, ESLint, and TypeScript typecheck
PASS: full current-UI suite (59 files / 620 tests)
PASS: fresh API generation matched the committed blocking-mode type
PASS: git diff --check

Once the three documentation locations are updated, I expect this to be ready
for approval.

@Sil3ntVip3r

Copy link
Copy Markdown

I prepared the remaining documentation-only patch against exact head
656965535fc2bb249052de4e59d47ada7f9579af and verified it locally.

diff --git a/AGHTechDoc.md b/AGHTechDoc.md
--- a/AGHTechDoc.md
+++ b/AGHTechDoc.md
@@ -1077,7 +1077,7 @@ Response:
 
 		"protection_enabled": true | false,
 		"ratelimit": 1234,
-		"blocking_mode": "default" | "refused" | "nxdomain" | "null_ip" | "custom_ip",
+		"blocking_mode": "default" | "refused" | "nxdomain" | "null_ip" | "custom_ip" | "noerror",
 		"blocking_ipv4": "1.2.3.4",
@@ -1103,7 +1103,7 @@ Request:
 
 		"protection_enabled": true | false,
 		"ratelimit": 1234,
-		"blocking_mode": "default" | "refused" | "nxdomain" | "null_ip" | "custom_ip",
+		"blocking_mode": "default" | "refused" | "nxdomain" | "null_ip" | "custom_ip" | "noerror",
 		"blocking_ipv4": "1.2.3.4",
@@ -1124,6 +1124,7 @@ Response:
 * NXDOMAIN: Respond with NXDOMAIN code
 * Null IP: Respond with zero IP address (0.0.0.0 for A; :: for AAAA)
 * Custom IP: Respond with a manually set IP address
+* NOERROR: Respond with NOERROR code and an empty answer
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,6 +26,9 @@ NOTE: Add new changes BELOW THIS COMMENT.
 
 ### Added
 
+- The `NOERROR` blocking mode, which returns an empty answer for blocked
+  requests ([#8024]).
+
 - Bootstrap servers configuration now supports comments.
@@ -44,6 +47,7 @@ NOTE: Add new changes BELOW THIS COMMENT.
 
 - Blocked requests without an EDNS(0) OPT record ([#8183]).
 
+[#8024]: https://github.com/AdguardTeam/AdGuardHome/issues/8024
 [#8183]: https://github.com/AdguardTeam/AdGuardHome/issues/8183
diff --git a/openapi/CHANGELOG.md b/openapi/CHANGELOG.md
--- a/openapi/CHANGELOG.md
+++ b/openapi/CHANGELOG.md
@@ -4,6 +4,9 @@
 
 ## v0.107.79: API changes
 
+- The `blocking_mode` field in `DNSConfig` now accepts `noerror`, which
+  returns a successful response with an empty answer for blocked requests.
+
 - Field `bootstrap_dns` in `POST /control/dns_config` now accepts comments.  A comment must start with the `#` symbol.

Validation on that exact head:

PASS: git diff --check
PASS: make md-lint
PASS: make txt-lint

This is the complete remaining change from my review; no production-code or
additional test modification is needed.

@Sil3ntVip3r Sil3ntVip3r left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rechecked exact current head c2802a5a7acd281f6dbb047239d10d205d5e4888.

The implementation itself is in good shape: make go-check passed; the current dashboard check passed (lint, typecheck, 620 tests); legacy-dashboard lint, typecheck, and 35 tests passed; and make md-lint, make txt-lint, and git diff --check passed.

The rewritten head still omits the three documentation updates from my prior review/comment: its changed-file list does not include AGHTechDoc.md, CHANGELOG.md, or openapi/CHANGELOG.md; the technical-document examples still omit noerror; and neither changelog records the new public mode. The complete minimal patch is already posted above and still applies conceptually to this head.

That documentation-only update is the sole remaining blocker. Please apply it (or an equivalent update) and rerun the two documentation lints; no production-code or additional regression-test change is needed. I expect to approve once it lands.

@agross

agross commented Aug 6, 2026

Copy link
Copy Markdown
Author

@Sil3ntVip3r The remaining blocker is the AdGuard team's lack of interest.

@hzjzjsjsnzn

Copy link
Copy Markdown

你好

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add "Blank" block mode

4 participants