-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Hosts Blocklists
- Introduction
- Basic examples
- Adblock-style syntax
/etc/hosts-style syntax- Domains-only syntax
- Hostlists compiler
There are three different approaches to writing hosts blocklists:
-
Adblock-style syntax: the modern approach to writing filtering rules based on using a subset of the Adblock-style rule syntax. This way blocklists are compatible with browser ad blockers.
-
/etc/hostssyntax: the old, tried-and-true approach that uses the same syntax that operating systems do for their hosts files. -
Domains-only syntax: a simple list of domain names.
If you are creating a blocklist for AdGuard Home, we recommend using the Adblock-style syntax. It has a couple of important advantages over the old-style syntax:
-
Blocklists size. Using pattern matching allows you to have a single rule instead of hundreds of
/etc/hostsentries. -
Compatibility. Your blocklist will be compatible with browser ad blockers, and it will be easier to share rules with a browser filter list.
-
Extensibility. For the last decade the Adblock-style syntax has greatly evolved, and we don't see why we can't extend it even more and provide additional features for network-wide blockers.
If you're maintaining an /etc/hosts-style blocklist or if you maintain
multiple filter lists regardless of their type, we provide a tool that can be
used to compile blocklists for AdGuard Home. We called it Hostlist
compiler and we use it ourselves to create AdGuard DNS filter.
-
||example.org^: block access to theexample.orgdomain and all its subdomains, likewww.example.org. -
@@||example.org^: unblock access to theexample.orgdomain and all its subdomains. -
1.2.3.4 example.org: (attention, old/etc/hosts-style syntax) respond with1.2.3.4to queries for theexample.orgdomain but not its subdomains.www.example.orgremains allowed.Using the unspecified IP address (
0.0.0.0) or a local address (127.0.0.1and alike) for a host is basically the same as blocking that host.# Returns the IP address 1.2.3.4 for example.org. 1.2.3.4 example.org # Blocks example.com by responding with 0.0.0.0. 0.0.0.0 example.com
-
example.org: a simple domain rule. Blocksexample.orgdomain but not its subdomains.www.example.orgremains allowed. -
! Here goes a commentand# Also a comment: comments. -
/REGEX/: block access to the domains matching the specified regular expression
This is a subset of the traditional Adblock-style syntax which is used by browser ad blockers.
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.
-
*: 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.orgmatchesexample.organdtest.example.orgbut 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.orgbut not toexample.org.com.|examplecorresponds toexample.orgbut not totest.example.
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.*/$importantwill unblock hosts matching theexample.*regexp. Note that this rule also implies theimportantmodifier.
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.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.
NOTE: Modifiers don't work with /etc/hosts-style rules. For example,
127.0.0.1 example.org$badfilter will not disable the original 127.0.0.1 example.org rule.
Examples:
-
||example.org^$important
||example.org^is the matching pattern.$is the delimiter, which signals that the rest of the rule are modifiers.importantis the modifier. -
You may want to use multiple modifiers in a rule. Separate them by commas in this case:
||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.1is theclientmodifier with its value,127.0.0.1, is the delimiter. And finally,dnstype=Ais thednstypemodifier 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.
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, that is clients which you have manually added on the “Settings → Client settings” page.
NOTE: 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=~value1Client 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 keep ~ out of the quotes.
Examples:
-
@@||*^$client=127.0.0.1: unblock everything for localhost. -
||example.org^$client='Frank\'s laptop': blockexample.orgfor the client namedFrank's laptoponly. Note that quote (') in the name must be escaped. -
||example.org^$client=~'Mary\'s\, John\'s\, and Boris\'s laptops': blockexample.orgfor 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.orgforKids, but not forMomandDad. This example demonstrates how to specify multiple clients in one rule. -
||example.org^$client=192.168.0.0/24: blockexample.orgfor all clients with IP addresses in the range from192.168.0.0to192.168.0.255.
Available since v0.106.0.
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 save 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|netExamples:
-
*$denyallow=com|net: block everything save for*.comand*.net. -
@@*$denyallow=com|net: unblock everything save for*.comand*.net. -
||example.org^$denyallow=sub.example.org. blockexample.organd*.example.orgbut don't blocksub.example.org.
Available since v0.105.0.
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|value2is equivalent to this:
$dnstype=value2Examples:
-
||example.org^$dnstype=AAAA: block DNS queries for the IPv6 addresses ofexample.org. -
||example.org^$dnstype=~A|~CNAME: only allowAandCNAMEDNS 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=~CNAMEallows 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
Available since v0.105.0.
The dnsrewrite response modifier allows replacing the content of the response
to the DNS request for the matching hosts. 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=REFUSEDThe 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.
Before v0.107.3 the only possible keyword is REFUSED.
Since v0.107.3 response codes NOERROR, NXDOMAIN, and SERVFAIL are also
supported.
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;;Since v0.107.3 a $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.netthen the response will be something like:
$ nslookup example.com my.adguard.localServer: 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.5will 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 aPTRrecord for reverse DNS. Reverse DNS requests for1.2.3.4to the AdGuard Home DNS server will result inexample.net.NOTE: the IP MUST be in reverse order. Before v0.106.0, the value had to contain a final dot, but since v0.106.0 both forms are accepted. See RFC 1035.
-
||example.com^$dnsrewrite=NOERROR;A;1.2.3.4adds anArecord with the value1.2.3.4. -
||example.com^$dnsrewrite=NOERROR;AAAA;abcd::1234adds anAAAArecord with the valueabcd::1234. -
||example.com^$dnsrewrite=NOERROR;CNAME;example.orgadds aCNAMErecord. See explanation above. -
||example.com^$dnsrewrite=NOERROR;HTTPS;32 example.com alpn=h3adds anHTTPSrecord. Only a subset of parameter values is supported: values must becontiguousand, where avalue-listis 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.mailadds anMXrecord with precedence value32and exchange valueexample.mail. -
||example.com^$dnsrewrite=NOERROR;SVCB;32 example.com alpn=h3adds anSVCBvalue. See theHTTPSexample above. -
||example.com^$dnsrewrite=NOERROR;TXT;hello_worldadds aTXTrecord with the valuehello_world. -
||_svctype._tcp.example.com^$dnsrewrite=NOERROR;SRV;10 60 8080 example.comadds anSRVrecord with priority value10, weight value60, port8080, and target valueexample.com. -
||example.com^$dnsrewrite=NXDOMAIN;;responds with anNXDOMAINcode. -
$dnstype=AAAA,denyallow=example.org,dnsrewrite=NOERROR;;responds with an emptyNOERRORanswers for allAAAArequests except the ones forexample.org.NOTE: this is available since v0.107.3.
Exception rules remove one or all rules:
-
@@||example.com^$dnsrewriteremoves all DNS rewrite rules. -
@@||example.com^$dnsrewrite=1.2.3.4removes the DNS rewrite rule that adds anArecord with the value1.2.3.4.
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^$importantwill block all requests to*.example.org. despite the exception rule. -
In this example:
||example.org^$important @@||example.org^$important
the exception rule also has the
importantmodifier, so it will work.
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$badfilterdisables||example.com. -
@@||example.org^$badfilterdisables@@||example.org^.
The ctag modifier 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.orgfor clients tagged asdevice_pcordevice_phone. -
||example.org^$ctag=~device_phone: blockexample.orgfor 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.
-
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. Modifiers, such as client or badfilter, don't work with these
rules.
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 commentThe IP addresses are used to respond to the DNS queries for these domains.
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 commentIf a string is not a valid domain (e.g. *.example.org), AdGuard Home will
consider it to be an Adblock-style rule.
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 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.