使用 iptables 限制每个 IP 地址的最大连接数和每秒新连接数

eva*_*ine 38 iptables limit

我们有一个 Ubuntu 12.04 服务器,在端口 80 上有 httpd,我们想限制:

  • 每个 IP 地址到 httpd 的最大连接数为 10
  • 每秒到 httpd 的最大新连接数为 150

我们如何用 iptables 做到这一点?

tot*_*tti 51

iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 32 -j REJECT --reject-with tcp-reset  
Run Code Online (Sandbox Code Playgroud)

这将拒绝来自一个源 IP 的 15 个以上的连接。

iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 150/second --limit-burst 160 -j ACCEPT  
Run Code Online (Sandbox Code Playgroud)

在应用每秒 150 个新连接(数据包)的限制之前,在这 160 个新连接(实际上是数据包)中是允许的。

  • 第二条规则不适用于“新连接”。它明确影响现有(“ESTABLISHED”)连接。要进行新连接,您需要 --state NEW。您也可以考虑使用 `-m conntrack --ctstate` 代替 `-m state --state`。conntrack 是新的,并且相对于状态有所改进。 (5认同)
  • 上面将第二条规则添加到“新”连接的评论 - 不要这样做 - 它有效地将你的“输入”链变成了默认的“接受”!!! (3认同)
  • 要为所有端口设置此规则,只需删除 --dport 80。 (2认同)

Ian*_*osh 9

您希望 iptables 中的以下规则能够回答您问题中的两个要求:

iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT

iptables -t filter -I INPUT -p tcp --dport 80 -m state \
  --state RELATED,ESTABLISHED -j ACCEPT

# Adjust "--connlimit-above NN" to limit the maximum connections per IP
#   that you need.
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
  --connlimit-above 10 --connlimit-mask 32 -j DROP

# Adjust "--connlimit-above NNN" to the maximum total connections you
#   want your web server to support
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
  --connlimit-above 150 -j DROP
Run Code Online (Sandbox Code Playgroud)

因为我们正在使用 -I(根据 OP 请求),所以我们必须以相反的顺序执行它们,以便从下往上“读取”它们。

我还建议考虑将 --connlimit-mask NN 从 32 更改为 24。这会将完整的 C 类网络(同一范围内最多 256 个 IP 地址)限制为 10 个连接。您还可以使用任何其他无类别数字,例如 22 或 30,具体取决于您认为您的服务可能会被如何使用。

同样取决于您希望客户端的行为方式,您可能希望在上述两个规则中使用“-j REJECT --reject-with tcp-reset”而不是“-j DROP”,甚至仅在最大 150 个连接中使用规则。

如果拒绝连接,使用端口 80 的浏览器或软件将立即显示“不可用”状态,但 DROP 选项将导致客户端等待并重试几次,然后再报告站点不可用。我倾向于自己使用 DROP,因为它的行为更像是连接不良而不是离线服务器。

此外,如果连接限制在它仍在重试时回落到 150(或 10)以下,那么它最终将连接到您的服务器。

然而,REJECT 选项将导致您站点的流量减少一小部分,因为 DROP 将导致它在重试时发送额外的数据包。可能不是那么相关。

另一方面,如果您的端口 80 流量是集群的一部分,则 REJECT 将告诉集群控制器它已关闭并在重试超时期间停止向其发送流量。

RELATED,ESTABLISHED 规则假设您的默认规则是阻止所有流量(iptables -t filter -P INPUT DROP)。这只是接受属于已接受连接的其他数据包。

此外 --syn 告诉它注意(或计数)建立 TCP 连接的数据包。


小智 5

您需要使用connlimit允许您限制每个客户端 IP 地址(或地址块)与服务器的并行 TCP 连接数的模块。

/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
      --connlimit-above 10 -j DROP
Run Code Online (Sandbox Code Playgroud)