单播通过iptables进行组播

注意:虽然现在有一个被接受的答案,但它只是一部分; 检查下面的最终iptables规则。

我正在一个接口上接收单播RTPstream,并希望通过第二个接口上的多播将其发送出去。 有问题的系统是一个运行Linux的embedded式处理器,但是我发现在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在一台单独的机器上显示没有数据包出来。

我看了如何翻译单播通过DNAT与iptables广播? 但似乎与广播案件的具体情况有关。

注意:没有其他iptables规则已经设置。 我使用iptables -L(和-t nat -L)和iptables –flush进行了双重检查。

(我意识到还有其他的select,比如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

这看起来似乎在某个时间点有效,但是由于在原始的embedded式主机上或在Linux工作站上,我一直无法工作。

编辑:事实certificate,这个问题再次提出。

完全工作的最终解决scheme:

获取smcroute(静态组播路由守护进程)。 如果您在embedded式系统中,则可能需要使用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规则,以确保不会捕获您不想要的数据包 – 这只是一个简单的示例。

你有内核上启用IP转发吗?

 # sysctl -a 2>&1 | grep ip_forward net.ipv4.ip_forward=1 

您需要将stream量从一个接口传递到另一个接口(即FORWARD表规则)。

编辑:

还有其他的sysctl设置,我怀疑是相关的:

 net.ipv4.conf.all.mc_forwarding 

和每个接口,以及ipv6。

这个“mc”确实听起来是多播的,但是我手头上没有内核文档是100%确定的。

尝试设置为1,如果不工作总是可以返回到默认的0。

编辑:

来自networking / ip-sysctl.txt:

conf / all / mc_forwarding也必须设置为TRUE来启用组播路由

您需要操作路由表,以便在对数据包进行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> 

在那里,一般的做法是做你想做的。 我希望我的(有限的)解释能使你走上正确的道路。

看起来,你将不得不使用特殊的守护进程 – 看看igmpproxymrouted – 因为iptables只是将传入的数据包转换并转发给给定范围内的一个地址/端口组合。

该内核模块在prerouting链中创build一个新的netfilter钩子,用于窃取单播报文,并根据“utomu”设置的规则将报文作为组播报文发送出去。

例如:入站单播会话接口为“eth0”,出站多播会话接口为“eth1”。 然后设置

echo“eth0”> / proc / sys / net / utom / in_ifname

echo“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

它将改变源端口和目标端口。

来源@ https://github.com/ravi-eticala/unicast-to-multicast