iptables 速率限制连接请求

iptables rate limiting connection request

为了设置上下文,我们有一个旧服务器为来自大量客户端的连接提供服务。连接是 tcp 并使用二进制协议。最近随着客户端的增加,服务器似乎无法处理所有传入的连接,尤其是在服务器重新启动时。在这种情况下,服务器进入某种不一致状态,在 CLOSE_WAIT.

中丢失连接

如果客户端连接请求错开,服务器最终会承担负载。我们通过模拟 docker.

中的客户端验证了这一点

由于服务器没有内置速率限制,我决定试用 iptables 看看我是否可以使用 iptables 中的速率限制功能来错开传入的连接请求。连接可以来自相同的 ip 或不同的 ip。

速率限制不应影响任何已建立的连接,而只会影响较新的连接(3 次握手)。由于客户端有重试逻辑,他们最终会来重新连接。所以不想通过 ip 进行速率限制,因为即使来自同一源 ip 的所有连接最终也应该连接而不会干扰已建立的连接。

这是我正在使用的 iptables 规则。这是正确的方法吗?

   iptables -A INPUT -i eth0 -p tcp --dport 9000 -m state --state NEW,ESTABLISHED -m recent --set -j ACCEPT

   iptables -A INPUT -i eth0 -p tcp --dport 9000 -m state --state NEW -m recent --update --seconds 600 --hitcount 11 -j REJECT --reject-with tcp-reset

我不熟悉 iptables,目前正在 Ubuntu 14.04 上使用 ufw 包装器。以上思路来源于此linkhttps://www.cyberciti.biz/tips/howto-limit-linux-syn-attacks.html.

目的是防止 SYN 泛滥,但最终会变慢并允许所有客户端建立连接。

经过长时间的反复试验才弄明白这一点。解决方案是使用 iptables 限制模块来限制任何新传入连接的连接速率。

最终在 /etc/ufw/before.rules

中添加了以下链

-A ufw-before-input -p tcp --dport 9000 -m state --state 相关,已建立 -j 接受 -A ufw-before-input -p tcp --dport 9000 -m state --state NEW -m limit --limit 4/min --limit-burst 4 -j 接受 -A ufw-before-input -p tcp --dport 9000 -j DROP

参考资料