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
ListenStream and ListenDatagram options need to be cleared with empty assignment before overriding, otherwise the new address would be added to the list of sockets. See systemd#Editing provided units for details.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
interface: 0.0.0.0@53 and access-control: your-network/subnet-mask allow inside the server: section so that the other computers can connect to the server. A client must be configured with nameserver address-of-your-server in /etc/resolv.conf.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