DNS 过滤规则语法
前言
您可以使用 AdGuard DNS 过滤规则语法来使规则更加灵活,因此它们可以根据您的首选项来拦截内容。 AdGuard DNS 过滤规则语法可用于不同的 AdGuard 产品,如 AdGuard Home、 AdGuard DNS、 Windows/Mac/Android 的 AdGuard。
有三种不同的方法来编写主机拦截列表:
Adblock 风格的语法是基于使用 Adblock 风格的规则语法子集编写过滤规则的现代方法。 这样阻止拦截列表与浏览器广告拦截器兼容。
/etc/hosts
语法:使用与操作系统处理其主机文件相同的语法的老式、经过实践检验的语法。Domains-only 语法是一个简单的域名列表。
如果您要创建阻止列表,我们建议使用 Adblock 样式语法。 与旧式语法相比,它有几个重要的优点:
拦截列表大小。使用模式匹配允许您拥有单个规则,而不是数百个
/etc/hosts
条目。兼容性。您的屏蔽列表将与浏览器广告拦截器兼容,并且与浏览器过滤器列表共享规则会更容易。
可扩展性。在过去的十年中,Adblock 风格的语法有了很大的发展,我们认为我们能进一步扩展它并为网络范围的拦截器提供额外的功能。
如果有用户在建立一个 /etc/hosts
式的拦截列表或者多个过滤列表(无论类型如何),我们提供一个编译拦截列表的工具。 我们称它为 Hostlist compiler ,我们自己用它来创建 AdGuard DNS 过滤器。
基本示例
||example.org^
:阻止访问example.org
域及其所有子域,例如www.example.org
。@@||example.org^
:取消阻止对example.org
域及其所有子域的访问。1.2.3.4 example.org
:(注意,旧的/etc/hosts
语法)在 AdGuard Home 里用1.2.3.4
对example.org
域名的查询,但 没有 其子网域的查询。 在私人 AdGuard DNS 中,阻止对example.org
的访问。www.example.org
仍然允许。在 AdGuard Home 中,对主机使用未指定的 IP 地址(
0.0.0.0
)或本地地址(127.0.0.1
等)基本上等同于拦截该主机。# 返回 example.org 的 IP 地址 1.2.3.4。
1.2.3.4 example.org
通过响应 0.0.0.0 来阻止 example.org。
0.0.0.0 example.org
* `example.org`:一个简单的域规则。 阻止 `example.org` 域,而**不是**其子域。 `www.example.org` 仍然允许。
* `! 这是一行注释`和`# 这也是一行注释`:注释。
* `/REGEX/`:拦截访问与特定的正则表达式匹配的域名。
## Adblock 语法样式
This is a subset of the [traditional Adblock-style][adb] syntax which is used by browser ad blockers.
```none
rule = ["@@"] pattern [ "$" modifiers ]
modifiers = [modifier0, modifier1[, ...[, modifierN]]]
pattern
: the hostname mask. Every hostname is matched against this mask. The pattern can also contain special characters, which are described below.@@
: the marker that is used in the exception rules. Start your rule with this marker if you want to turn off filtering for the matching hostnames.modifiers
: parameters that clarify the rule. They may limit the scope of the rule or even completely change the way it works.
Special Characters
*
: the wildcard character. It is used to represent any set of characters. This can also be an empty string or a string of any length.||
: matches the beginning of a hostname, including any subdomain. For instance,||example.org
matchesexample.org
andtest.example.org
but nottestexample.org
.^
: the separator character. Unlike browser ad blocking, there's nothing to separate in a hostname, so the only purpose of this character is to mark the end of the hostname.|
: a pointer to the beginning or the end of the hostname. The value depends on the character placement in the mask. For example, the ruleample.org|
corresponds toexample.org
but not toexample.org.com
.|example
corresponds toexample.org
but not totest.example
.
Regular Expressions
If you want even more flexibility in making rules, you can use regular expressions instead of the default simplified matching syntax. If you want to use a regular expression, the pattern has to look like this:
pattern = "/" regexp "/"
Examples:
/example.*/
will block hosts matching theexample.*
regexp.@@/example.*/$important
will unblock hosts matching theexample.*
regexp. Note that this rule also implies theimportant
modifier.
Comments
Any line that starts with an exclamation mark or a hash sign is a comment and it will be ignored by the filtering engine. Comments are usually placed above rules and used to describe what a rule does.
Example:
! This is a comment.
# This is also a comment.
Rule Modifiers
You can change the behavior of a rule by adding modifiers. Modifiers must be located at the end of the rule after the $
character and be separated by commas.
Examples:
||example.org^
is the matching pattern.$
is the delimiter, which signals that the rest of the rule are modifiers.important
is the modifier.You may want to use multiple modifiers in a rule. In that case, separate them by commas:
||example.org^$client=127.0.0.1,dnstype=A
||example.org^
is the matching pattern.$
is the delimiter, which signals that the rest of the rule are modifiers.client=127.0.0.1
is theclient
modifier with its value,127.0.0.1
, is the delimiter. And finally,dnstype=A
is thednstype
modifier with its value,A
.
NOTE: If a rule contains a modifier not listed in this document, the whole rule must be ignored. This way we avoid false-positives when people are trying to use unmodified browser ad blockers' filter lists like EasyList or EasyPrivacy.
client
The client
modifier allows specifying clients this rule is applied to. There are two main ways to identify a client:
By their IP address or CIDR prefix. This way works for all kinds of clients.
By their name. This way only works for persistent clients (in AdGuard Home) and devices (in Private AdGuard DNS), which you have manually added.
NOTE: In AdGuard Home, ClientIDs are not currently supported, only names are. If you have added a client with the name “My Client” and ClientID
my-client
spell your modifier as$client='My Client'
as opposed to$client=my-client
.
The syntax is:
$client=value1|value2|...
You can also exclude clients by adding a ~
character before the value. In this case, the rule is not be applied to this client's DNS requests.
$client=~value1
Client names usually contain spaces or other special characters, which is why you should enclose the name in quotes. Both single and double ASCII quotes are supported. Use the backslash (\
) to escape quotes ("
and '
), commas (,
), and pipes (|
).
NOTE: When excluding a client, you must place ~
outside the quotes.
Examples:
@@||*^$client=127.0.0.1
: unblock everything for localhost.||example.org^$client='Frank\'s laptop'
: blockexample.org
for the client namedFrank's laptop
only. Note that quote ('
) in the name must be escaped.||example.org^$client=~'Mary\'s\, John\'s\, and Boris\'s laptops'
: blockexample.org
for everyone except for the client namedMary's, John's, and Boris's laptops
. Note that comma (,
) must be escaped as well.||example.org^$client=~Mom|~Dad|Kids
: blockexample.org
forKids
, but not forMom
andDad
. This example demonstrates how to specify multiple clients in one rule.||example.org^$client=192.168.0.0/24
: blockexample.org
for all clients with IP addresses in the range from192.168.0.0
to192.168.0.255
.
denyallow
You can use the denyallow
modifier to exclude domains from the blocking rule. To add multiple domains to one rule, use the |
character as a separator.
The syntax is:
$denyallow=domain1|domain2|...
This modifier allows avoiding creating unnecessary exception rules when our blocking rule covers too many domains. You may want to block everything except for a couple of TLD domains. You could use the standard approach, i.e. rules like this:
! Block everything.
/.*/
! Unblock a couple of TLDs.
@@||com^
@@||net^
The problem with this approach is that this way you will also unblock tracking domains that are located on those TLDs (i.e. google-analytics.com
). Here's how to solve this with denyallow
:
*$denyallow=com|net
Examples:
*$denyallow=com|net
: block everything except for*.com
and*.net
.@@*$denyallow=com|net
: unblock everything except for*.com
and*.net
.||example.org^$denyallow=sub.example.org
. blockexample.org
and*.example.org
but don't blocksub.example.org
.
dnstype
The dnstype
modifier allows specifying DNS request or response type on which this rule will be triggered.
The syntax is:
$dnstype=value1|value2|...
$dnstype=~value1|~value2|~...
The names of the types are case-insensitive, but are validated against a set of actual DNS resource record (RR) types.
Do not combine exclusion rules with inclusion ones. This:
$dnstype=~value1|value2
is equivalent to this:
$dnstype=value2
Examples:
||example.org^$dnstype=AAAA
: block DNS queries for the IPv6 addresses ofexample.org
.||example.org^$dnstype=~A|~CNAME
: only allowA
andCNAME
DNS queries forexample.org
, block out the rest.
NOTE: Before version v0.108.0, AdGuard Home would use the type of the request to filter the response records, as opposed to the type of the response record itself. That caused issues, since that meant that you could not write rules that would allow certain CNAME
records in responses in A
and AAAA
requests. In v0.108.0 that behaviour was changed, so now this:
||canon.example.com^$dnstype=~CNAME
allows you to avoid filtering of the following response:
ANSWERS:
-> example.com
canonical name = canon.example.com.
ttl = 60
-> canon.example.com
internet address = 1.2.3.4
ttl = 60
dnsrewrite
The dnsrewrite
response modifier allows replacing the content of the response to the DNS request for the matching hosts. Note that this modifier in AdGuard Home works in all rules, but in Private AdGuard DNS — only in custom ones.
Rules with the dnsrewrite
response modifier have higher priority than other rules in AdGuard Home.
The shorthand syntax is:
$dnsrewrite=1.2.3.4
$dnsrewrite=abcd::1234
$dnsrewrite=example.net
$dnsrewrite=REFUSED
The keywords MUST be in all caps (e.g. NOERROR
). Keyword rewrites take precedence over the other and will result in an empty response with an appropriate response code.
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 $dnsrewrite
modifier with the NOERROR
response code may also has empty RRTYPE
and VALUE
fields.
The CNAME
one is special because AdGuard Home 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
Next, the CNAME
rewrite. After that, all other records' 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 aPTR
record for reverse DNS. Reverse DNS requests for1.2.3.4
to the DNS server will result inexample.net
.NOTE: the IP MUST be in reverse order. See RFC 1035.
||example.com^$dnsrewrite=NOERROR;A;1.2.3.4
adds anA
record with the value1.2.3.4
.||example.com^$dnsrewrite=NOERROR;AAAA;abcd::1234
adds anAAAA
record with the valueabcd::1234
.||example.com^$dnsrewrite=NOERROR;CNAME;example.org
adds aCNAME
record. See explanation above.||example.com^$dnsrewrite=NOERROR;HTTPS;32 example.com alpn=h3
adds anHTTPS
record. Only a subset of parameter values is supported: values must becontiguous
and, where avalue-list
isexpected
, 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 be changed in the future.
||example.com^$dnsrewrite=NOERROR;MX;32 example.mail
adds anMX
record with precedence value32
and exchange valueexample.mail
.||example.com^$dnsrewrite=NOERROR;SVCB;32 example.com alpn=h3
adds aSVCB
value. See theHTTPS
example above.||example.com^$dnsrewrite=NOERROR;TXT;hello_world
adds aTXT
record with the valuehello_world
.||_svctype._tcp.example.com^$dnsrewrite=NOERROR;SRV;10 60 8080 example.com
adds anSRV
record with priority value10
, weight value60
, port8080
, and target valueexample.com
.||example.com^$dnsrewrite=NXDOMAIN;;
responds with anNXDOMAIN
code.$dnstype=AAAA,denyallow=example.org,dnsrewrite=NOERROR;;
responds with an emptyNOERROR
answers for allAAAA
requests except the ones forexample.org
.
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 anA
record with the value1.2.3.4
.
important
The important
modifier applied to a rule increases its priority over any other rule without the modifier. Even over basic exception rules.
Examples:
In this example:
||example.org^$important
@@||example.org^||example.org^$important
will block all requests to*.example.org
despite the exception rule.In this example:
||example.org^$important
@@||example.org^$importantthe exception rule also has the
important
modifier, so it will work.
badfilter
The rules with the badfilter
modifier disable other basic rules to which they refer. It means that the text of the disabled rule should match the text of the badfilter
rule (without the badfilter
modifier).
Examples:
||example.com$badfilter
disables||example.com
.@@||example.org^$badfilter
disables@@||example.org^
.NOTE: The
badfilter
modifier currently doesn't work with/etc/hosts
-style rules.127.0.0.1 example.org$badfilter
will not disable the original127.0.0.1 example.org
rule.
ctag
The ctag
modifier can only be used in AdGuard Home.
It allows to block domains only for specific types of DNS client tags. You can assign tags to clients in the AdGuard Home UI. In the future, we plan to assign tags automatically by analyzing the behavior of each client.
The syntax is:
$ctag=value1|value2|...
If one of client's tags matches the ctag
values, this rule applies to the client. The syntax for exclusion is:
$ctag=~value1|~value2|...
If one of client's tags matches the exclusion ctag
values, this rule doesn't apply to the client.
Examples:
||example.org^$ctag=device_pc|device_phone
: blockexample.org
for clients tagged asdevice_pc
ordevice_phone
.||example.org^$ctag=~device_phone
: blockexample.org
for all clients except those tagged asdevice_phone
.
The list of allowed tags:
By device type:
device_audio
: audio devices.device_camera
: cameras.device_gameconsole
: game consoles.device_laptop
: laptops.device_nas
: NAS (Network-attached Storages).device_pc
: PCs.device_phone
: phones.device_printer
: printers.device_securityalarm
: security alarms.device_tablet
: tablets.device_tv
: TVs.device_other
: other devices.
By operating system:
os_android
: Android.os_ios
: iOS.os_linux
: Linux.os_macos
: macOS.os_windows
: Windows.os_other
: other OSes.
By user group:
user_admin
: administrators.user_regular
: regular users.user_child
: children.
/etc/hosts
-Style Syntax
For each host a single line should be present with the following information:
IP_address canonical_hostname [aliases...]
Fields of the entries are separated by any number of space or tab characters. Text from the #
character until the end of the line is a comment and is ignored.
Hostnames may contain only alphanumeric characters, hyphen-minus signs (-
), and periods (.
). They must begin with an alphabetic character and end with an alphanumeric character. Optional aliases provide for name changes, alternate spellings, shorter hostnames, or generic hostnames (for example, localhost
).
Example:
# This is a comment
127.0.0.1 example.org example.info
127.0.0.1 example.com
127.0.0.1 example.net # this is also a comment
In AdGuard Home, the IP addresses are used to respond to DNS queries for these domains. In Private AdGuard DNS, these addresses are simply blocked.
Domains-Only Syntax
A simple list of domain names, one name per line.
Example:
# This is a comment
example.com
example.org
example.net # this is also a comment
If a string is not a valid domain (e.g. *.example.org
), AdGuard Home will consider it to be an Adblock-style rule.
Hostlists Compiler
If you are maintaining a blocklist and use different sources in it, Hostlists compiler may be useful to you. It is a simple tool that makes it easier to compile a hosts blocklist compatible with AdGuard Home, Private AdGuard DNS or any other AdGuard product with DNS filtering.
What it's capable of:
Compile a single blocklist from multiple sources.
Exclude the rules you don't need.
Cleanup the resulting list: deduplicate, remove invalid rules, and compress the list.