Skip to content
bacillation edited this page Dec 10, 2021 · 27 revisions

Introduction

Filters are a powerful set of built-in features, that let you control exactly what domain names and IP addresses your application are allowed to connect to, and when.

This can be used to block ads, trackers, malware, or anything you don't want your applications to load, or your devices to phone home to.

dnscrypt-proxy supports several types of filters:

  • blocklists: names, or patterns that will cause a query to immediately receive a REFUSED response.

  • IP blocklists: block responses containing specific IP addresses. This is especially useful to block trackers, that can use many different domain names, but share a small subset of IP addresses.

  • allow lists: names, or patterns that will cause a query to bypass blocklists. It will never be blocked.

Unlike cloud-based content filters, when a query is blocked, it will be blocked by dnscrypt-proxy itself. The DNS server will never see that query, and cannot log anything about the attempt.

The configuration for each of these lists can be found in the main configuration files, in the [blocked_names], [blocked_ips] and [allowed_names] sections.

As an illustration, here is the [blocked_names] section from the example configuration file:

  ## Path to the file of blocking rules (absolute, or relative to the same directory as the config file)
  # blocked_names_file = 'blocked-names.txt'

  ## Optional path to a file logging blocked queries
  # log_file = 'blocked-names.log'

  ## Optional log format: tsv or ltsv (default: tsv)
  # log_format = 'tsv'

Each filter has its own dedicated log file. If no logging is necessary, the log_file definition can just be removed or commented.

The TSV format is a simple list of TAB-separated values, that is easy to read.

The LTSV format is a structured format which is more suitable for automated log processing.

Filter patterns

Filters are loaded from files sharing a common format: a text file, with one line per pattern.

Here are examples of valid name patterns:

Pattern Result
ads.* matches anything with an "ads." prefix
*.example.com matches example.com and all names within that zone such as www.example.com
example.com identical to the above
=example.com block example.com but not *.example.com
*sex* matches any name containing that substring
ads[0-9]* matches any name with the prefix "ads" followed by one or more digits
ads[a-z]* matches any name with the prefix "ads" followed by one or more letters
ads*.example* *, ? and [] can be used anywhere, but prefixes/suffixes are faster

The example.com (shorthand for *.example.com) pattern is the most common, as it will block the domain itself, but also all names within that domain.

Filters are extremely fast at matching prefixes (ads.*), suffixes (*.example.com or example.com) and exact matches (=example.com), even with huge set of rules.

Other pattern types are slower and should be used with moderation.

Only prefix matching and exact matching make sense for IP addresses. Therefore, rules for the IP blocklists must be

  • Either complete IP addresses: [fe80::53:b2f8:d3a4:1e48] (IPv6) or 192.168.2.44 (IPv4)
  • Or prefixes: 192.168.*, [fe80:53:*]

Note that starting with version 2.0.34, name-based filters are applied both to the original query name itself, and to aliases (CNAME pointers).

For example www.nytimes.com doesn't have an IP address. This is actually an alias for nytimes.map.fastly.net. Blocking fastly.net would block *.fastly.net, as well as all aliases pointing to it (in that case example, www.nytimes.com).

A note on allow lists

A name can be allowed even if it wouldn't have been blocked by a blocklist. Since allow lists have their own log file, this can be used to log only names matching specific patterns, without blocking them.

allow lists can be useful when you use a 3rd party blocklist and you want to make sure that some domains are always accessible.

They can also be useful if you want to blocklist *.example.com but still allow api.example.com.

To avoid foot-shooting, allow lists are only applied to the query name, not to all the aliases it may resolve to.

Public blocklists

Instead of building blocklists from scratch, you can use some of the available ones, listed here:

Anybody can maintain a blocklist and share it online. Don't hesitate to do so, and to add links to that wiki page!

Time-based filters

By default, a rule has permanent validity.

However, specific rules can also be configured to only apply on certain days, or at certain times of the day.

This can be useful for parental control, or to restrict the traffic to a minimal subset of domains when no one in your house is supposed to be accessing the Internet.

In order to apply time-based rules, a schedule has to be defined. This happens in the [schedules] section of the dnscrypt-proxy.toml configuration file:

[schedules]

  [schedules.'time-to-sleep']
    mon = [{after='21:00', before='7:00'}]
    tue = [{after='21:00', before='7:00'}]
    wed = [{after='21:00', before='7:00'}]
    thu = [{after='21:00', before='7:00'}]
    fri = [{after='23:00', before='7:00'}]
    sat = [{after='23:00', before='7:00'}]
    sun = [{after='21:00', before='7:00'}]

  [schedules.'work']
    mon = [{after='9:00', before='18:00'}]
    tue = [{after='9:00', before='18:00'}]
    wed = [{after='9:00', before='18:00'}]
    thu = [{after='9:00', before='18:00'}]
    fri = [{after='9:00', before='17:00'}]

Here, we define two schedules, named time-to-sleep and work. Any number of schedules can be defined.

A schedule is a set of time ranges for days of the week.

For example,

tue = [{after='21:00', before='7:00'}]

Means that the schedule time-to-sleep will be active on Tuesday, from midnight to 7:00, and from 21:00 to midnight.

Multiple time ranges can be defined for the same day:

tue = [{after='7:00', before='10:00'}, {after='17:00', before='19:00'}]

And a schedule doesn't have to be defined for every day of the week. In the above example, the sat and sun days were not specified for the work schedule.

In order to apply a rule only when a schedule is active, the rule must be followed with @ and the schedule name.

For example, the following rule in a blocklist config file (i.e. dnscrypt-blocklist-domains.txt):

*.youtube.* @time-to-sleep

would block Youtube only between 23:00 and 7:00.

In order to only allow access to some domains at specific times or on specific days, these domains can also be permanently blocklisted, and time-based exceptions will be defined in the allowlist.

Allowlist-only

dnscrypt-proxy can also be configured to block everything, except domains that have been explicitly allowed.

In order to do so:

  • block all domains with a blocked-names.txt file that only contains *.*
  • add domains to allow in the allowed-names.txt file.

DNS rebinding protection

dnscrypt-proxy can perform DNS rebinding protection with its IP blocklist feature. Add the following entries to your blocked-ips.txt file:

# Localhost rebinding protection
0.0.0.0
127.0.0.*

# RFC1918 rebinding protection
10.*
172.16.*
172.17.*
172.18.*
172.19.*
172.20.*
172.21.*
172.22.*
172.23.*
172.24.*
172.25.*
172.26.*
172.27.*
172.28.*
172.29.*
172.30.*
172.31.*
192.168.*

Note: Some applications like Plex require rebinding protection to be disabled for local clients to be detected correctly. Instead of disabling it globally, you can allow the relevant domain(s). In the case of Plex, add plex.direct to allowed-names.txt. Captive portal domains which resolve to private addresses can also be allowed in the same way.

Rebinding protection testing

Test DNS rebinding protection with nslookup or dig:

nslookup net4.rebindtest.com        # not blocked, should return 4.4.4.4
nslookup net10.rebindtest.com       # 10.0.0.1 blocked
nslookup net127.rebindtest.com      # 127.0.0.1 blocked
nslookup net172.rebindtest.com      # 172.16.0.1 blocked
nslookup net192.rebindtest.com      # 192.168.0.1 blocked

Further reading/research:

Clone this wiki locally