跳转至内容

pdnsd

来自 ArchWiki

pdnsd 是一个用于本地缓存 DNS 信息的 DNS 服务器。正确配置后,它可以显著提高宽带连接的浏览速度。与 BINDdnsmasq 相比,它可以在重启后保留其缓存;“p” 代表持久化。请参阅 域名解析#DNS 服务器 以与其他 DNS 服务器进行比较。

安装

安装 pdnsd 包。

配置

该软件包提供了一个示例配置文件:/usr/share/doc/pdnsd/pdnsd.conf。自定义的配置文件应创建在 /etc/pdnsd.conf

格式

pdnsd.conf 文件采用相当简单的格式,但与您可能遇到的其他大多数配置文件有所不同。它包含各种类型的节(sections)。一个节以节的类型名称和开括号({)开始,并以闭括号(})结束。节不能嵌套。

每个块内部是一系列格式如下的选项:

option_name=option_value;

请注意末尾的分号;与其他一些格式不同,它不是可选的。

注释以 #/* 开始。前者直到行尾,后者直到遇到 */

DNS 服务器

pdnsd 需要知道至少一个 DNS 服务器的地址才能从中收集 DNS 信息。此设置部分取决于您是使用宽带连接还是拨号连接。宽带用户应使用第一个服务器节作为起点,拨号用户使用第二个,并将其他服务器节注释掉。

label
label 选项用于唯一标识一个服务器节。它是完全任意的,但一个好的选择是您的 ISP 的名称。
ip
此选项在默认的宽带配置中使用,它告诉 pdnsd 要使用的 DNS 服务器的地址。多个地址应以单个逗号分隔,逗号前后可带可选空格。您可以直接从 /etc/resolv.conf 复制地址。
file
可以使用 file 选项代替 ip 来指定一组 DNS 服务器 IP。其值是要使用的服务器文件的路径,格式为 resolv.conf。默认的拨号连接配置使用它,因为 PPP 客户端会用从 PPP 服务器获取的地址写入 /etc/ppp/resolv.conf。除非您想使用比 ISP 默认提供的 DNS 服务器不同的服务器,否则您无需更改它。
interface
uptest=if 选项的网络接口。默认为 eth0,这很可能是错误的。如果 pdnsd 服务已启动但未返回任何 DNS 记录,这可能设置错误。

服务器节的其余部分无需更改即可正常工作。有关所有可用选项的详细信息,请参阅 pdnsd 手册

带有 DHCP 连接的 DNS 服务器

安装 netctl 后,pdnsd 可以通过 openresolv 获取名称服务器的 IP 地址,并且当您使用 自动切换配置文件 时,通知会动态更新。

要配置此功能,请删除宽带服务器节,并更新拨号连接服务器节,进行以下更改:

   label = resolvconf;
   file = /etc/pdnsd-resolv.conf;

编辑 /etc/resolvconf.conf 以将 pdnsd 配置为 openresolv 的一个订阅者。

name_servers=127.0.0.1
pdnsd_resolv=/etc/pdnsd-resolv.conf

并运行 resolvconf -u 以使用名称服务器的地址更新 /etc/pdnsd-resolv.conf(忽略关于 pdnsd 套接字无法访问的错误消息)。此更新仅在手动启动 pdnsd 之前需要一次。

OpenDNS

pdnsd.conf 文件内置了 OpenDNS 设置;您可以简单地删除(或注释掉)它上方的拨号和宽带节(注意不要删除文件顶部必需的全局设置),然后取消注释以使用 OpenDNS 解析。

但是,OpenDNS 对 Google 做了一些奇怪的事情。如果您想避免这种行为(对许多人来说,这会将 Google 请求从例如 15ms 增加到 75ms+),您需要拒绝 OpenDNS 返回其 Google 代理机的结果。确切的服务器 IP 会变化,但您可以运行 drill www.google.com @208.67.222.222(由 ldns 提供)来查找当前 IP。如果查询被代理,您会知道,因为服务器名称会解析为类似 google.navigation.opendns.com 的内容。在一次尝试中,这些地址是 208.67.216.230208.67.216.231

一旦知道 IP 地址,就可以在 OpenDNS server { …} 声明中替换 pdnsd.conf 中已存在的 rejected IP。确保保留前缀。

OpenNIC 是 OpenDNS 的可靠替代方案。

注意 此示例使用 OpenDNS 服务器。请将其替换为您信任的 DNS 解析器。请参阅 域名解析#第三方 DNS 服务

测试

您现在应该有一个工作的 pdnsd 守护进程了。启动它。

测试它现在是否正常工作。

第二次使用 127.0.0.1 查询任何地址时,查询时间应小于 1 毫秒。

系统设置

确保 启用 pdnsd.service

它在 network.target 之后立即启动,因为依赖网络的服务的 DNS 是有效的,即 network-online.target(请参阅 上游说明)。

对于拥有两个或更多网卡的任何 PC,为了让 pdnsd 对任何有线和无线连接正常工作,请通过在 pdnsd.conf 中指定正确的 interface 为每个网卡配置单独的配置文件。

技巧与提示

家庭宽带用户的性能设置

许多用户使用宽带连接,其 DNS 服务器速度慢或不可靠,并希望使用 pdnsd 作为缓存服务器以尽量减少所需的 DNS 查询次数。在完成上述设置后,/etc/pdnsd.conf 中的以下设置将有助于提高其在此角色中的性能:

在全局设置下

neg_rrs_pol=on;
par_queries=1;

在服务器设置下

proxy_only=on;
purge_cache=off;

neg_rrs_pol=on; 策略意味着当查询收到否定响应时,pdnsd 服务器将缓存结果,即使响应不是“权威”的。这很重要,因为观察 DNS 查询会发现有很多针对 AAAA 记录(IPv6 的 DNS 查询)的请求,而许多域不使用 IPv6,因此这些请求永远不会返回结果,并且即使在域名称已缓存后,这些请求仍会发送。在这种角色下,您不希望额外的 DNS 请求被发送。此选项与 proxy_only=on; 选项结合使用很重要,以最大程度地减少系统发出的查询数量。

如果您在下面的“server”节中指定了多个 DNS 服务器,则 par_queries=1; 选项很有用。它指定一次并行查询的数量。例如,如果在“server”节中列出了四个 DNS 服务器,并且 par_queries=2;(默认值),则将同时查询前 2 台服务器,如果前 2 台服务器都失败,pdnsd 将继续查询接下来的 2 台服务器。上述设置意味着一次只查询一台 DNS 服务器,因此您可以在“server”节中列出两个或多个 DNS 服务器,只有当第一台服务器失败时才会查询第二台服务器。这有助于最大程度地减少流量,但如果第一台服务器失败,您将不得不等待超时后第二台服务器才会查询。根据您的偏好调整此设置,如果您在“server”节中只指定了一台服务器,则无需担心它。

proxy_only=on; 设置在常见问题解答中有所提及,对于家庭宽带用户很重要,因为您通常只使用一两个 DNS 服务器,而不是尝试进行完整的、分层的名称解析,就像完整的 DNS 服务器会做的那样。此设置将阻止 pdnsd 解析到“权威”名称服务器,而是接受“server”节中已指定的 DNS 服务器的结果。再次,这减少了您需要进行的查询数量,从而提高了性能。

purge_cache=off; 设置告诉 pdnsd 即使缓存条目已超过 DNS 记录的生存时间(TTL)也不要删除它们。当您的 ISP 的 DNS 服务器宕机时,这可能非常有用,并且您希望即使在中断期间也能访问常用域的名称查找。当缓存已满时,记录仍会根据年龄从缓存中移除(有关如何设置缓存大小,请参阅 pdnsd.conf(5))。

其他性能设置

TTL (生存时间)

从服务器返回的每个 DNS 资源记录都包含一个最大生存时间(TTL)。这告诉接收者可以存储该记录多长时间以及何时对其进行新的查找。许多 DNS 记录的 TTL 相对较短,例如 3600(一小时)。这意味着在一小时后,pdnsd 将尝试对该条目进行新的查找,无论它是否可用缓存记录。通过设置全局最小 TTL 来覆盖此默认 TTL 将会提高性能,从而减少查找次数。使用过长的最小 TTL 的缺点是,缓存的记录可能已过时(主机的 IP 地址可能已更改,但您的客户端不会知道这一点,因为它会收到缓存的地址)。然而,大多数 IP 地址不会每小时甚至每天更改。

默认情况下,时间以秒为单位指定;或者,您可以附加“m”、“h”、“d”或“w”来指定分钟、小时、天或周。

全局设置中的 min_ttl 设置了缓存记录的最小 TTL,使 pdnsd 忽略从服务器接收到的记录中的默认 TTL。在连接缓慢或 DNS 服务器缓慢的情况下,您可能希望将其设置为几个小时以减少查找次数(例如 min_ttl=6h;)。

全局设置中的 neg_ttl 设置了不存在域的最小 TTL。如果服务器告知 pdnsd 某个域不存在,它将在此时间段过去之前不会再次尝试查找该域。

超时

设置更短的超时意味着 pdnsd 将更快地放弃整个查询或给定的服务器查询,从而提高性能。设置超时过短的缺点是 pdnsd 可能因为服务器未获得足够响应时间而返回错误。

全局设置中的 timeout 决定了 pdnsd 何时放弃整个查询并向您的浏览器或其他客户端返回错误。设置全局超时选项可以让你在服务器节中(见下文)指定相当短的超时间隔。效果是,如果第一台服务器响应缓慢,pdnsd 将相对较快地开始查询其他服务器(但仍会继续监听第一台服务器的响应)。(如果您使用 query_method=tcp_udp,建议将全局超时设置至少是最大服务器超时时间的两倍,否则 pdnsd 可能没有时间在 TCP 连接超时时尝试 UDP 查询。)

全局设置中的 tcp_qtimeout 确定 TCP 查询连接可以保持打开状态的时间。

服务器设置中的 timeout 决定了 pdnsd 将等待每个服务器响应的时间。将其设置为较短的时间意味着 pdnsd 将更快地放弃无响应的服务器并继续查询下一个可用服务器,有时会得到更快的整体响应时间。在快速连接上,将其设置为 4 或 5 秒是合理的。

调试

要查看 pdnsd 为特定查找正在使用哪些服务器、超时如何工作以及域使用的默认 TTL 是什么,请在全局设置中打开调试:

debug=on;

重新启动 pdnsd 并使用 systemd journal 监控 pdnsd.service 以查看更改。

# journalctl -f -u pdnsd.service

确保在常规使用时关闭调试,因为它可能会降低性能。

缓存大小

默认情况下,pdnsd 会自动为 /etc/hosts 中的所有条目创建权威记录。如果您有很多条目,例如将其用于广告屏蔽,/etc/pdnsd.conf 提供的默认最大缓存大小可能不够大,导致 DNS 请求未按预期时间缓存。

要增加缓存大小,请编辑配置文件“全局设置”部分中的 perm_cache 行(大小以 KB 为单位)。

或者,您可以通过在“source”节中添加选项 authrec=off 来阻止 pdnsd 预先加载您的 hosts 文件。如果由于任何原因,将 authrec 设置为 off 无效,一个简单的解决方法是创建一个单独的 hosts 文件(例如 /etc/hosts-pdnsd),其中仅包含您的系统信息,并将您的“source”节指向该文件,同时保留原始 hosts 文件。这样,pdnsd 将仅在执行查找时引用 /etc/hosts。例如:

/etc/hosts-pdnsd
#<ip-address>	<hostname.domain.org>	<hostname>
127.0.0.1	localhost.localdomain	my_hostname
::1		localhost.localdomain	localhost

局域网共享服务器

如果您网络中有多个计算机,您可能希望让 pdnsd 成为所有计算机的 DNS 服务器。这样,您的整个网络可以共享一个 DNS 缓存,使重复查找更快。为此,只需在 global 节中将 server_ip 设置为您的网络接口名称(通常是 eth0)。如果您设置了防火墙,请告知它允许来自您网络上任何地址到 53 端口的连接。

现在,您可以配置网络上的其他计算机,使其使用运行 pdns 的计算机作为其主要的 DNS 服务器。

域名屏蔽

pdnsd 允许您指定它永远不返回结果的主机或域名。这使得您可以将其用作基本的广告或内容拦截器等。在 pdnsd.conf 中创建一个新的 neg 节。neg 节有两个主要选项。name 是您要屏蔽的主机或域名的名称。types 可以设置为 domain 以屏蔽给定域中的所有主机。默认的 pdnsd.conf 提供了一个屏蔽 doubleclick.net 所有广告的示例。

由于每个块只能设置一个域名,因此在 pdnsd.conf 中直接屏蔽广告、跟踪器或恶意内容的效果不佳。您可能希望创建单独的配置文件专门用于这些列表,例如 /etc/pdnsd.d/spam_domains,并在 pdnsd.conf 中添加一个 include 节,如下所示:

include {file="/etc/pdnsd.d/spam_domains";}

或者,可以在现有的加载 /etc/hosts 的节之外添加一个 source 节,该节加载一个 /etc/hosts 格式的文件,将域名绑定到特殊 IP 地址 0.0.0.0 – 但这将不会屏蔽子域,因为 /etc/hosts 不允许通配符。这样做相当于将规则添加到 /etc/hosts,但避免了巨大的 /etc/hosts 文件,该文件可能会导致某些应用程序出现问题。

pdnsd-ctl

来自 pdnsd-ctl(8) § DESCRIPTION

pdnsd-ctl 控制 pdnsd,一个具有永久缓存的代理 DNS 服务器。请注意,必须在 pdnsd 命令行或配置文件中指定选项来启用状态控制套接字,然后才能使用 pdnsd-ctl

为此,请在 /etc/pdnsd.conf 的全局节中包含以下选项:

status_ctl = on;

/etc/pdnsd.conf 的全局节中。

如果您更改了 /etc/pdnsd.conf 中的缓存目录,您将不得不使用 -c 选项运行 pdnsd-ctl

# pdnsd-ctl -c path/to/cache

一些有用的命令供您开始...

查看缓存

# pdnsd-ctl dump

刷新缓存

# pdnsd-ctl empty-cache

DNSCrypt

pdnsd 可以与 DNSCrypt 一起使用。DNSCrypt 对域名查找进行加密。pdnsd 在需要时查询 DNSCrypt。一个示例配置可以在 DNSCrypt#pdnsd 中找到。

故障排除

uptest for 192.168.x.x 的结果:失败

您可以成功 ping 您的 ISP 的 动态 DNS 服务器,即使日志显示以下内容:

# journalctl -f -u pdnsd.service
result of uptest for 192.168.x.x: failed

检查 /etc/pdnsd.conf 全局节中配置的接口是否存在。

interface = any;

或者服务器节中的接口:

interface=enp2s0;

可以通过运行:ifconfig 来找到正确的名称。

常见问题解答

问) 我感觉速度没有明显提升。为什么?
答) 运行本地 DNS 缓存所带来的额外速度提升全部在于连接到服务器所需的时间。吞吐量,也就是人们通常所说的速度,不会受到影响。在浏览网页时,这种差异最为明显,因为这通常涉及从多个服务器下载小文件。在连接速度较慢的情况下,尤其是拨号连接,吞吐量是主要瓶颈,因此百分比差异不会那么大。
问) 为什么现在比以前慢了?
答) 您几乎肯定在 pdnsd.conf 的某个服务器节中关闭了 proxy_only 选项。默认情况下,pdnsd 会频繁地向多个 DNS 服务器查询域名,以获得尽可能准确的响应。proxy_only 选项禁用了此功能。如果您使用 ISP 提供的 DNS 服务器,则应将其打开。