我正在尝试找到一种方法来限制可以连接到某个端口的 IP 数量。这是一个简单的示例,返回连接到端口的唯一 IP 的数量
netstat -ntu | grep :80 | grep -v LISTEN | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | grep -v 127.0.0.1 | wc -l
或者当上面的代码满足条件时,具有一个条件的脚本可以拒绝来自新 IP 的连接。
或者也许可以用 iptables 来完成
我也看到了这段代码
iptables -A INPUT -p tcp --syn -dport 80 -m iplimit --iplimit-above 10 -J REJECT
但我没有找到 iplimit 或 --iplimit-above 的任何文档
答案1
之中iptables扩展, 这connlimit
匹配可以做到这一点:
connlimit
允许您限制每个客户端 IP 地址(或客户端地址块)到服务器的并行连接数。
它是最初被称为iplimit
但已更名(2003 年!)connlimit
:
将 iplimit 重命名为 connlimit
它依赖于连线跟踪正在进行的已建立连接的当前状态的子系统,因此此匹配也可以在过滤器/转发中的路由器(包括托管容器或虚拟机的系统)中使用,而不仅仅是在过滤器/输入中的端节点上使用。
你的例子将转化为:
iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 10 -j REJECT
默认情况下对每个源地址应用限制:
--connlimit-mask
前缀长度[...] 如果未指定,则使用适用协议的最大前缀长度。
对于 IPv4 意味着 /32,对于 IPv6 意味着 /128
--connlimit-saddr
[...]这是默认的[...]
对于全局限制,--connlimit-mask 0
可以使用附加选项:
iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 10 --connlimit-mask 0 -j REJECT
由于 OP 的初始命令排除了 127.0.0.1,因此应在之前插入一个异常,以便这些连接不会在下一个规则中被考虑,以获得最终(非优化)结果:
iptables -A INPUT -p tcp --syn --dport 80 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 10 --connlimit-mask 0 -j REJECT
人们可以立即替换-s 127.0.0.1
甚至-i lo
拥有先前的规则,允许所有-i lo
这些都是常见的等等。
该-p tcp --syn --dport 80
块大致相当于-p tcp --dport 80 -m conntrack --ctstate new
.--ctstate new
一旦考虑默认超时,可用于其他面向数据报的协议(UDP、ICMP ...)。例如,要限制同时应答两个(全局)正在进行的 ping(ICMP 回显请求):
iptables -I INPUT -p icmp --icmp-type echo-request -m conntrack --ctstate NEW -m connlimit --connlimit-above 2 --connlimit-mask 0 -j DROP
注:如连线的条目使用 ICMP 在 30 秒时超时,“槽”将需要 30 秒才能再次可用,并允许新命令在之前两个允许的命令之一结束ping
后获得答复。ping