From 8cfcc10f7fd3cbcdcff68369c1ffd266830d518f Mon Sep 17 00:00:00 2001
From: Ainar Garipov <a.garipov@adguard.com>
Date: Thu, 24 Dec 2020 17:10:11 +0300
Subject: [PATCH] Pull request: Hosts-Blocklists: add dnsrewrite docs

Merge in DNS/adguard-home-wiki from 2102-dnsrewrite to master

Updates AdguardTeam/AdGuardHome#2102.

Squashed commit of the following:

commit dd8d38a0a274d50b4bb2ce2a642cfd8a1f6bcf7e
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Dec 24 13:14:24 2020 +0300

    all: fix typos, add versions

commit 3add81c650e27b5e19d10a5a4e4e1b0e0b64d670
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Dec 23 17:13:50 2020 +0300

    Hosts-Blocklists: fix ptr part

commit 4ff69767455900554bc053632595ad070c34eb23
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Dec 23 13:12:52 2020 +0300

    Hosts-Blocklists: add dnsrewrite docs
---
 Configuration.md    |   2 +-
 Getting-Started.md  |   2 +-
 Hosts-Blocklists.md | 118 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 120 insertions(+), 2 deletions(-)

diff --git a/Configuration.md b/Configuration.md
index 715b42a..1a3102f 100644
--- a/Configuration.md
+++ b/Configuration.md
@@ -173,7 +173,7 @@ Settings are stored in [YAML format](https://en.wikipedia.org/wiki/YAML), possib
   - **Protection settings**
     - `protection_enabled` — Whether any kind of filtering and protection should be done, when off it works as a plain dns forwarder.
     - `filtering_enabled` — Filtering of DNS requests based on filter lists.
-    - `blocking_mode` — Specifies how to block DNS requests. "nxdomain" (default): respond with NXDOMAIN status; "null_ip": respond with the unspecified IP address (0.0.0.0); or "custom_ip": reponsd with `blocking_ipv4` or `blocking_ipv6`.
+    - `blocking_mode` — Specifies how to block DNS requests. "nxdomain" (default): respond with NXDOMAIN status; "null_ip": respond with the unspecified IP address (0.0.0.0); or "custom_ip": respond with `blocking_ipv4` or `blocking_ipv6`.
     - `blocking_ipv4` - IP address to be returned for a blocked A request if `blocking_mode` is set to `custom_ip`
     - `blocking_ipv6` - IP address to be returned for a blocked AAAA request if `blocking_mode` is set to `custom_ip`
     - `blocked_response_ttl` — For how many seconds the clients should cache a filtered response. Low values are useful on LAN if you change filters very often, high values are useful to increase performance and save traffic.
diff --git a/Getting-Started.md b/Getting-Started.md
index 5b72d90..d631ff4 100644
--- a/Getting-Started.md
+++ b/Getting-Started.md
@@ -18,7 +18,7 @@ Download the archive with the binary file for your operating system from the [la
 We currently **officially** support the following operating systems:
 
 * Linux: [64-bit](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_amd64.tar.gz), [32-bit](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_386.tar.gz)
-* Linux ARM: [32-bit ARMv6](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_armv6.tar.gz) (recommended for Rapsberry Pi), [64-bit](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_arm64.tar.gz), [32-bit ARMv5](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_armv5.tar.gz), [32-bit ARMv7](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_armv7.tar.gz)
+* Linux ARM: [32-bit ARMv6](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_armv6.tar.gz) (recommended for Raspberry Pi), [64-bit](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_arm64.tar.gz), [32-bit ARMv5](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_armv5.tar.gz), [32-bit ARMv7](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_armv7.tar.gz)
 * Linux MIPS: [32-bit MIPS](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_mips_softfloat.tar.gz), [32-bit MIPSLE](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_mipsle_softfloat.tar.gz), [64-bit MIPS](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_mips64_softfloat.tar.gz), [64-bit MIPSLE](https://static.adguard.com/adguardhome/release/AdGuardHome_linux_mips64le_softfloat.tar.gz)
 * Windows: [64-bit](https://static.adguard.com/adguardhome/release/AdGuardHome_windows_amd64.zip), [32-bit](https://static.adguard.com/adguardhome/release/AdGuardHome_windows_386.zip)
 * MacOS: [64-bit](https://static.adguard.com/adguardhome/release/AdGuardHome_darwin_amd64.zip), [32-bit](https://static.adguard.com/adguardhome/release/AdGuardHome_darwin_386.zip)
diff --git a/Hosts-Blocklists.md b/Hosts-Blocklists.md
index 5a769de..f6c9900 100644
--- a/Hosts-Blocklists.md
+++ b/Hosts-Blocklists.md
@@ -8,6 +8,7 @@
     * [Rule modifiers](#modifiers)
         * [client](#client)
         * [dnstype](#dnstype)
+        * [dnsrewrite](#dnsrewrite)
         * [important](#important)
         * [badfilter](#badfilter)
         * [ctag](#ctag)
@@ -131,6 +132,8 @@ Client names usually contain spaces or other special characters, that's why you
 
 #### <a id="dnstype"></a> `dnstype`
 
+(Since **v0.105.0**.)
+
 The `$dnstype` modifier allows specifying DNS request type on which this rule
 will be triggered.
 
@@ -162,6 +165,121 @@ $dnstype=value2
 * `||example.org^$dnstype=~A|~CNAME` — Only allow `A` and `CNAME` DNS requests
   for `example.org`, block out the rest.
 
+#### <a id="dnsrewrite"></a> `dnsrewrite`
+
+(Since **v0.105.0**.)
+
+The `$dnsrewrite` response modifier allows replacing the content of the response
+to the DNS request for the matching hosts.
+
+The shorthand syntax is:
+
+```
+$dnsrewrite=1.2.3.4
+$dnsrewrite=abcd::1234
+$dnsrewrite=example.net
+$dnsrewrite=REFUSED
+```
+
+The keywords, like `REFUSED`, MUST be in all caps.
+
+The full syntax is of the form `RCODE;RRTYPE;VALUE`:
+
+```
+$dnsrewrite=NOERROR;A;1.2.3.4
+$dnsrewrite=NOERROR;AAAA;abcd::1234
+$dnsrewrite=NOERROR;CNAME;example.net
+$dnsrewrite=REFUSED;;
+```
+
+The `CNAME` one is special because _AdGuardHome_ will resolve the host and add
+its info to the response.  That is, if example.net has IP `1.2.3.4`, and the
+user has this in their filter rules:
+
+```
+||example.com^$dnsrewrite=example.net
+```
+
+Or:
+
+```
+||example.com^$dnsrewrite=NOERROR;CNAME;example.net
+```
+
+Then the response will be something like:
+
+```
+$ nslookup example.com my.adguard.local
+Server:		my.adguard.local
+Address:	127.0.0.1#53
+
+Non-authoritative answer:
+example.com	canonical name = example.net.
+Name:	example.net
+Address: 1.2.3.4
+```
+
+Keyword rewrites (for example, `REFUSED`) take precedence over the other.  Next,
+the `CNAME` rewrite.  After that, all other records's values are summed as one
+response, so this:
+
+```
+||example.com^$dnsrewrite=NOERROR;A;1.2.3.4
+||example.com^$dnsrewrite=NOERROR;A;1.2.3.5
+```
+
+Will result in a response with two `A` records.
+
+Currently supported RR types with examples:
+
+* `||4.3.2.1.in-addr.arpa.^$dnsrewrite=NOERROR;PTR;example.net.` adds a `PTR`
+  record for reverse DNS.  Reverse DNS requests for `1.2.3.4` to the
+  _AdGuardHome_ DNS server will result in `example.net`.
+
+  **NOTE:** the IP MUST be in reverse order, and the value MUST contain a final
+  dot.  See [RFC](https://tools.ietf.org/html/rfc1035#section-3.5).
+
+* `||example.com^$dnsrewrite=NOERROR;A;1.2.3.4` adds an `A` record with the
+  value `1.2.3.4`.
+
+* `||example.com^$dnsrewrite=NOERROR;AAAA;abcd::1234` adds an `AAAA` record with
+  the value `abcd::1234`.
+
+* `||example.com^$dnsrewrite=NOERROR;CNAME;example.org` adds a `CNAME` record.
+  See explanation above.
+
+* `||example.com^$dnsrewrite=NOERROR;HTTPS;32 example.com alpn=h3` adds an
+  `HTTPS` record.  Only a subsed of parameter values is supported: values must
+  be `contiguous` and, where a `value-list` is expected`, only one value is
+  currently supported:
+
+  ```
+  ipv4hint=127.0.0.1             // Supported.
+  ipv4hint="127.0.0.1"           // Unsupported.
+  ipv4hint=127.0.0.1,127.0.0.2   // Unsupported.
+  ipv4hint="127.0.0.1,127.0.0.2" // Unsupported.
+  ```
+
+  This will change in the future.
+
+* `||example.com^$dnsrewrite=NOERROR;MX;32 example.mail` adds an `MX` record
+  with precedence value `32` and exchange value `example.mail`.
+
+* `||example.com^$dnsrewrite=NOERROR;SVCB;32 example.com alpn=h3` adds and
+  `SVCB` value.  See `HTTPS` above.
+
+* `||example.com^$dnsrewrite=NOERROR;TXT;hello_world` adds a `TXT` record with
+  the value `hello_world`.
+
+* `||example.com^$dnsrewrite=NXDOMAIN;;` responds with an `NXDOMAIN` code.
+
+Exception rules remove one or all rules:
+
+* `||example.com^$dnsrewrite` removes all DNS rewrite rules.
+
+* `||example.com^$dnsrewrite=1.2.3.4` removes the DNS rewrite rule that adds an
+  `A` record with the value `1.2.3.4`.
+
 #### <a id="important"></a> <a id="important"></a> `important`
 
 The `$important` modifier applied to a rule increases its priority over any other rule without \$important modifier. Even over basic exception rules.