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

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

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

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

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

答案1

iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 32 -j REJECT --reject-with tcp-reset  

这将拒绝来自一个源 IP 的超过 15 个连接。

iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 150/second --limit-burst 160 -j ACCEPT  

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

答案2

您希望 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

因为我们使用 -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 连接的数据包。

答案3

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

/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
      --connlimit-above 10 -j DROP

相关内容