

























前几天给电脑折腾加密 DNS 的时候突然意识到,我还没有给我用过的所有 Linux 服务器设置过加密 DNS。为了增加点安全性,还是配置一下的好,毕竟自己电脑都会注意这些问题,没理由不在服务器上弄。本文会介绍如何在 RHEL 系发行版(以 AlmaLinux 10 为例)里通过 DNSCrypt-Proxy 设置 Cloudflare DNS over HTTPS,并配置 NetworkManager 服务来让系统 DNS 指向 DNSCrypt-Proxy。
对于 Debian 系,可以使用已经自带的 systemd-resolved 来配置 DNS over TLS(但不支持 DoH),也可以卸载 systemd-resolved 转而使用 DNSCrypt-Proxy,但我还是建议用系统自带的。另外,国内服务器用不了 Cloudflare 加密 DNS,请自行设置国内的加密 DNS 服务。
封面图来自 DNSCrypt / dnscrypt-proxy GitHub,版权声明见 ISC License。
由于我们会使用 53 端口为本机提供 DNS 服务,所以需要先检查是否有程序占用该端口:
# 需要安装 lsof 包
sudo lsof -i:53如果没有返回任何结果就没问题。但如果有的话,就需要你看下是什么在占用了。当然也可以将 DNSCrypt-Proxy 的监听端口改为 53 以外的,但我懒得。
然后用 dig cloudflare-dns.com 检查下目前是否使用外部 DNS 来解析域名(需安装 bind-utils 包),只要不是本机 IP 就行,如图,目前使用的 1.1.1.1 来解析:
注意:如果你这里看到的 DNS 服务器是像 169.254.169.254 这样的 Instance Metadata Service IP,修改之后可能会影响内网其他 VPS 主机名的解析。如果你只有一台 VPS,或者愿意修改 hosts,那应该不影响。

先启用 CRB 支持,并安装 epel-release 软件包来启用 EPEL 源(其它发行版方法可能不同):
sudo dnf config-manager --set-enabled crb
sudo dnf install epel-release
sudo dnf update然后安装 dnscrypt-proxy 包:
sudo dnf install dnscrypt-proxy安装好后先将原有的配置备份一份,然后就可以开始修改配置文件了:
sudo cp /etc/dnscrypt-proxy/dnscrypt-proxy.toml /etc/dnscrypt-proxy/dnscrypt-proxy.toml.bak
sudo vim /etc/dnscrypt-proxy/dnscrypt-proxy.toml以下以带 IPv6 的服务器为例配置,如果只有 IPv4,则可以跳过所有和 IPv6 有关的配置项。
配置文件里注释也写的很清楚了,请按需自行修改,不一定完全要按照我的。
将第 30 行(Vim 使用 :set nu 可以看行号)的 server_names 注释删掉,改为以下这样,就可以使用 Cloudflare 加密 DNS 了:
server_names = ['cloudflare', 'cloudflare-ipv6']具体有哪些 DNS 服务器可选,请访问 DNSCrypt DNS 服务器列表。然后将第 40 行的监听地址改为:
listen_addresses = ['127.0.0.1:53', '[::1]:53']将第 66 行的 ipv6_servers = false 改为 ipv6_servers = true,表示程序可以使用 IPv6 的 DNS 服务器。
将 81 行的 require_dnssec = false 改为 require_dnssec = true,表示程序必须使用支持 DNSSEC 的 DNS 服务器。
将 http3 = false 改为 http3 = true,来让程序可以使用 HTTP/3 协议连接到 DNS 服务器(Cloudflare 是支持的),速度理论上更快。
将 http3_probe = false 改为 http3_probe = true,来让程序首选 HTTP/3 协议连接到 DNS 服务器,并在连接失败时退回 HTTP/2。
修改好后保存,然后创建一个缓存文件夹,再使用以下命令启动 DNSCrypt-Proxy,并设置开机自启:
sudo mkdir -p /var/cache/dnscrypt-proxy
sudo systemctl enable --now dnscrypt-proxy.service接着可以用 sudo systemctl status dnscrypt-proxy.service 来查看日志。第一次启动耗时较长,因为程序会从网上下载目前的 DNS 列表。等看到 dnscrypt-proxy is ready 就行了,如图:

然后使用 dig @127.0.0.1 cloudflare-dns.com 检查下有没有返回查询信息,有就行。
我们可以直接使用 nmcli 工具来配置,先使用 sudo nmcli connection show 来找到连接外网使用的配置名称(注意,第一列是连接配置名称,最后一列才是网卡名称),如图:

此处以 cloud-init eth0(对应网卡为 eth0)为例:
sudo nmcli connection modify "cloud-init eth0" ipv4.dns "127.0.0.1" ipv6.dns "::1"
sudo nmcli connection modify "cloud-init eth0" ipv4.ignore-auto-dns yes ipv6.ignore-auto-dns yes
sudo nmcli connection up "cloud-init eth0"然后使用以下两条命令来检查 DNS 是否设置成功:
sudo nmcli connection show "cloud-init eth0" | grep dns
dig cloudflare-dns.com如果第一条命令返回的 ipv4.dns 和 ipv6.dns 是对应的本地地址,并且 dig 所使用的 DNS 服务器也是本地地址即可。

我们可以使用 tcpdump 命令(需要安装 tcpdump 包)来捕获经过外网网卡,且端口为 53 的流量:
sudo tcpdump -n -i eth0 port 53开始监听后,我们打开一个新的 SSH 窗口执行 dig @1.1.1.1 cloudflare-dns.com,再回到 tcpdump 就可以发现有明文的 DNS 响应信息,如图:

我们再执行 dig cloudflare-dns.com(这次使用刚才设置好的 DNSCrypt-Proxy),然后回到 tcpdump,发现看不到 DNS 响应信息。这是因为 DNSCrypt-Proxy 是通过 443 端口请求的 Cloudflare 加密 DNS,不会走 53 端口。
我们将这个 tcpdump CTRL + C 掉,再 sudo tcpdump -n -i eth0 port 443 来监听 443 端口。执行 dig cloudflare-dns.com 可以发现,DNS 走的是 443 端口,UDP 协议来解析,也就是我们刚才设置的 HTTP/3,如图:

默认情况下 DNSCrypt-Proxy 使用 root 身份启动。为了安全性,你可以新建一个专用用户来运行,并且通过 sudo systemctl edit dnscrypt-proxy.service 修改服务文件,来让其以非 root 运行。具体请自行研究。
另外,进程默认以 system_u:system_r:unconfined_service_t:s0 的 SELinux 上下文运行,没有任何限制,也不是很安全。你可能需要自行研究如何更改掉 unconfined_service_t,同时能让进程读取配置文件和缓存目录,并且监听 53 端口。
你可以去 DNSCrypt-Proxy 的 GitHub Wiki 页面 研究更多功能,也欢迎到我 主页 看更多内容。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。