DNSCrypt (简体中文)
DNSCrypt 可以加密和认证用户和 DNS 解析服务器之间的数据传输。IP 数据本身没有任何变化,DNScrypt 可以避免 DNS 查询欺骗,确保 DNS 相应来自选择的 DNS 服务器。[1]
Contents
安装
安装 软件包 dnscrypt-proxy。
配置
从 /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv
选择解析服务器,然后 编辑 服务文件 dnscrypt-proxy.service
, -R
选项设置为解析服务器的第一列,例如如果选择 dnscrypt.eu-nl 作为解析服务器,文件应该是:
[Service] ExecStart= ExecStart=/usr/bin/dnscrypt-proxy -R dnscrypt.eu-nl
选择 dnscrypt 解析服务器后,修改 resolv.conf 文件,将当前解析服务器设置为 localhost:
nameserver 127.0.0.1
其它程序可能会覆盖这个设置,处理方式请参考 resolv.conf#Preserve DNS settings 这里。
最后 启动并启用 dnscrypt-proxy.service
.
提示和技巧
DNSCrypt as a forwarder for local DNS cache
It is recommended to run DNSCrypt as a forwarder for a local DNS cache, otherwise every single query will make a round-trip to the upstream resolver. Any local DNS caching program should work, examples below show configuration for Unbound, dnsmasq, and pdnsd.
First configure dnscrypt-proxy to listen on a port different from the default 53
, since the DNS cache needs to listen on 53
and query dnscrypt-proxy on a different port. Port number 40
is used as an example in this section:
# systemctl edit dnscrypt-proxy.socket
[Socket] ListenStream= ListenDatagram= ListenStream=127.0.0.1:40 ListenDatagram=127.0.0.1:40
Then restart dnscrypt-proxy.socket
and stop dnscrypt-proxy.service
if already running to let it be started by the .socket unit.
Example: configuration for Unbound
Configure Unbound to your liking (in particular, see Unbound#Local DNS server) and add the following lines to the end of the server
section in /etc/unbound/unbound.conf
:
do-not-query-localhost: no forward-zone: name: "." forward-addr: 127.0.0.1@40
Restart unbound.service
to apply the changes.
Example: configuration for dnsmasq
Configure dnsmasq as a local DNS cache. The basic configuration to work with DNSCrypt:
/etc/dnsmasq.conf
no-resolv server=127.0.0.1#40 listen-address=127.0.0.1
If you configured DNSCrypt to use a resolver with enabled DNSSEC validation, make sure to enable it also in dnsmasq:
/etc/dnsmasq.conf
proxy-dnssec
Restart dnsmasq.service
to apply the changes.
Example: configuration for pdnsd
Install pdnsd. A basic configuration to work with DNSCrypt is:
/etc/pdnsd.conf
global { perm_cache = 1024; cache_dir = "/var/cache/pdnsd"; run_as = "pdnsd"; server_ip = 127.0.0.1; status_ctl = on; query_method = udp_tcp; min_ttl = 15m; # Retain cached entries at least 15 minutes. max_ttl = 1w; # One week. timeout = 10; # Global timeout option (10 seconds). neg_domain_pol = on; udpbufsize = 1024; # Upper limit on the size of UDP messages. } server { label = "dnscrypt-proxy"; ip = 127.0.0.1; port = 40; timeout = 4; proxy_only = on; } source { owner = localhost; file = "/etc/hosts"; }
Restart pdnsd.service
to apply the changes.
Enable EDNS0
Extension Mechanisms for DNS that, among other things, allows a client to specify how large a reply over UDP can be.
Add the following line to your /etc/resolv.conf
:
options edns0
You may also wish to add the following argument to dnscrypt-proxy:
--edns-payload-size=<bytes>
The default size being 1252 bytes, with values up to 4096 bytes being purportedly safe. A value below or equal to 512 bytes will disable this mechanism, unless a client sends a packet with an OPT section providing a payload size.
Test EDNS0
Make use of the DNS Reply Size Test Server, use the dig command line tool from the bind-tools package to issue a TXT query for the name rs.dns-oarc.net:
$ dig +short rs.dns-oarc.net TXT
With EDNS0 supported, the output should look similar to this:
rst.x3827.rs.dns-oarc.net. rst.x4049.x3827.rs.dns-oarc.net. rst.x4055.x4049.x3827.rs.dns-oarc.net. "2a00:d880:3:1::a6c1:2e89 DNS reply size limit is at least 4055 bytes" "2a00:d880:3:1::a6c1:2e89 sent EDNS buffer size 4096"
Redundant DNSCrypt providers
Add new forward address
Extend the previous Unbound configuration in /etc/unbound/unbound.conf
to include an additional forward address that uses a different port. Port 41 is used in the below example:
do-not-query-localhost: no forward-zone: name: "." forward-addr: 127.0.0.1@40 forward-addr: 127.0.0.1@41
Create instanced systemd service
We will use an instanced systemd service to accomplish this. This will use one dnscrypt-proxy@.service
systemd service to handle as many distinct DNSCrypt resolves as we want.
First, we need /etc/systemd/system/dnscrypt-proxy@.service
containing:
[Unit] Description=DNSCrypt client proxy Documentation=man:dnscrypt-proxy(8) Requires=dnscrypt-proxy@%i.socket [Service] Type=notify NonBlocking=true ExecStart=/usr/bin/dnscrypt-proxy \ --resolver-name=%i Restart=always
This specifies an instanced systemd service that starts a dnscrypt-proxy using the service name specified after the @ symbol of a corresponding .socket file.
Add first dnscrypt-socket
You can now create two (or more!) socket files, specifying different DNSCrypt providers.
For the first dnscrypt-proxy socket, listening on 127.0.0.1@40 and connecting to the example dnscrypt.eu-nl provider, copy /lib/systemd/system/dnscrypt-proxy.socket
to /etc/systemd/system/dnscrypt-proxy@dnscrypt.eu-nl.socket
.
Add additional dyscrypt-sockets
For the second (or more) dnscrypt-proxy socket, copy /lib/systemd/system/dnscrypt-proxy.socket
to eg. /etc/systemd/system/dnscrypt-proxy@cloudns-syd.socket
Here you can replace the socket instance name to eg. cloudns-syd as one of those listed in providers name
column in /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv
and edit it to eg. port 41 and so forth.
[Unit] Description=dnscrypt-proxy-secondary listening socket [Socket] ListenStream=127.0.0.1:41 ListenDatagram=127.0.0.1:41 [Install] WantedBy=sockets.target
Apply new systemd configuration
Now we need to reload the systemd configuration.
# systemctl daemon-reload
Since we are replacing the default service with a different name, we need to explicitly stop and disable dnscrypt-proxy
and dnscrypt-proxy.socket
.
Now start/enable the new sockets, dnscrypt-proxy@dnscrypt.eu-nl.socket
and dnscrypt-proxy@cloudns-syd.socket
.
Finally restart unbound.service
Known issues
dnscrypt runs with root privileges
See FS#49881. To work around this, create an unprivileged user manually.
Create the user as follows:
# useradd -r -d /var/dnscrypt -m -s /sbin/nologin dnscrypt
Edit dnscrypt-proxy.service
, pointing --user
to the new user:
[Service] ExecStart= ExecStart=/usr/bin/dnscrypt-proxy -R dnscrypt.eu-nl --user=dnscrypt