如何使用 UFW 限制某个端口的同时连接数?

如何使用 UFW 限制某个端口的同时连接数?

我看到许多关于暴力攻击、每 N 秒的连接数的文章,但我的情况不同,我有一个代理服务器,我只想将来自任何地方的连接限制为 1 个...再次,不是来自同一 IP,而是来自任何地方...我尝试使用 ufw 限制,但那是针对来自同一 IP 地址的连接,我只想要这样,如果有人当前连接到端口 3128,那么在当前连接完成之前,没有其他人可以连接。

答案1

UFW 正在使用iptables作为后端。 UFW 的限制规则基于 iptables'最近的match 不适合 OP 的用例。相关功能应该是连接限制匹配(并且对于nftablesCT计数表达)。

connlimit

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

遗憾的是,该功能并非由 UFW 直接提供,UFW 称为简单防火墙是有原因的。相反,为了提供缺失的功能,UFW 提供 加载任何自定义 iptables 规则来自文件(只要它不在user.rules/中user6.rules)。所以这个答案实际上是一个iptables答案隐藏在 UFW 答案中。

独立iptables限制 TCP 端口 3128 上的并发连接数为 1 的规则可以这样写:

iptables -A INPUT -p tcp --dport 3128 -m conntrack --ctstate NEW -m connlimit --connlimit-upto 1 --connlimit-mask 0 --connlimit-saddr -j ACCEPT

-m conntrack --ctstate NEW仅验证新连接,--connlimit-mask 0 --connlimit-saddr将匹配任何源地址,并且--connlimit-upto 1只允许一个连接跟踪符合条件的条目,结果才为真。

应将此规则放入iptables-save格式为 (仅表示没有前导iptables命令)的专用自定义链中,该ufw-after-input链在 中定义/etc/ufw/after.rules。因此它将使用-A ufw-after-input而不是-A INPUT

的结尾/etc/ufw/after.rules现在应该是这样的(至少对于 UFW 0.36 来说):

# don't log noisy broadcast
-A ufw-after-input -m addrtype --dst-type BROADCAST -j ufw-skip-to-policy-input

# allow only one established connection to port 3128
-A ufw-after-input -p tcp --dport 3128 -m conntrack --ctstate NEW -m connlimit --connlimit-upto 1 --connlimit-mask 0 --connlimit-saddr -j ACCEPT

# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT

并重新加载防火墙规则:

ufw reload

笔记:

  • 本地连接不会受到影响,并且由于多种原因,该规则无法在本地连接下正常工作。必须从远程验证此规则。

  • -A ufw6-after-inputIPv6:可以以相同的方式在 中插入相同的条目(这次以 开始) /etc/ufw/after6.rules。请注意iptablesip6tables不会将两个计数合并在一起:这将允许一个 IPv4 连接加一个 IPv6 连接。

  • 虽然示例中经常使用--syn,但如果需要,可以使用而不是-m conntrack --ctstate NEW将 TCP 协议替换为 UDP 。-p udp-p tcp

  • 单个允许客户端的异常断开连接(例如:连接丢失)可能会导致套接字处于 FIN_WAIT 状态,并会导致延迟才能再次使用。此外,使用代理的浏览器可能会尝试通过它同时进行多个连接。仅允许一个连接可能会破坏浏览器的默认行为否定/降低规则。允许多个同时连接,使用反向iptables应该考虑以-j REJECT或政策结尾的规则。ufw default reject incoming

相关内容