笔记:虽然现在有一个可以接受的答案,但这只是部分;请检查下面的最终 iptables 规则。
我在一个接口上接收单播 RTP 流,并希望通过第二个接口上的多播将其发送出去。所讨论的系统是运行 Linux 的嵌入式处理器,但我发现在我的 Ubuntu 10.10 主机上设置它同样困难。简单而明显的答案是基于http://lists.netfilter.org/pipermail/netfilter/2002-October/038890.html和其他来源,似乎是:
iptables -t nat -A PREROUTING -i [unicast-interface] -p udp --dport [unicast-incoming-port] -j DNAT --to-destination [multicast-addr]:[multicast-port]
经过一些额外的研究,我们得到了这样的配对:
iptables -t nat -A PREROUTING -i [unicast-interface] -p udp --dport [unicast-incoming-port] -j DNAT --to-destination [multicast-addr]:[multicast-port]
iptables -A FORWARD -i [unicast-interface] -o [multicast-interface] -p udp --dport [unicast-incoming-port] -j ACCEPT
虽然列出时规则会出现,并且 tcpdump 会显示单播数据包进入,但另一台机器上的 Wireshark 不会显示任何数据包出来。
我在看如何使用 iptables 通过 DNAT 将单播转换为广播?但这似乎与广播案件的具体情况有关。
注意:没有设置其他 iptables 规则。我已使用 iptables -L(和 -t nat -L)和 iptables --flush 进行了双重检查。
(我意识到还有其他选择,比如socat
——但在切换到它们之前,我想确保我没有遗漏任何东西。)
编辑:我确实已启用 ip_forward。
~ # sysctl -a 2>&1 |grep ip_forward
net.ipv4.ip_forward = 1
编辑:看起来我的 NAT 表中的数据包数量在增加(iptables -t nat -L -v -n
),但主/过滤表中的数据包数量却没有增加(iptables -L -v -n
)
编辑:我尝试了很多方法,但都没有成功。我看到一些人通过类似的流程与思科合作,例如在这个网站上:http://www.penrod.cc/?p=527
这似乎确实有效某一时间点但从那时起,无论是在原始嵌入式主机上还是在 Linux 工作站上,我都无法让它工作。
编辑:事实证明,这个问题再次出现了。
最终完整有效的解决方案:
获取 smcroute(正在运行的静态多播路由守护程序)。如果你在嵌入式系统中,你可能需要使用smcroute -d
smcroute -a [unicast-interface] [source-ip] [multicast-addr] [multicast-interface]
iptables -t nat -A PREROUTING -p UDP -d [unicast-interface-ip] -j NETMAP --to [multicast-addr]
例如:
smcroute -a eth0 192.168.0.101 239.1.1.1 eth0
iptables -t nat -A PREROUTING -p UDP -d 192.168.0.1 -j NETMAP --to 239.1.1.1
请注意,您可能需要优化 iptables 规则以确保您不会捕获您不想要的数据包——这只是一个简化的示例。
答案1
内核中启用了 ip forward 吗?
# sysctl -a 2>&1 | grep ip_forward
net.ipv4.ip_forward=1
您需要它将流量从一个接口传递到另一个接口(又名FORWARD表规则)。
编辑:
我怀疑还有其他 sysctl 设置与之相关:
net.ipv4.conf.all.mc_forwarding
以及每个接口,以及 IPv6。
那个“mc”听起来确实像是多播,但我手头没有内核文档可以 100% 确定。
尝试设置为 1,如果不奏效,您可以返回默认值 0。
编辑:
来自networking/ip-sysctl.txt:
conf/all/mc_forwarding 还必须设置为 TRUE 才能启用多播路由
答案2
您需要操作路由表,以便在对数据包进行 NAT 后,将其发送出正确的接口。
ip route add to $MULTICAST_ADDR dev $MULTICAST_IFACE
如果你通过传入接口发送多播,这可能会引起问题,因此我们必须标记数据包
iptables -t mangle <rules to match the packets you want to multicast> -j MARK --mark <your favorite number>
ip rule add order 10 fwmark <that favorite number> lookup table <another favorite number>
ip route add to <multicast> dev <iface> table <2nd fav number>
最后,您必须意识到 conntrack 将无法匹配返回数据包;您必须执行自己的 conntrack:
iptables -t nat -A POSTROUTING -d <multicast> -o <iface> -j SNAT <router's IP>:<a port>
iptables -t nat -A PREROUTING -i <router's IP> -p udp --dport <a port> -j DNAT <orig sender>:<orig port>
以上就是完成你想要做的事情的一般方法。我希望我的(有限的)解释能让你走上正确的道路。
答案3
看来你必须使用特殊的守护进程 - 看看igmpproxy
或mrouted
- 因为 iptables 将简单地转换并转发传入的数据包到一给定范围内的地址/端口组合。
答案4
该内核模块在预路由链中创建一个新的 netfilter 钩子,用于窃取单播数据包,并根据“utomu”设置的规则将其作为多播数据包发送出去
例如:传入单播会话接口为“eth0”,传出多播会话接口为“eth1”。然后设置
回显“eth0”> /proc/sys/net/utom/in_ifname
回显“eth1”> /proc/sys/net/utom/out_ifname
假设单播源 ip 为“192.168.56.5”,想将其转换为多播“225.1.2.3”,则将规则设置为
utomu-m 225.1.2.3-a 192.168.56.5-s 1194-d 1194
它也将改变源端口和目标端口。