客户端主机名¶
管理 → 客户端 页面有一个客户端主机名设置。打开显示客户端主机名后,凡是页面原本会显示原始地址(例如 172.16.2.111)的地方,只要你网络的 DNS 服务器能给出一个名称,就会改用这个名称显示。
本页说明这个设置实际在问 DNS 服务器什么问题、为什么仅有一条 DNS 重写记录通常无法满足它,以及如何让你的 DNS 服务器正确回答这个问题。
该开关的作用¶
开关打开后,应用会针对每个客户端地址向你网络的 DNS 服务器提出同一个问题:"这个地址是谁?"如果服务器给出了名称,页面就会用这个名称代替数字显示;如果服务器没有答案,页面照旧显示地址。该设置默认关闭。
已保存的昵称始终优先于 DNS 提供的名称,DNS 提供的名称又始终优先于原始地址。
在客户端非常多的网络上,一次只会查询最近活跃的那部分客户端,以免一次页面加载就向你的 DNS 服务器发出大量查询。达到这个上限时,客户端页面会给出提示,超出上限的客户端会继续显示地址,直到之后的刷新为止。
为什么仅有 DNS 重写记录还不够¶
假设你在 DNS 服务器里添加了一条重写记录,把 test.lan 指向 172.16.2.111。这条记录回答的是"test.lan 指向哪个地址?",这是一条正向记录。
客户端主机名功能问的是相反的问题:"172.16.2.111 属于哪个名称?"这需要反向记录,也叫 PTR 记录(PTR 是 "pointer",指针的缩写)。正向记录和反向记录是两份独立的数据,创建其中一个并不会自动创建另一个。绝大多数 DNS 服务器,包括 lancache-dns 容器本身,默认只会创建正向记录,除非你专门为反向记录做配置。
所以一条能正常工作的 test.lan → 172.16.2.111 重写记录,单靠它本身对这个设置没有任何帮助。你需要为 172.16.2.111 单独创建一条指回 test.lan 的 PTR 记录。
构建反向区域名称¶
PTR 记录不挂在 test.lan 下面,而是挂在一个由地址本身构造出来的特殊区域下,这个区域叫 in-addr.arpa。构造方法是:把地址中的四段数字倒序排列,再加上 .in-addr.arpa。
以 172.16.2.111 为例:
111.2.16.172.in-addr.arpa 就是你要为其创建 PTR 记录的名称,而你在这里填写的答案就是 test.lan。
添加反向记录¶
反向记录必须存在于你网络的 DNS 服务器上,本应用无法替你创建。运行 dnsmasq 的路由器(OpenWrt 以及许多厂商固件)会在通过 DHCP 分配地址时,自动为每台设备同时创建正向名称和对应的反向记录。如果你的路由器不会这样做,或者该地址是静态配置而不是 DHCP 分配的,可以查阅你所用 DNS 服务器的文档,搜索"反向 DNS"或"PTR 记录",了解如何手动添加。
dnsmasq、OpenWrt 和 Pi-hole¶
这三者底层用的都是同一套软件(dnsmasq),修复方式也完全相同。
使用 host-record,而不是 address:
host-record 会在同一行里同时创建正向记录和反向(PTR)记录。
而一条普通的重写记录只会创建正向记录:
host-record 和 address 这一个字的差别,就是整个问题的根源。如果你现在用的是 address=,把它改成 host-record=,PTR 记录就会随之出现。
自行检查¶
在网络上任意一台设备运行下面两条命令,就能知道问题出在哪一边。
检查正向方向:
检查反向方向,这才是该功能真正需要的:
如果第一条命令能返回地址,第二条却返回类似"Non-existent domain"或"can't find … NXDOMAIN"这样的结果,那正是本页要解决的情况:正向记录存在,反向(PTR)记录不存在。按照上面的说明添加 PTR 记录后,再次运行第二条命令确认。
端口 53 重定向陷阱¶
有些路由器会把网络上所有的 DNS 请求都重定向到同一台服务器,不管设备本身配置的是哪个 DNS 服务器。如果你的路由器就是这样,那么把某台设备指向另一个 DNS 服务器不会有任何变化:所有设备最终都会从同一个被劫持的解析器那里得到完全相同的答案,与各自的设置无关。
一个快速的判断方法:查询一个你网络上根本不存在的 DNS 服务器地址。
如果 172.16.99.99 并不是真实存在的服务器,你却依然得到了答案,说明你的流量正被重定向到路由器选定的某个 DNS 服务器。在这样的网络里,修改 lancache-manager 自身与 DNS 相关的设置也无济于事,因为每一条查询离开你的设备后,最终都会走到同一个地方。
如果什么名称都看不到¶
应用会建立一份简短的 DNS 服务器列表并按顺序询问,最多八台:
- 您在要查询的 DNS 服务器中填写的地址(如果填写了)。
- 本机已配置的 DNS 服务器。直接运行在机器上时,这是 DHCP 分配的地址;在容器中通常是 Docker 自带的解析器,它会转发到宿主机的解析器。
- 本机路由所经过的网关。直接运行在机器上或使用 host 网络时,这就是您的局域网路由器;在 bridge 网络的容器中则是 Docker 网桥,它不会给出答案,只多花一次查询。
- 通过 host.docker.internal 得到的 Docker 宿主机地址。这是 bridge 网络下的应用访问同一台机器上解析器的途径。
- 正在运行且对外提供 DNS 53 端口的容器。
- 出现过客户端的每个子网的 .1 与 .254。所有私有网络都使用这两种惯例,因此没有任何地址是写死的:子网来自您自己的客户端。在容器中路由表只能看到 Docker 网桥,这一步正是访问家用路由器 DHCP 名称的途径。
收到“名称不存在”的答复后会继续询问下一个,这样只有缓存、没有反向记录的 DNS 就不会挡住真正有记录的服务器;某个服务器返回真实名称后,下次会优先询问它。只会询问私有地址和回环地址,因此这些查询不会到达公共 DNS,也不会联系上述列表之外的任何地址,更不会扫描客户端网段。
第 5 步和第 6 步都可以在客户端页面上单独关闭。向 Docker 查询 DNS 服务器对应第 4 步和第 5 步,关闭后客户端名称查询将完全不再接触 Docker 套接字。查询各客户端子网上的路由器对应第 6 步,也就是应用唯一自行推导的地址;关闭后,应用只会与有人明确配置的 DNS 服务器通信。
除非开启向访客显示客户端名称,否则不会向访客会话显示客户端名称。该项默认关闭:访客看到的是缓存概况,而不是网络中设备的清单。关闭时,访客在任何位置都只会看到原始地址:服务器会像该功能已关闭一样答复访客,也不会告知访客应用被配置为查询哪些 DNS 服务器。
如果完全没有任何地址显示名称,通常是因为这些服务器上都没有反向记录。运行 dnsmasq 的路由器会记录通过 DHCP 分配地址的设备名称,但该功能需要开启,且这些记录仍需能通过上述某台服务器查询到。如果您知道哪台服务器保存着这些记录而应用没有找到它,请在客户端页面的要查询的 DNS 服务器中填入它的地址,应用会优先询问它。
有些设备无论用哪种方式查询都不会响应。如果一台设备既没有反向记录,也不响应直接的名称查询,那么就没有任何自动方式能发现它的名称,此时给它设置一个手动昵称是唯一的办法。