- 论坛徽章:
- 2
|
环境背景:
linux服务器
话机1 ------------------------
|fm1-gb0 --- fm1-gb1| ----------------------dsp
话机2 ------------------------
使用服务器隔离dsp和外部网络,话机1和话机2都处在外部网络。
话机1: 10.0.1.60
话机2: 10.0.1.50
服务器:对外网口 10.0.1.10
对内网口 192.100.1.1
dsp: 192.100.1.100
linux version: 2.6.38
现象(以话机2发送RTP为例说明):
1) 如果在话机发送第一个RTP或RTCP之前,先配置NAT规则:
iptables -t nat -A PREROUTING -d 10.0.1.10 -p udp --dport 10000 -j DNAT --to-destination 192.100.1.100:10000
iptables -t nat -A POSTROUTING -s 10.0.1.50 -p udp --sport 11780 -j SNAT --to-source 192.100.1.1:10000
则,话机2发送的RTP包可以通过NAT规则的转换,并将包发往DSP
2)如果在话机发送第一个包之后才设置NAT规则,则话机2发送的RTP包无法通过NAT规则的转换,最终死在路由的结果上,返回icmp,code = 3, type =3 (目的端口不可达)
追踪内核源码,发现如下:
当收到第一个包时,新建了链接跟踪(nf_conntrack_in),然后进入NAT表在PREROUTING链路上的操作。
在nf_nat_fn中
nf_nat_fn()
{
switch(ctinfo)
{
case IP_CT_NEW:
{
/* ct->staus 在进行了一次nat match匹配后,会调用target函数 ipt_snat_table或者ipt_dnat_table来设置
* ,并且将转换操作的规则信息nat_info转换成一个tuple,挂到ct上,后续的NAT转换就不用再查NAT规则了。
*/
if(!nf_nat_initalized()) /* 第一包会进入 */
{
nf_nat_rule_find();
}
}
}
nf_nat_packet(); /* 会调用manip_pkt()来修改ip和port */
}
nf_nat_rule_find()
{
ret = ipt_do_table();
if (NF_ACCEPT == ret)
if(!nf_initialized())
ret = alloc_null_binding();
return ret;
}
在ipt_do_table中,由于我们刚启动时,清空了nat规则表,所以查match时,是没有任何能匹配的,acpar.hotdrop == false。
这个查找应该返回NF_DROP(直接丢弃,后面的操作也不用了),并且,ct->status的SNAT和DNAT应该不会被设置啊。但是,从我在nf_nat_find中的打印来看,后续的包好像都没进入这个nf_nat_find函数,这个怎么解释呢??? |
|