![IPTables 限制高“每秒调用”并重定向到另一个程序(同一台机器)](https://linux22.com/image/190634/IPTables%20%E9%99%90%E5%88%B6%E9%AB%98%E2%80%9C%E6%AF%8F%E7%A7%92%E8%B0%83%E7%94%A8%E2%80%9D%E5%B9%B6%E9%87%8D%E5%AE%9A%E5%90%91%E5%88%B0%E5%8F%A6%E4%B8%80%E4%B8%AA%E7%A8%8B%E5%BA%8F%EF%BC%88%E5%90%8C%E4%B8%80%E5%8F%B0%E6%9C%BA%E5%99%A8%EF%BC%89.png)
我正在寻找一种方法来“控制”我的 VoIP 服务器中到达端口 5060 的 iptables 级别的每秒大量 SIP VoIP INVITE (UDP)(每秒呼叫)。
我需要做的是限制每秒 INVITE 的数量以一定的速率(例如20 cps),如果我收到大量的CPS到服务器,我需要将它们重定向到另一个程序正在运行的同一台机器上的另一个端口(例如UDP/5090),以回答向他们发送 SIP 消息“603 Decline”。这可能吗?
到目前为止,我对类似问题的很多答案感到有点迷失......我需要使用 --limit?,connlimit?,hitcount 吗?......
除此之外,可以通过源代码来做到这一点IP地址?
从概念上讲,我在想这样的事情......如果可能的话:
INPUT
iptables --append INPUT --match conntrack --ctstate NEW --jump RATE-LIMIT
RATE-LIMIT
iptables --append RATE-LIMIT --match limit --limit 20/sec --limit-burst 20 --jump ACCEPT
iptables --append RATE-LIMIT --jump DECLINE-INVITE
DECLINE-INVITE
iptables --append DECLINE-INVITE [how to redirect to port udp 5090]
谢谢!里卡多
答案1
首先,我们来看看Netfilter 和通用网络中的数据包流示意图:
在OP尝试操作的步骤:筛选/INPUT 做想做的事已经太晚了,做 DNAT 的机会必须在路由决定之前完成,在纳特/预路由。
所以这一定是更早的,对于其他一些情况,可能需要使用两个不同的表:碾压/PREROUTING 用于一些特殊测试,以及纳特/PREROUTING 用于端口重定向,在数据包上带有标记以传达来自端口的意图碾压表到纳特桌子。实际上这种情况会非常复杂,可能涉及到生的表并且从不使用简单的设置(这是一个例子:IPTables 重定向所有 UDP 数据包,包括 ESTABLISHED)
这里,纳特/PREROUTING 就足够了。这是因为只有数据包开始一个新的流(状态新的)检查OP的情况,这正是已经发生的情况纳特表:仅处于状态的数据包新的被看到(如原理图所示),并且所有其他数据包将遵循已完成的 NAT 决策。所以这个块:--match conntrack --ctstate NEW
在任何情况下都变得多余纳特餐桌规则:永远正确。这限制match没有限制,可以在任何表/链中使用。
到底:
- 添加 UDP 端口 5060 的过滤器以不影响其他任何内容
- 不连线这里需要匹配
- 提醒一下,
-j ACCEPT
在纳特表仅表示“在这种情况下不执行任何 NAT” - DECLINE-INVITE 并不是真正需要的,但我将保留 OP 使用的方式
- 由于与端口一起使用的 DNAT 目标需要协议,
-p udp
因此即使只有 5060/UDP 数据包符合此规则,也必须再次添加。 - 您无法轻松测试本地系统的结果:本地系统使用路径 OUTPUT -> ... Loopback ... -> PREROUTING -> INPUT。在 PREROUTING 阶段,第一个传入数据包在环回之前与 OUTPUT 中刚刚创建的流匹配,因此它不会再出现在 NEW 状态,也不会看到纳特/PREROUTING 链,并且不会在那里进行 DNAT。 DNAT 仍然可以通过在 OUTPUT 中复制(并充分调整)这些规则来立即完成纳特/输出。无论如何,我确信对于当地的情况还有其他注意事项。相反,从远程(或从连接的容器或网络命名空间)进行测试。
iptables -t nat -N RATE-LIMIT
iptables -t nat -N DECLINE-INVITE
iptables -t nat -A PREROUTING -p udp --dport 5060 -j RATE-LIMIT
iptables -t nat -A RATE-LIMIT -m limit --limit 20/sec --limit-burst 20 -j ACCEPT
iptables -t nat -A RATE-LIMIT -j DECLINE-INVITE
iptables -t nat -A DECLINE-INVITE -p udp -j DNAT --to-destination :5090