允许本地 DNS 流量(到远程 DNS 服务器)通过应用程序/守护进程进行过滤,而不仅仅是通过端口进行过滤

允许本地 DNS 流量(到远程 DNS 服务器)通过应用程序/守护进程进行过滤,而不仅仅是通过端口进行过滤

互联网上有很多关于如何使用 iptables 允许 DNS 流量的示例,但它们都只是添加一条愚蠢的规则,例如

ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           state NEW udp dpt:53

它根据流量发送到的端口对其进行过滤。DNS 服务器确实使用端口 53,但这不是很不安全吗?试图穿过防火墙的恶意应用程序难道不会直接与同一端口上的服务器通信吗?它只是一个 UDP 端口,因此使用这样的规则,任何数据都可能发送到任何服务器,只要它们只使用该端口。

仅允许 DNS 客户端使用端口发送实际 DNS 查询的另一种正确方法是什么?哪个应用程序在 Ubuntu 上执行 DNS 请求,是否可以仅允许该应用程序/守护程序通过防火墙?还是特定用户?

答案1

但是,对于所有其他应用程序来说,DNS 不是由 DNS 守护进程来处理的吗?还是系统上执行的每个 DNS 查询都是由发出命令的进程本身执行的?

两者都有。情况有所不同。

  • 传统上,Linux 系统没有专用的系统解析器。使用 libc 函数的程序会自动加载 libnss_dns.so 并在同一进程内进行查询。

  • 然而,glibc有一个“nscd”守护进程,它充当所有 nsswitch 查找(包括 DNS)的中央缓存。如果此守护进程正在运行,则它会加载 libnss_dns.so 并对整个系统进行 DNS 查询,而其他正常进程则不会。(但它旨在充当缓存 - 如果回复速度太慢,则程序将再次回退到直接查询。)

    类似地,一些 Linux 发行版带有“systemd-resolved”,它提供它自己的模块 libnss_resolve.so – 如果启用此功能,则所有地址查询都将转发到 systemd-resolved 守护进程。(除非失败,在这种情况下配置通常会再次回退到标准“dns”模块。)

  • Libc 只处理“名称 ↔ 地址”查找,但需要记住的是,有些程序需要的不仅仅是这些,所以它们使用其内部解析器——它们将只读取 DNS 服务器地址,resolv.conf但会发出并发送自己的 DNS 请求,例如使用 libresolv、libunbound、libldns、python-dns 或类似程序。

    例如,ssh想要查询 SSHFP 记录;postfix/smtp可能想要查询 TLSA 记录;Minecraft 想要查询 SRV 记录;任何使用 Kerberos 的应用程序都会想要 TXT、SRV、URI 记录。它们必须发送自己的 DNS 查询,因为系统名称解析器不足。

  • 最后,一些发行版设置了一个 DNS 解析器,它实际上在“localhost:53”上提供 DNS 服务(通常是 Unbound 或 Dnsmasq)。在这种情况下,所有程序(即使是那些自己进行查询的程序)实际上只与“localhost”上的本地解析器对话,而这个解析器才是真正与外界对话的解析器。

简而言之:如果你真的想要严格控制出站网络访问,则设置本地 DNS 服务器使用 Unbound/BIND/Knot(无论是针对机器还是整个​​ LAN)并仅限制对该 DNS 服务器的访问。

相关内容