DNSCrypt (简体中文)
DNSCrypt encrypts and authenticates DNS traffic between user and DNS resolver. While IP traffic itself is unchanged, it prevents local spoofing of DNS queries, ensuring DNS responses are sent by the server of choice. [1]
Contents
安装
安装 dnscrypt-proxy 软件包。
配置
When dnscrypt-proxy.socket
is enabled, dnscrypt-proxy accepts incoming requests on 127.0.0.1:53
to a DNS resolver. The default DNS resolver for dnscrypt-proxy.service
is dnscrypt.eu-nl. Compatible resolver names are visible in the first column of /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv
.
To change the default, edit dnscrypt-proxy.service
. It is recommended to choose a provider close to your location.
Modify the resolv.conf file and replace the current set of resolver addresses with localhost:
nameserver 127.0.0.1
Other programs may overwrite this setting; 参阅 resolv.conf#Preserve DNS settings for details.
提示和技巧
DNSCrypt 作为转发的本地DNS缓存
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.
示例: 配置 Unbound
配置 Unbound (简体中文) to your liking (remember to set /etc/resolv.conf to use the local DNS server[broken link: invalid section]) 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
重启 unbound.service
以应用更改。
示例: 配置 dnsmasq
配置 dnsmasq作为 本地DNS缓存, 基本配置工作在DNSCrypt:
/etc/dnsmasq.conf
no-resolv server=127.0.0.1#40 listen-address=127.0.0.1
如果你配置DNSCrypt并使用 resolver和启用DNSSEC 验证,要确保并启用dnsmasq:
/etc/dnsmasq.conf
proxy-dnssec
重启 dnsmasq.service
以应用更改。
示例: 配置 pdnsd
安装pdnsd. 基本配置工作在DNSCrypt:
/etc/pdnsd.conf
global { perm_cache=16384; 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; interface = any; uptest = if; interval = 15m; proxy_only=on; } source { owner=localhost; file="/etc/hosts"; } rr { name=localhost; reverse=on; a=127.0.0.1; owner=localhost; soa=localhost,root.localhost,42,86400,900,86400,86400; }
重启 pdnsd.service
以应用更改。
启用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.
测试 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
Creating redundancy is easy. Obtaining redundancy requires a simple edit to the above Unbound example and the addition of a second instance of the dnscrypt-proxy and service. Please be sure that you have the above Unbound example working prior to proceeding, as this tip extends the previous example.
Extend the above Unbound configuration in /etc/unbound/unbound.conf
to include an additional forward address that uses a different port. I use port 41 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 a copy of the dnscrypt-proxy.service and dnscrypt-proxy.socket in the /etc/systemd/system folder. I used the names dnscrypt-proxy-backup.service and dnscrypt-proxy-backup.socket. The names don't really matter, but they must be unique and the socket must use the same prefix as the service. Edit dnscrypt-proxy-backup.socket and change the port to 41, as follows:
[Unit] Description=dnscrypt-proxy listening socket [Socket] ListenStream=127.0.0.1:41 ListenDatagram=127.0.0.1:41 [Install] WantedBy=sockets.target
Edit dnscrypt-proxy-backup.service , as follows indicating a different dnscrypt server name and listening on the the port entered above, 41:
[Unit] Description=DNSCrypt client proxy Requires=dnscrypt-proxy.socket [Install] Also=dnscrypt-proxy.socket WantedBy=multi-user.target [Service] Type=simple NonBlocking=true ExecStart=/usr/bin/dnscrypt-proxy -R cloudns-can
You must force systemd to read the new service and socket files:
systemctl daemon-reload
Then enable the service and socket:
systemctl enable dnscrypt-proxy-backup.service dnscrypt-proxy-backup.socket
Start the service and socket. It's not really necessary to start the service as the socket will automatically launch it, but it does no harm.:
systemctl start dnscrypt-proxy-backup.service dnscrypt-proxy-backup.socket
Finally Restart Unbound:
systemctl restart unbound
If successful, your two selected dns providers should be the only ones found when using one of the dns leak test websites.
I really wanted to accomplish this with only a single .service and .socket files. Though the systemd documentation seems to indicate that it should be possible, I could not make it work. Here in lies a challenge to the more educated systemd folks out there. I'd love to see this further simplified.