AdguardTeam / AdguardTeam/AdGuardHome

Don't forward queries that can't be answered by public DNS servers

Open
#1,705 14 comments 16 reactions 0 assignees View on GitHub
feature request help wanted P3: Medium
Dominant language
TypeScript
Stars
36.9k
Forks
2.5k
PR merge metrics
No merged PRs in 30d

Description

(@ainar-g: updating the top post to summarize the discussion, define the UI, and add the special-use domains; original content is under the `` tag.)

Currently, AdGuard Home forwards all queries upstream, even ones that can't be answered by public DNS servers like PTR record lookup for private-use IP addresses or for domains like `localhost`, `home.arpa`, and `lan`, to name a few. This presents two issues, one is the added latency of receiving `NXDOMAIN` response for something public DNS can't answer and the other is leaking queries to a third-party service.

AdGuard Home shouldn't forward queries that can't be answered by upstream DNS servers by default unless there is a manual forward definition defined in Upstream DNS servers section.

Proposed changes:

* UI:
* Add a new section to the *Settings → DNS settings* page (probably right before the *Access settings* section) with the following checkboxes:

* Enabled (to enable or disable this feature entirely);
* Block Special-Use Domain Names (like `*.example` etc.);
* Block Undelegated Domain Names (like `modem`, `local`, etc.);
* Block Unqualified Domain Names (domains that consist of only the top-level domain).

* Internals:

* See the original post content for great tips on implementation.
* The unqualified and special-use checks are relatively easy to implement without the need for `urlfilter`-like rules. The undelegated domains check might require them.
* The special-use check must work in accordance with [RFC 6761](https://datatracker.ietf.org/doc/html/rfc6761).

* Configuration file:

* The new object is added to object `dns`:

```yaml
block_special:
enabled: true
special_use: true
undelegated: true
unqualified: true
```

(These are the default values.)

* * *

Original post content

### Problem Description

At the moment AGH forwards all queries upstream, even ones that can't be answered by public DNS servers like PTR record lookup for private IP addresses or for domains like `localhost`, `home.arpa`, `lan` to name a few.

This presents two issues, one is the added latency of receiving NXDOMAIN response for something public DNS can't answer and the other is leaking queries to a 3rd party service.

### Proposed Solution

Adguard shouldn't forward queries that can't be answered by upstream DNS servers by default unless there is a manual forward definition defined in Upstream DNS servers section.

I am not sure what is the best method of implementation for this, so I will just point out some implementation examples from other projects.

dnscrypt-proxy comes with following optioned enabled by default.
```toml
## Immediately respond to A and AAAA queries for host names without a domain name
block_unqualified = true

## Immediately respond to queries for local zones instead of leaking them to
## upstream resolvers (always causing errors or timeouts).
block_undelegated = true
```
Source: https://github.com/DNSCrypt/dnscrypt-proxy/blob/master/dnscrypt-proxy/example-dnscrypt-proxy.toml

For blocking unqualified domains, this seems to be the plugin that handles it - https://github.com/DNSCrypt/dnscrypt-proxy/blob/master/dnscrypt-proxy/plugin_block_unqualified.go

And the plugin for undelegated domains and PTR records - https://github.com/DNSCrypt/dnscrypt-proxy/blob/master/dnscrypt-proxy/plugin_block_undelegated.go

Some of those PTR records are from https://www.iana.org/assignments/locally-served-dns-zones/locally-served-dns-zones.xhtml

DNSMasq has the following option.
```
-f, --filterwin2k
Later versions of windows make periodic DNS requests which don't get sensible answers from the public DNS and can cause problems by triggering dial-on-demand links. This flag turns on an option to filter such requests. The requests blocked are for records of types SOA and SRV, and type ANY where the requested name has underscores, to catch LDAP requests.
```
Openwrt uses the above option along with filtering private IP address in the dnsmasq that they ship - https://github.com/openwrt/luci/blob/aac1a8d512643e3864843d2c2b3c6ee7f7f2a3d2/modules/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js#L212-L219

### Alternatives Considered
Write rules to block queries that can't be answered upstream with exceptions for internal domains & PTR for internal IP range which are forwarded to router's DNS server.

### Additional Information

While undelegated domains & PTR records can be handled by creating rules to block requests with some exceptions to ones you use, it would be good have this feature built into AGH and enabled by default so it benefits all users not just the ones who can write their own rules.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.