![特定端口范围的路由流量](https://linux22.com/image/766475/%E7%89%B9%E5%AE%9A%E7%AB%AF%E5%8F%A3%E8%8C%83%E5%9B%B4%E7%9A%84%E8%B7%AF%E7%94%B1%E6%B5%81%E9%87%8F.png)
我有一台 Ubiquiti Dream Machine (UDM),它是用不同的网络拓扑替换网络拓扑的项目的一部分。这涉及互联网流量和 VoIP (Asterisk)。在分阶段引入新拓扑期间,由于我们在配置 Asterisk 服务器时受到限制,我有以下要求:
在 UDM 上,我需要将10.0.0.1
端口中指向的所有 UDP 流量重新路由50000-55000
到10.0.10.1
接口上br8
我怀疑这是否可以从 UI 实现,但我可以通过 SSH 访问 UDM,在那里我可以修饰iptables
和ip route
配置。
在UDM上,路由表如下:
# ip route
10.0.0.0/24 dev br3 proto kernel scope link src 10.0.0.1
10.0.1.0/24 dev br5 proto kernel scope link src 10.0.1.1
10.0.2.0/24 dev br6 proto kernel scope link src 10.0.2.1
10.0.3.0/24 dev br4 proto kernel scope link src 10.0.3.1
10.0.10.0/24 dev br8 proto kernel scope link src 10.0.10.1
10.1.1.0/24 dev br0 proto kernel scope link src 10.1.1.1
10.2.2.0/24 dev br2 proto kernel scope link src 10.2.2.1
192.168.1.0/24 dev eth4 proto kernel scope link src 192.168.1.86
关于拓扑的重要说明:10.0.10.0/24 网络是连接新旧拓扑之间的 VoIP 流量的桥接网络,那里的旧 VoIP 服务器具有以下路由表:
# ip route
192.168.1.248/29 dev eth1 proto kernel scope link src 192.168.1.250
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.1
10.0.1.0/24 dev eth3 proto kernel scope link src 10.0.1.1
10.0.10.0/24 dev eth2 proto kernel scope link src 10.0.10.10
10.0.0.0/8 via 10.0.10.1 dev eth2
default via 192.168.1.254 dev eth1
一些网络看似存在冲突,但实际上它们之间并没有相互交流。这两个服务器之间唯一的通信是连接到旧服务器的br8
UDM 上的VLAN,仅用于 VoIP 流量。eth2
路由工作正常,正如我所料。VoIP 正在通过 的服务器10.0.10.10
,旧世界和新世界都可以看到。当我拨打 VoIP 电话时,SIP 协商正确进行,这意味着每部电话都可以看到服务器并双向通话。
我唯一的问题是,当 RTP 语音流量开始流动时,其中一部电话有时(取决于哪一方发起呼叫)会将其发送到旧的 VoIP 服务器地址(原为 10.0.0.1),而不是新的地址 10.0.10.10。尽管重新配置为使用新地址,尽管刚刚使用新地址进行了 SIP 协商,但这种情况仍然会发生!这是星号配置问题,它在 SIP 邀请中发送了错误的地址,欺骗了电话。Asterisk 服务器认为它们都一样,因为它自己的身份是 10.0.0.1 和 10.0.10.10,但这只在旧世界中是正确的,在新世界中则不是……
因此,在单向音频通话期间,我在 UDM 上看到这种流量:
# tcpdump -q -n -c 20 -i any host 10.0.10.10 or host 10.0.2.1833 or host 10.0.10.47
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
12:20:55.545461 IP 10.0.10.47.5032 > 10.0.0.1.50042: UDP, length 172
12:20:55.545461 IP 10.0.10.47.5032 > 10.0.0.1.50042: UDP, length 172
12:20:55.545461 IP 10.0.10.47.5032 > 10.0.0.1.50042: UDP, length 172
12:20:55.565464 IP 10.0.10.47.5032 > 10.0.0.1.50042: UDP, length 172
12:20:55.565464 IP 10.0.10.47.5032 > 10.0.0.1.50042: UDP, length 172
12:20:55.565464 IP 10.0.10.47.5032 > 10.0.0.1.50042: UDP, length 172
12:20:55.570260 IP 10.0.2.183.50030 > 10.0.10.10.54736: UDP, length 172
12:20:55.570260 IP 10.0.2.183.50030 > 10.0.10.10.54736: UDP, length 172
12:20:55.570313 IP 10.0.2.183.50030 > 10.0.10.10.54736: UDP, length 172
12:20:55.570317 IP 10.0.2.183.50030 > 10.0.10.10.54736: UDP, length 172
12:20:55.570764 IP 10.0.2.183.50030 > 10.0.10.10.54736: UDP, length 172
12:20:55.570764 IP 10.0.2.183.50030 > 10.0.10.10.54736: UDP, length 172
12:20:55.570807 IP 10.0.2.183.50030 > 10.0.10.10.54736: UDP, length 172
12:20:55.570810 IP 10.0.2.183.50030 > 10.0.10.10.54736: UDP, length 172
12:20:55.571077 IP 10.0.2.183.50030 > 10.0.10.10.54736: UDP, length 172
12:20:55.571077 IP 10.0.2.183.50030 > 10.0.10.10.54736: UDP, length 172
12:20:55.571109 IP 10.0.2.183.50030 > 10.0.10.10.54736: UDP, length 172
12:20:55.571111 IP 10.0.2.183.50030 > 10.0.10.10.54736: UDP, length 172
12:20:55.585465 IP 10.0.10.47.5032 > 10.0.0.1.50042: UDP, length 172
12:20:55.585465 IP 10.0.10.47.5032 > 10.0.0.1.50042: UDP, length 172
去往 10.0.10.10 的流量没有问题,去往 10.0.0.1 的流量有问题。我想重定向它,但我需要你的帮助。
(我知道可以,或者甚至应该尝试通过某种方式修复 Asterisk 服务器配置来解决问题,但这样做存在局限性,而且我只需要重新路由解决方案。询问重新路由是我在此提问的唯一目的)。
当前UDM 上的 iptables 配置这是:
# iptables-save
# Generated by iptables-save v1.6.1 on Thu May 13 12:28:34 2021
*nat
:PREROUTING ACCEPT [149794:35652606]
:INPUT ACCEPT [59043:3818189]
:OUTPUT ACCEPT [205240:13204474]
:POSTROUTING ACCEPT [179113:10974505]
:UBIOS_INPUT_JUMP - [0:0]
:UBIOS_OUTPUT_JUMP - [0:0]
:UBIOS_POSTROUTING_JUMP - [0:0]
:UBIOS_POSTROUTING_USER_HOOK - [0:0]
:UBIOS_PREROUTING_JUMP - [0:0]
-A PREROUTING -j UBIOS_PREROUTING_JUMP
-A INPUT -j UBIOS_INPUT_JUMP
-A OUTPUT -j UBIOS_OUTPUT_JUMP
-A POSTROUTING -j UBIOS_POSTROUTING_JUMP
-A UBIOS_POSTROUTING_JUMP -j UBIOS_POSTROUTING_USER_HOOK
-A UBIOS_POSTROUTING_USER_HOOK -o eth4 -m comment --comment 00000001095216660481 -j MASQUERADE
COMMIT
# Completed on Thu May 13 12:28:34 2021
# Generated by iptables-save v1.6.1 on Thu May 13 12:28:34 2021
*mangle
:PREROUTING ACCEPT [21051971:19450922056]
:INPUT ACCEPT [11815594:10852127372]
:FORWARD ACCEPT [9222781:8597163389]
:OUTPUT ACCEPT [11762182:10802741148]
:POSTROUTING ACCEPT [21125153:19406413016]
COMMIT
# Completed on Thu May 13 12:28:34 2021
# Generated by iptables-save v1.6.1 on Thu May 13 12:28:34 2021
*filter
:INPUT ACCEPT [11703464:10819984868]
:FORWARD ACCEPT [9222781:8597163389]
:OUTPUT ACCEPT [11762124:10802734194]
:UBIOS_FORWARD_IN_USER - [0:0]
:UBIOS_FORWARD_JUMP - [0:0]
:UBIOS_FORWARD_OUT_USER - [0:0]
:UBIOS_FORWARD_USER_HOOK - [0:0]
:UBIOS_INPUT_JUMP - [0:0]
:UBIOS_INPUT_USER_HOOK - [0:0]
:UBIOS_IN_GEOIP - [0:0]
:UBIOS_LAN_IN_USER - [0:0]
:UBIOS_LAN_LOCAL_USER - [0:0]
:UBIOS_LAN_OUT_USER - [0:0]
:UBIOS_OUTPUT_JUMP - [0:0]
:UBIOS_OUTPUT_USER_HOOK - [0:0]
:UBIOS_OUT_GEOIP - [0:0]
:UBIOS_WAN_IN_USER - [0:0]
:UBIOS_WAN_LOCAL_USER - [0:0]
:UBIOS_WAN_OUT_USER - [0:0]
-A INPUT -j UBIOS_INPUT_JUMP
-A FORWARD -j UBIOS_FORWARD_JUMP
-A OUTPUT -j UBIOS_OUTPUT_JUMP
-A UBIOS_FORWARD_IN_USER -i eth4 -m comment --comment 00000001095216663481 -j UBIOS_WAN_IN_USER
-A UBIOS_FORWARD_IN_USER -i br0 -m comment --comment 00000001095216663482 -j UBIOS_LAN_IN_USER
-A UBIOS_FORWARD_IN_USER -i br2 -m comment --comment 00000001095216663483 -j UBIOS_LAN_IN_USER
-A UBIOS_FORWARD_IN_USER -i br3 -m comment --comment 00000001095216663484 -j UBIOS_LAN_IN_USER
-A UBIOS_FORWARD_IN_USER -i br4 -m comment --comment 00000001095216663485 -j UBIOS_LAN_IN_USER
-A UBIOS_FORWARD_IN_USER -i br5 -m comment --comment 00000001095216663486 -j UBIOS_LAN_IN_USER
-A UBIOS_FORWARD_IN_USER -i br6 -m comment --comment 00000001095216663487 -j UBIOS_LAN_IN_USER
-A UBIOS_FORWARD_IN_USER -i br8 -m comment --comment 00000001095216663488 -j UBIOS_LAN_IN_USER
-A UBIOS_FORWARD_JUMP -j UBIOS_FORWARD_USER_HOOK
-A UBIOS_FORWARD_OUT_USER -o eth4 -m comment --comment 00000001095216663481 -j UBIOS_WAN_OUT_USER
-A UBIOS_FORWARD_OUT_USER -o br0 -m comment --comment 00000001095216663482 -j UBIOS_LAN_OUT_USER
-A UBIOS_FORWARD_OUT_USER -o br2 -m comment --comment 00000001095216663483 -j UBIOS_LAN_OUT_USER
-A UBIOS_FORWARD_OUT_USER -o br3 -m comment --comment 00000001095216663484 -j UBIOS_LAN_OUT_USER
-A UBIOS_FORWARD_OUT_USER -o br4 -m comment --comment 00000001095216663485 -j UBIOS_LAN_OUT_USER
-A UBIOS_FORWARD_OUT_USER -o br5 -m comment --comment 00000001095216663486 -j UBIOS_LAN_OUT_USER
-A UBIOS_FORWARD_OUT_USER -o br6 -m comment --comment 00000001095216663487 -j UBIOS_LAN_OUT_USER
-A UBIOS_FORWARD_OUT_USER -o br8 -m comment --comment 00000001095216663488 -j UBIOS_LAN_OUT_USER
-A UBIOS_FORWARD_USER_HOOK -m comment --comment 00000001095216663481 -j UBIOS_FORWARD_IN_USER
-A UBIOS_FORWARD_USER_HOOK -m comment --comment 00000001095216663482 -j UBIOS_FORWARD_OUT_USER
-A UBIOS_INPUT_JUMP -j UBIOS_INPUT_USER_HOOK
-A UBIOS_INPUT_USER_HOOK -i eth4 -m comment --comment 00000001095216663481 -j UBIOS_WAN_LOCAL_USER
-A UBIOS_INPUT_USER_HOOK -i br0 -m comment --comment 00000001095216663482 -j UBIOS_LAN_LOCAL_USER
-A UBIOS_INPUT_USER_HOOK -i br2 -m comment --comment 00000001095216663483 -j UBIOS_LAN_LOCAL_USER
-A UBIOS_INPUT_USER_HOOK -i br3 -m comment --comment 00000001095216663484 -j UBIOS_LAN_LOCAL_USER
-A UBIOS_INPUT_USER_HOOK -i br4 -m comment --comment 00000001095216663485 -j UBIOS_LAN_LOCAL_USER
-A UBIOS_INPUT_USER_HOOK -i br5 -m comment --comment 00000001095216663486 -j UBIOS_LAN_LOCAL_USER
-A UBIOS_INPUT_USER_HOOK -i br6 -m comment --comment 00000001095216663487 -j UBIOS_LAN_LOCAL_USER
-A UBIOS_INPUT_USER_HOOK -i br8 -m comment --comment 00000001095216663488 -j UBIOS_LAN_LOCAL_USER
-A UBIOS_LAN_IN_USER -d 10.0.10.10/32 -j LOG
-A UBIOS_LAN_IN_USER -d 10.0.10.10/32 -m comment --comment 00000001095216662480 -j RETURN
-A UBIOS_LAN_IN_USER -s 10.0.10.10/32 -j LOG
-A UBIOS_LAN_IN_USER -s 10.0.10.10/32 -m comment --comment 00000001095216662481 -j RETURN
-A UBIOS_LAN_IN_USER -s 10.0.2.0/24 -m comment --comment 00000001095216666481 -j RETURN
-A UBIOS_LAN_IN_USER -s 10.0.3.0/24 -m comment --comment 00000001095216666482 -j RETURN
-A UBIOS_LAN_IN_USER -s 10.0.1.0/24 -m comment --comment 00000001095216666483 -j RETURN
-A UBIOS_LAN_IN_USER -s 10.2.2.0/24 -m comment --comment 00000001095216666484 -j RETURN
-A UBIOS_LAN_IN_USER -s 10.0.10.0/24 -m comment --comment 00000001095216666485 -j RETURN
-A UBIOS_LAN_IN_USER -s 10.1.1.0/24 -m comment --comment 00000001095216666486 -j RETURN
-A UBIOS_LAN_IN_USER -s 10.0.0.0/24 -m comment --comment 00000001095216666487 -j RETURN
-A UBIOS_LAN_IN_USER -j LOG
-A UBIOS_LAN_IN_USER -m comment --comment 00000001097364144127 -j RETURN
-A UBIOS_LAN_LOCAL_USER -j LOG
-A UBIOS_LAN_LOCAL_USER -m comment --comment 00000001097364144127 -j RETURN
-A UBIOS_LAN_OUT_USER -d 10.0.2.0/24 -m comment --comment 00000001095216666481 -j RETURN
-A UBIOS_LAN_OUT_USER -d 10.0.3.0/24 -m comment --comment 00000001095216666482 -j RETURN
-A UBIOS_LAN_OUT_USER -d 10.0.1.0/24 -m comment --comment 00000001095216666483 -j RETURN
-A UBIOS_LAN_OUT_USER -d 10.2.2.0/24 -m comment --comment 00000001095216666484 -j RETURN
-A UBIOS_LAN_OUT_USER -d 10.0.10.0/24 -m comment --comment 00000001095216666485 -j RETURN
-A UBIOS_LAN_OUT_USER -d 10.1.1.0/24 -m comment --comment 00000001095216666486 -j RETURN
-A UBIOS_LAN_OUT_USER -d 10.0.0.0/24 -m comment --comment 00000001095216666487 -j RETURN
-A UBIOS_LAN_OUT_USER -j LOG
-A UBIOS_LAN_OUT_USER -m comment --comment 00000001097364144127 -j RETURN
-A UBIOS_WAN_IN_USER -m conntrack --ctstate RELATED,ESTABLISHED -m comment --comment 00000001095216663481 -j RETURN
-A UBIOS_WAN_IN_USER -m conntrack --ctstate INVALID -m comment --comment 00000001095216663482 -j DROP
-A UBIOS_WAN_IN_USER -m comment --comment 00000001097364144127 -j DROP
-A UBIOS_WAN_LOCAL_USER -m conntrack --ctstate RELATED,ESTABLISHED -m comment --comment 00000001095216663481 -j RETURN
-A UBIOS_WAN_LOCAL_USER -m conntrack --ctstate INVALID -m comment --comment 00000001095216663482 -j DROP
-A UBIOS_WAN_LOCAL_USER -m comment --comment 00000001097364144127 -j DROP
-A UBIOS_WAN_OUT_USER -m comment --comment 00000001097364144127 -j RETURN
COMMIT
我在网上读到了关于通过以下方式实现我的目的的可能性:
- 在 iptables 中标记要路由的数据包(使用 mangle)
- 对这些数据包使用第二个路由表(添加到 /etc/iproute2/rt_tables)
- 调整桌子,把东西送到需要去的地方
虽然我理解总体思路,但我不是网络专家,我对这些概念很陌生,对细节很困惑。我不确定如何标记,以及主路由表有多少需要在第二个表中重复。如果能得到有关这些命令和配置的具体帮助,我将不胜感激。提前致谢!
所以,如何将10.0.0.1
端口中指向的 UDM 上的所有 UDP 流量重新路由50000-55000
到接口上的 10.0.10.1br8
?
答案1
这是“基于策略的路由”的任务基于策略的路由允许您配置复杂的路由方案。例如,您可以根据各种标准(如源地址、数据包元数据和包括协议)路由数据包。
我不确定是否可以在 UDM 上完成 - 但这里是 USG 的链接:
https://help.ui.com/hc/en-us/articles/360005460813-UniFi-USG-Advanced-Policy-Based-Routing-
答案2
我终于让它工作了,所以我将回答我自己的问题。以终端命令序列描述的解决方案不是永久性的,它不会在重启或升级后继续存在,但我想从教学角度关注路由解决方案(这是我的问题标题),并将永久性问题留给最后的脚本(更简要地解释,因为互联网上有其他地方可以帮助解决那问题)。
您是否应该像我一样使用此解决方案?可能不会。有一些“注意事项”,请参阅问题中的一些评论。我将尝试解释如何进行路由技巧,但我不一定推荐它用于其他情况...
创建新的路由表:
echo "74 myroutes" >> /etc/iproute2/rt_tables
检查
cat /etc/iproute2/rt_tables
将默认路由添加到新的路由表:
ip route add default via 10.0.10.10 dev br8 table myroutes
检查
ip route list table myroutes
请注意,我可以保持这个非常简单,因为只有少数非常特定的数据包会经过这里(仅到特定主机,通过特定端口)。因此,使用此表的内容可以全部朝着同一个方向前进,因为它已经通过iptables
标记彻底“预先选择”,见下文。
标记选定的数据包iptables
iptables -t mangle -I PREROUTING -p udp -m udp --dport 50000:55000 -d 10.0.0.1 -j MARK --set-mark 0x74
通过添加日志行来检查您的标准:
iptables -t mangle -I PREROUTING -p udp -m udp --dport 50000:55000 -d 10.0.0.1 -j LOG --log-prefix "I just marked a packet: "
(请记住随后删除该行。要删除iptables
mangle 规则,我先删除
iptables -L -t mangle -n -v --line-numbers
它,然后使用规则编号执行类似操作
iptables -t mangle -D PREROUTING 2
)
在继续之前请确保预期的数据包得到正确标记!
用于ip rule
告诉内核使用新的路由表来处理这些标记的数据包
因此我从这些规则开始:
# ip rule list
0: from all lookup local
32000: from all lookup main
32500: from 192.168.1.86 lookup 201
32766: from all lookup 201
32767: from all lookup default
我需要插入我的规则在第一个之前,这使得它比仅仅添加一条新规则要复杂一些(感谢@AB 对此的帮助使“ip 规则”的优先级高于“本地”)。
一句话警告,不要通过弄乱规则将自己锁定在服务器之外local
,这会破坏您与 UDM 之间的所有网络连接。而网络连接是进入 UDM 的唯一途径 :-)... 因此命令以下命令很重要,只有local
在新的“首选项”位置添加相同规则后才能进行删除:
ip rule add pref 10 lookup local
ip rule add pref 5 fwmark 0x74 lookup myroutes
ip rule delete pref 0
那么让我们检查一下现在有什么:
# ip rule list
5: from all fwmark 0x74 lookup myroutes
10: from all lookup local
32000: from all lookup main
32500: from 192.168.1.86 lookup 201
32766: from all lookup 201
32767: from all lookup default
通过对比这两个命令的结果来检查:
# ip route get 10.0.0.1
local 10.0.0.1 dev lo src 10.0.0.1
cache <local>
# ip route get 10.0.0.1 mark 0x74
10.0.0.1 via 10.0.10.10 dev br8 src 10.0.10.1 mark 0x74
cache
就是这样!尽管 Asterisk 服务器的配置存在错误,但现在一切都正常并且 RTP 流量再次流向正确的位置。
重启和升级后使更改永久生效
简要地讲一下(这不是这个问题的重点),如何在 Ubiquiti UDM 上永久保留这些更改。您必须先安装udm 实用程序并使用如下名称保存脚本
/mnt/data/on_boot.d/10-add-myroutes.sh
并使用 使其可执行chmod 700
。它将作为 运行root
。
下面的脚本在启动时执行上述命令。在需要时,有一些技巧可以确保它可以多次运行而不会创建重复的条目。
#!/bin/sh
# fail-safe mechanism in case our boot script is causing broken networking
# and we need to reboot and rescue by killing script before it runs:
sleep 180
grep -qxF '74 myroutes' /etc/iproute2/rt_tables || echo "74 myroutes" >> /etc/iproute2/rt_tables
ip route add default via 10.0.10.10 dev br8 table myroutes
iptables -t mangle -C PREROUTING -p udp -m udp --dport 50000:55000 -d 10.0.0.1 -j MARK --set-mark 0x74 || iptables -t mangle -I PREROUTING -p udp -m udp --dport 50000:55000 -d 10.0.0.1 -j MARK
ip rule list | grep $'10:\tfrom all lookup local' || ip rule add pref 10 lookup local
ip rule list | grep $'5:\tfrom all fwmark 0x74 lookup myroutes' || ip rule add pref 5 fwmark 0x74 lookup myroutes
# the following logic is a bit different: for safety, we want to ensure the delete only happens when the other "local" line is there
ip rule list | grep $'10:\tfrom all lookup local' && ip rule delete pref 0
如果进行更改,请特别小心,ip rule delete pref 0
因为没有本地规则,您可能会失去对设备的访问权限。如果发生这种情况,请重新启动,在脚本处于开始时的 3 分钟休眠状态时快速重新登录,然后将其终止(出于自卫!)。