DNS over HTTPS 服务器
DNS 自诞生以来,在 UDP/53 和后来的 TCP/53 上都是未加密的,使其容易受到窥探攻击。有关可用于解决此漏洞的可用协议的更多信息,请参阅 域名解析#隐私和安全。本文涵盖了 DNS 服务器的三种可用协议中的两种,以及必要的代理配置,以提供 DNS over HTTPS (DoH) 和 DNS over TLS (DoT)。 AUR 中提供了多种 DoH 实用程序,包括 corednsAUR、 dns-over-https、 doh-proxyAUR 和 python-doh-proxyAUR。哪种可用的解决方案是合适的,取决于您的网络需求。
corednsAUR 同时提供缓存、非权威 DNS 服务器和 DoH 服务(需要引证)。
dns-over-https、 doh-proxyAUR 和 python-doh-proxyAUR 都提供了一个 HTTP 监听器,用于在您现有的 HTTPS 服务器后面进行代理,以及一个 stub 解析器,用于将 UDP/53 上的常规查询转发到安全的 DNS 服务器。此外,doh-proxyAUR 和 python-doh-proxyAUR 都提供独立的 HTTPS/2 服务器。
DoH 服务器/代理软件配置
coreDNS
您可以将 coreDNS 用作 DoH/DoT/gRPC DNS 服务器和/或 DoT 代理。默认配置文件应位于 /etc/coredns/Corefile
。
简单的配置文件示例如下
/etc/coredns/Corefile
protocol://domain:port { forward domain forward_to tls_servername domain_of_dot_server tls cert_path key_path }
第一个字符串是监听器,您可以使用以下协议:dns://
用于纯 DNS 协议,http://
用于 DNS over HTTPS,tls://
用于 DNS over TLS,grpc://
用于 gRPC(参见 [1])。如果协议留空(例如 example.com:53),则默认选择 dns://。 domain
用于匹配查询的域名,您可以使用特定的域名(例如 dns: //example.com: 53)或使用 .
(例如 dns: //.: 53)来匹配所有域名。通过 :port
您可以设置监听端口,您可以将其留空,将选择 53 端口。
forward
字符串用于 DNS 查询将转发到的位置。使用 .
作为 domain
以匹配所有域名。在 forward_to
中设置上游 DNS 服务器,将查询发送到该服务器,您可以为 DoT 服务器指定 tls://
协议。如果您使用上游 DoT 服务器,则需要为 TLS 协商设置 tls_servername
。
如果您使用 DoH、DoT 或 gRPC 协议,则 tls
字符串是强制性的。在此处按给定顺序放置证书和私钥路径。
简单 DoT 代理监听 53 端口并使用 Cloudflare DoT 服务器的配置示例
/etc/coredns/Corefile
. { forward . tls://1.1.1.1 { tls_servername cloudflare-dns.com } }
此外,您可以使用多个实例和转发插件
/etc/coredns/Corefile
https://.:443 { forward . 127.0.0.1 { forward example1.com 8.8.8.8 tls cert.pem key.pem } tls://example2.com:853 { tls cert.pem key.pem forward . tls://9.9.9.9 { tls_servername dns.quad9.net } }
启动/启用 coredns.service
单元。
dns-over-https
首先,安装 dns-over-https,设置后不要忘记启用并启动所需的服务。
Stub 解析器
您可以在安装后立即使用默认设置开始使用它。默认监听端口为 53 和 5380,如果其中一个端口已被绑定,则将被忽略。 启动/启用 doh-client.service
。
配置文件位于 /etc/dns-over-https/doh-client.conf
。您可以在 listen
部分更改所需的端口。配置文件中包含许多第三方 DoH 服务器,您只需取消注释您需要的服务器或写入未指定的服务器即可。您也可以使用多个解析器。将为每个请求随机选择其中一个。要强制 dns-over-https 按照要求的顺序使用解析器,请将 upstream_selector
设置为 weighted_round_robin
或 lvs_weighted_round_robin
,并更改正在使用的解析器中的权重值。
DoH 代理
用作 doh 服务器的配置文件位于 /etc/dns-over-https/doh-server.conf
。在 upstream
部分中,您可以设置所需的上游解析器及其要使用的协议。您可以将 dns-over-https 用作独立服务,也可以与 nginx 或 apache 等 HTTPS 服务一起使用。
对于独立使用,您需要将端口设置为 443 并指定正确的证书和密钥
/etc/dns-over-https/doh-server.conf
listen = [ "127.0.0.1:443", ] ... cert = "" key = ""
如果您想使用 HTTP 服务器进行缓存或与其他 HTTPS 服务一起使用,请在 doh-server.conf
中将证书和密钥字符串留空,并使用以下示例配置所需的 HTTP 服务器。请注意,此处使用的是默认 dns-over-https 端口。
nginx
/etc/nginx/nginx/site-available/doh
server { listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; server_name MY_SERVER_NAME; ssl_certificate /path/to/your/server/certificates/fullchain.pem; ssl_certificate_key /path/to/your/server/certificates/privkey.pem; location /dns-query { proxy_pass http://localhost:8053/dns-query; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
caddy
/etc/caddy/Caddyfile
MY_SERVER_NAME { reverse_proxy * localhost:8053 tls my@email.address try_files {path} {path}/index.php /index.php?{query} }
apache
/etc/httpd/conf/vhosts/doh.conf
<VirtualHost *:443> ServerName MY_SERVER_NAME Protocols h2 http/1.1 ProxyPass /dns-query http://[::1]:8053/dns-query ProxyPassReverse /dns-query http://[::1]:8053/dns-query </VirtualHost>
设置完成后,启动/启用 doh-server.service
。
doh-proxy
python-doh-proxy
安装 python-doh-proxyAUR。
Stub 解析器
如果您打算为传统应用程序向本地网络提供加密查询,请配置 stub 解析器
/etc/conf.d/doh-stub
LISTENPORT=5353 ADDR=127.0.0.1 DOMAIN=mydomain.tld NS=127.0.0.1 PORT=443
如果您没有办法为您的真实 DNS 服务器提供安全的转发 DNS 查询,您应该配置 DOMAIN 和 NS 以使用上游提供商之一(CloudFlare、OpenDNS 等,而不是 localhost)。如果您只需要为 localhost 提供查询,这就可以了。如果您需要为整个网络提供查询,如果您没有本地缓存或权威 DNS 服务器,您可以直接监听 53 端口 - 在这种情况下,您还需要使用真实的 IP 地址而不是环回适配器。
DoH 代理
如果您有现有的 HTTP 服务器并希望使用它代理 DNS 查询,请设置 HTTP 代理以监听端口 8080
/etc/conf.d/doh-httpproxy
NS=127.0.0.1 PORT=8080 ADDR=127.0.0.1
或者,您可以利用 doh-proxy 服务或上游 DoH 提供商来转发查询。
DoH 代理
如果您没有现有的 http 服务器,您可以配置 HTTPS/2 监听器
/etc/conf.d/doh-proxy
NS=127.0.0.1 UPSTREAMPORT=5353 ADDR=127.0.0.1 LISTENPORT=443 CERT=/etc/ssl/private/fullchain.pem KEY=/etc/ssl/private/privkey.pem
再次强调,根据需要进行调整,但请确保上游服务器有办法执行安全查询,否则您将创建一个循环。
独立 DNS 服务器配置
BIND
BIND 9.18 原生支持提供 DNS over HTTPS 和 DNS over TLS。有关详细信息,请参阅 BIND#Configuration。
作为解析器,使用 TLS 代理
典型情况:如果使用 ISC bind 作为当前的 DNS 提供商,并且您将为传统客户端和现代客户端提供转发服务和 DoH,您可能需要配置 named 将所有非本地查询转发到您的 stub 解析器,注释掉任何转发行并转发到 stub 解析器(如果您想回退到根,请省略仅转发)
/etc/named.conf
options { ... //forwarders { 8.8.8.8; 8.8.4.4; }; forwarders { 127.0.0.1 port 5353; }; forward only; ... }; ...
如果您想转发到外部 TLS 代理(通过 stunnel),请执行相同的操作,但仅使用 TCP/54(参见下面的 stunnel 配置)
/etc/named.conf
options { ... //forwarders { 8.8.8.8; 8.8.4.4; }; forwarders { 127.0.0.1 port 54; }; forward only; ... }; ... server 127.0.0.1 { tcp-only yes; }; ...
可选:如果使用 ISC bind 作为当前的 DNS 提供商,并且您将为传统客户端和现代客户端提供转发服务和 DoH,您可能需要配置 named 以监听备用端口,例如 TCP|UDP/54,而不是默认的 53 端口,以便您的 stub 解析器将监听标准端口。注释掉任何现有的“listen”行并添加以下内容(如果不需要 v6 行,请省略)
/etc/named.conf
... //listen-on { any; }; listen-on port 54 { any; }; listen-on-v6 port 54 { any; }; ...
Unbound
您可以通过在配置文件中添加端口 853 到监听,并指定证书和密钥路径,来轻松设置 DoT 服务器。
/etc/unbound/unbound.conf
server: ... interface: 127.0.0.1@853 tls-service-pem: /etc/unbound/public.pem tls-service-key: /etc/unbound/private.pem ...
DoH 服务器的设置与 DoT 相同,但所需的端口是 443。
/etc/unbound/unbound.conf
server: ... interface: 127.0.0.1@443 tls-service-pem: /etc/unbound/public.pem tls-service-key: /etc/unbound/private.pem ...
Web 服务器配置
Apache httpd 代理配置
在您的主 httpd.conf 或适当的 vhost 中配置一个监听 443 端口的代理。
/etc/httpd/conf/vhosts/yourhost.conf
... ProxyPass /dns-query http://[127.0.0.1]:8080/dns-query ProxyPassReverse /dns-query http://[127.0.0.1]:8080/dns-query ...
nginx 代理配置
DoT 代理
使用 Nginx stream 模块,您可以设置代理到上游 DNS。请注意,您可以使用本地 DNS 以及第三方。
/etc/nginx/nginx.conf
... stream { upstream dns { zone dns 64k; server 8.8.8.8:53; } server { listen 853 ssl; ssl_certificate /etc/nginx/ssl/certs/public.pem; ssl_certificate_key /etc/nginx/ssl/private/private.pem; proxy_pass dns; } } ...
DoH 代理
对于 DoH 的实现,您需要使用额外的 NJS 脚本。您需要从这个 GitHub 页面获取它,将其放入 /etc/nginx/njs.d/
,并确保安装了 nginx-mod-njs 包。
首先,您需要设置 stream 服务,它将从 nginx 的 HTTP/2 服务获取 DNS 请求,使用 js_filter
处理它以找到 DNS 数据包,并将其传递给上游 DNS 服务器。
/etc/nginx/nginx.conf
... stream { upstream dns { zone dns 64k; server 1.1.1.1:53; server { listen 127.0.0.1:8053; js_filter doh_filter_request; proxy_ssl on; proxy_pass dns; } } ...
然后,设置 HTTP/2 服务以监听 URI /dns-query 的 DNS 请求,并将它们中继到 stream 服务。请注意,需要将证书更改为有效的证书。
/etc/nginx/nginx.conf
... upstream dohloop { zone dohloop 64k; server 127.0.0.1:8053; } server { listen 443 ssl http2; ssl_certificate /etc/nginx/ssl/certs/public.pem; ssl_certificate_key /etc/nginx/ssl/private/private.pem; location /dns-query { proxy_http_version 1.0; proxy_pass http://dohloop; } } ...
您可以同时使用 DoT 和 DoH 服务,进行缓存和多上游 DNS。有关更多示例,请参阅这些配置文件。
通过 stunnel 配置 DNS over TLS
配置 stunnel 监听 TCP/853 端口的 TLS 连接,并转发到您的本地 DNS 提供商
/etc/stunnel/conf.d/DoT.conf
[dns] accept = 853 connect = 127.0.0.1:53 cert = /etc/ssl/private/fullchain.pem key = /etc/ssl/private/privkey.pem
配置 stunnel 监听 TCP/54 端口,并转发到上游安全提供商
/etc/stunnel/conf.d/DoT-Remote.conf
[dnsovertls] client = yes accept = 54 connect = 10.10.10.1:853 verifyChain = yes CAPath = /etc/ssl/certs checkHost = <your_host_name>