![如何使用 iptables 删除来自源的第一个 udp 数据包?](https://linux22.com/image/646101/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20iptables%20%E5%88%A0%E9%99%A4%E6%9D%A5%E8%87%AA%E6%BA%90%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%20udp%20%E6%95%B0%E6%8D%AE%E5%8C%85%EF%BC%9F.png)
为了防御分布式 UDP 洪水,我需要丢弃来自源的第一个 UDP 数据包并接受除第一个数据包之外的其他数据包。iptables 有能力做到这一点吗?如果可以,怎么做?
答案1
我不知道 iptables 是否具有您所要求的功能,但我可以解释为什么这样的功能对您没有帮助。
如果您收到大量不需要的 UDP 数据包,它们可能针对的是关闭的端口,也可能针对的是开放的端口。如果它们针对的是关闭的端口,内核将发送正确的 ICMP 错误响应。此错误响应很重要,因为如果没有它,调试网络问题将变得困难,并且在某些情况下,此错误响应也是其他人了解正在进行的攻击并缓解攻击的唯一方法。
发往已关闭端口的大量 UDP 数据包可能会导致大量 ICMP 错误消息。但是一个不错的堆栈会自动限制错误消息的速率,因此不必担心。UDP 数据包所消耗的带宽首先就被浪费了,在数据包已经浪费带宽之后,您无法通过丢弃该数据包来改变这一情况。
如果 UDP 数据包的目的地是开放端口,情况就会变得稍微复杂一些。由于 UDP 的无状态特性,数据包被传送到应用程序时,内核或应用程序根本无法知道源 IP 是真实的还是伪造的。如有必要,更高层协议有责任验证源 IP。DNS 和 NTP 就是在这方面失败的协议的例子,它们可能被滥用来实施反射/放大攻击。
由于 UDP 具有无状态特性,许多基于 UDP 的服务可以处理大量 UDP 数据包。如果它们不存储状态,那么就只是数据包进 - 数据包出,然后就忘了。服务并不真正关心源 IP 是否合法,而且由于服务的无状态特性,大量带有欺骗源的数据包不会导致内存浪费在状态上。
但是如果你部署的防火墙会丢弃来自源的第一个 UDP 数据包并让后面的数据包通过,那么防火墙需要维护状态。没有状态,它就无法知道数据包是否是第一个。
因此,现在您已将状态防火墙置于使用无状态协议进行通信的无状态服务之前。此时,大量带有欺骗性来源的数据包仍不会破坏服务,但会破坏防火墙。防火墙必须记住它收到的每个数据包的来源。因此,防火墙将耗尽内存,并且必须忘记一些先前收到的数据包。这意味着,即使对于合法来源,第二个、第三个等数据包也将被丢弃,因为防火墙根本记不住它曾看到过来自该来源的早期数据包。
因此,您要求的功能会将相对无害的 DoS 尝试转变为对防火墙的更强大的攻击。
这种情况并不新鲜。几十年前,TCP 堆栈容易受到 SYN 洪水攻击,这种攻击会出于上述完全相同的原因对服务进行 DoS 攻击。这就是发明 SYN cookies 的原因。
如果您正在设计任何在 UDP 上运行的新协议(或任何其他无状态协议),则必须牢记这一点并应用适当的设计标准,以使协议能够抵御欺骗尝试。如果您没有设计协议,那么您所能做的就是要求设计协议的人正确地设计协议。