如何拒绝除 DNS 查找之外的所有传入 UDP 数据包?

如何拒绝除 DNS 查找之外的所有传入 UDP 数据包?

我将服务器设置为拒绝所有传入的 UDP 数据包,以防止 UDP 泛洪。但是,有人告诉我,由于我使用自己的域名和服务器作为名称服务器,因此这可能会导致一些问题。我该如何解决这个问题?

我的防火墙是iptables,我的发行版是CentOS5.5。

答案1

如果您遵循标准安全实践,则您的默认防火墙策略将是阻止一切。如果您想允许传入的 DNS 请求,您所要做的就是编写一条规则以允许 tcp 和 udp 流量到端口 53。

您所谈论的流量是 UDP。UDP 是无状态的。这意味着,即使您只是丢弃了数据包,想要占用您连接的人也可以将数据包发送到您的地址。不过,您仍然可以使用 iptables 最近的匹配做一些半有用的事情,只允许系统实际接受和处理有限数量的流量。Evan 有一个例子SSH 的用法这里。我们可能必须查看您的整个防火墙规则集才能告诉您必须添加哪些规则。

如果您的系统遭受到严重的 DoS 攻击,您几乎肯定需要 ISP 的帮助,尝试使用 VPS 上的基于主机的防火墙来处理洪灾实际上并不是很有用。

如果您还没有,您应该考虑在完全不同的网络上为您的区域设置一些辅助 DNS 服务器。

答案2

在 Iptables 中,接受传入端口 53 的 UDP 流量并拒绝临时端口范围内的所有内容。

最高限制不应太高,否则,您的服务器将无法从服务器内部解析外部域(例如,当您执行“ping google.com”时)。在 Linux 操作系统上,32768 是套接字数量最多为 61000 的第一个临时端口(又名动态端口)。因此,32767 是静态分配端口的最高端口。这仅在不将您的服务器用作 DNS 解析器(又名 DNS 缓存)时才适用,即 /etc/resolv.conf 指向名称服务器 127.0.0.1 或 ::1 的服务器

以下是 tcpdump 的示例:

 23:10:13.315832 IP b.b.b.b.34507 > a.a.a.a.53: 23674% [1au] A? whitehouse.gov. (38)
 23:10:13.377619 IP a.a.a.a.53 > b.b.b.b.34507: 23674*- 1/2/3 A 172.230.122.69(122)
  1. bbbb 从端口 34507 请求名称服务器 aaaa 在端口 53 上为 whitehouse.gov 提供 A 记录
  2. 来自端口 53 的 aaaa 回答 bbbb 到端口 34507

通常,要在 Linux 上找到 UDP 和 TCP 的本地动态(也称为临时或私有)端口范围:

 cat /proc/sys/net/ipv4/ip_local_port_range

但是,它仅适用于不托管 DNS 解析器的服务器(例如,当您将 /etc/resolv.conf 指向 8.8.8.8 时)。

服务器不是 DNS 解析器:

 -A INPUT -p udp -m udp --dport 53 -j ACCEPT
 -A INPUT -p udp -m udp --dport 0:32767 -j DROP

服务器是一个 DNS 解析器:

-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p udp -m udp --dport 0:1023 -j DROP

如果您想托管自己的 DNS 解析器来解析所有域名,则应该考虑到这一点。

最好的办法是自己检查一下:

您可以使用以下方式监视发送端口

tcpdump udp and port 53 and not dst host *yourserveripaddress*

然后查看发送端口并尝试找到最小数字。此最小数字不应低于 --dport 0:xxxx 中的端口号 xxxx,否则会阻止或减慢 DNS 请求。

答案3

如何拒绝除 DNS 查找之外的所有传入 UDP 数据包?

可以更广泛地表述如下:我怎样才能拒绝所有不是用 Linux netfilter 发起的流量?

答案只有两行:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -j DROP

考虑到您不想过滤环回流量以节省一些 CPU 周期,您可以为其添加例外。

另一方面,如果你在同一台计算机上有 DNS 服务器,那么你的 qn 可以更精确地表述为“如何拒绝除 DNS 服务器的外部查询之外的所有传入 UDP 流量?“您可以使用相同的两行基础并添加另一行明确允许 DNS 流量:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A INPUT -p udp --dport 53 -j ACCEPT -m comment --comment "we serve DNS"
iptables -A INPUT -p tcp --dport 53 -j ACCEPT -m comment --comment "DNS uses TCP too sometimes"

iptables -A INPUT -j DROP

请注意,您通常不需要-m state为除第一行之外的任何内容指定任何内容,因为第一行是一个快捷方式,允许任何合法流量在其引导数据包获得进入许可后继续。

其他通知

@Zoredache 的建议根本recent不适用。recent用例范围非常有限,因为它不使用有效的数据结构,而是使用列表和哈希,没有树,不行。默认情况下,每个列表只能记住 100 个 IP,可以扩展,但无论如何,哈希对于搜索来说并不是很有效。

答案4

您真的需要允许互联网上的陌生人对您的服务器运行 DNS 查询吗?我猜您只需要确保您的防火墙允许您的服务器发出传出的 DNS 请求。

使用防火墙,您首先要阻止所有内容,然后非常精确/详细地打开特定的端口/服务/协议组合并通过 IP 地址(范围)进行限制。

相关内容