分类: LINUX
2015-04-02 21:58:22
我们先来看看一条流上的两个方向的报文是怎么在Netfilter中进行NAT处理的。
在NAT网关上配置
iptables -t nat -A POSTROUTING -p udp -j SNAT --to-source 9.9.9.9
我们看根据上述配置报文在netfilter中的处理流程。
Client 发送 udp报文,报文格式如下
Sip:192.168.3.227
Dip:192.168.5.2
Sport:103
Dprot:105
进入NAT网关后,在PREROUTING HOOK点先由IP conntrack进行conntrack的建立
建立conntrack后,这时struct nf_conn还不是确认状态。报文经过路由查找后,找到出接口后,走到POSTROUTING HOOK点。
被SNAT注册的hook函数处理,在nat表中找到配置的规则,把conntrack的reply反向信息修改如下
把nf_conn的status的IPS_SRC_NAT_BIT位置1,然后把报文src ip 修改为9.9.9.9。
再由conntrack的 ipv4_confirm来确认conntrack并把该conntrack加入到conntrack hash表中。
然后根据SNAT前查到的路由信息,把报文发送出去。
回应报文,报文格式如下
Sip:192.168.5.2
Sport:105
Dip:9.9.9.9
Dport:103
到达NAT网关后,在PREROUTING HOOK点上,先由conntrack hook处理函数来更新conntrack的连接状态,并把查找到的conntrack 赋值给skb->nfct。
然后进入NAT的hook函数nf_nat_in,发现报文是reply方向的,并且skb->nfct->status是置位了IPS_SRC_NAT_BIT,就进行DNAT来进行报文的处理。
根据conntrack A的信息来把报文的dip 修改为 192.168.3.227。然后查找路由后发送出去。
以后每次两个反向的报文进入NAT网关,都会查到建立的conntrack,根据报文的方向以及conntrack中status的信息,
来决定NAT的处理方式,使用该报文反方向的信息来修改报文的IP地址,完成NAT功能。
iptables -t nat -A PREROUTING -j DNAT --to-destination 192.168.3.227
这时从server 端 发送dip为192.168.5.1 ,报文信息如下:
Sip:192.168.5.2
Sport:105
Dip:192.168.5.1
Dport:103
报文先进入PREROUTING处建立连接
建立完conntrack后,在PREROUNTING点被DNAT的hook处理函数处理,修改conntrack的信息,并置位conntrack中status中的IPS_DST_NAT_BIT位。
修改完conntrack信息后,根据conntrack的信息把报文的目的IP修改为192.168.3.227。
报文离开Netfilter 的PREROUTIN后,查找路由把报文发现给client。
Client回应server的报文:信息如下
Dip:192.168.5.2
Dport:105
Sip:192.168.3.227
Sport:103
报文进入NAT网关后,在PRERONTING出先进入conntrack的hook处理函数,更新conntrack的连接状态,并把查找到的conntrack 赋值给skb->nfct。然后从PREROUTING处离开Netfilter。查找路由后,找到对应的出接口。
进入POSTROUTING,先被nat的处理函数进行处理,根据skb->nfct的conntrack信息,根据tuple A ,修改报文的源IP地址为192.168.5.1,根据上面路由的信息把报文发送出去。
以上就是报文在Netfilter中进行NAT操作的大致流程。
(未完待续)