在 的联机帮助页中iptables-extensions
,给出了一个示例,展示了如何阻止来自尝试在端口 139 上连接的 IP 地址的所有流量:
iptables -A FORWARD -m recent --name badguy --rcheck --seconds 60 -j DROP
iptables -A FORWARD -p tcp -i eth0 --dport 139 -m recent --name badguy --set -j DROP
我正在尝试修改此设置,以便如果有人在端口 22 上连接过于频繁,他们也会在一段时间内被完全阻止(所有流量),但允许一些初始连接。然而,我不想阻止任何现有的活动连接,只是阻止新连接。
我已经尝试过这个:
iptables -A INPUT -i eno3 -m state --state NEW -m recent --rcheck --seconds 300 --reap --hitcount 3 --name sshthrottle -j DROP
iptables -A INPUT -i eno3 -m state --state NEW -m recent --set --name sshthrottle -p tcp --dport 22
但是现在发生的情况是传入连接任何端口触发阻止,因此例如在端口 80 上进行三个连接后,该 IP 会被阻止 300 秒。我不希望该块在连接到任何端口时激活,而仅在连接到端口 22 时激活。
我究竟做错了什么?
(仅供参考,我知道 Google 上有一些用于限制 SSH 流量的示例,但它们都重复了线路--dport
上的规则--rcheck
,这意味着只有 SSH 流量会被阻止,而我想一旦触发就阻止与所有端口的连接。我的问题不是使用阻止 - 流量已成功阻止 - 但使用触发器,我只希望端口 22 触发阻止而不是所有端口。)
答案1
好的,弄清楚它是什么。我没有意识到命令行上参数的顺序iptables
会产生影响。
我有这个:
-m state --state NEW -m recent --set --name sshthrottle -p tcp --dport 22
其中说:
- 如果状态是 NEW
- SET(添加)到 sshthrottle IP 列表
- 然后检查是否连接到端口22
- 不执行任何操作并继续执行下一条规则
所以当然是检查它是否是端口 22后它已将该 IP 添加到列表中。
将顺序更改为这样有效:
-m state --state NEW -p tcp --dport 22 -m recent --set --name sshthrottle
这当然可以翻译为:
- 如果状态是 NEW
- TCP端口是22
- 然后 SET(添加)到 sshthrottle IP 列表
- 不执行任何操作并继续执行下一条规则
当然,关键是该--set
参数一旦遇到就会将 IP 添加到列表中,因此它应该是命令行上的最后一个参数之一,才能按预期工作。
实际上,--set
参数应该是目标(例如-j SETRECENT
),因为通常只有目标做某事,这就是为什么例如-j LOG
是目标而不是--log
参数。