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


37

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

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

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

Answers:


48
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个新连接(实际上是数据包)是允许的。


1
可以将以上设置设置为在所有端口上运行,而不仅仅是80端口吗?
EminezArtus

1
您确定这是每个IP吗?
LatinSuD 2015年

2
要设置这条规则对所有端口,只是删除--dport 80
丹Pritts

5
第二条规则不适用于“新连接”。它明确影响现有(“已建立”)连接。要进行新连接,您需要--state NEW。您也可以考虑使用-m conntrack --ctstate代替-m state --state。conntrack是新的,与状态相比有所改进。
Dan Pritts 2015年

2
上面为NEW连接添加第二条规则的注释-请勿这样做-可以有效地将您的INPUT链变成默认规则accept
斯图尔特·卡达尔

8

您希望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将告知群集控制器它已关闭,并在重试超时期间停止向其发送流量。

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

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


感谢您浏览这些命令的细节。
txyoji

我是否可以--connlimit-mask仅阻止该特定IP地址而不是整个范围?
模拟

--connlimit-mask 32 单个地址限制。即,它就像一个/ 32网络掩码。更少的东西,例如24就像一个/ 24网络掩码,忽略了低8位。
伊恩·

5

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

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

我更新了您的答案,希望它仍然可以(为什么需要“ --syn”?)。+“每秒最大连接数(端口80,tcp)到150”又如何呢?谢谢!
evachristine

--syn表示该规则仅查看带有syn标志的TCP数据包-表示新连接。您可以使用-m state --state NEW进行大致相同的操作,但这可能会更快。
Dan Pritts 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.