Linux实现基于Loopback的NVI(NAT Virtual Interface)
2013-10-04 13:48:57 来源:WEB开发网数据包从物理网卡进入->执行DNAT->路由到loopback->执行SNAT->loopback口发出->策略路由->物理网卡发出
可以看到,路由执行了两次,第一次是为了NAT,第二次是真正的路由。
除了使用loopback,编写一个类似veth的虚拟网卡是一个更不错的选择:
Veth stands for Virtual ETHernet. It is a simple tunnel driver that works at the link layer and looks like a pair of ethernet devices interconnected
with each other.
比loopback好的是,这基本可以不修改代码实现NVI,并且可以很容易取到数据包原始的进入接口。该驱动的逻辑非常简单,即一个pair中包含一个主接口和一个辅助接口,数据包从主接口进入被路由到该主接口的辅助接口,注意,不改变skb的接收接口,这个所谓的路由只是为了搞一次“从物理网卡接收到发送到某另一个网卡的动作”,此时PREROUTING/POSTROUTING都已经完成了,真正的路由之后就可以从另一个主接口发出了。
这次先不急着自己写虚拟网卡,先折腾完loopback再说,那么现在动手吧!
1.对代码的修改:
重新封装RAW表的NF_INET_PRE_ROUTING钩子函数,在ipt_hook的调用前调用下面的逻辑:
//判断有点太鲁莽,正常应该可以设计成一个匹配算法的 if (skb->dev->flags & IFF_LOOPBACK && skb->nfct) { skb->nfct = &nf_conntrack_untracked.ct_general; skb->nfctinfo = IP_CT_NEW; nf_conntrack_get(skb->nfct); skb_dst_drop(skb); return NF_ACCEPT; }
这段代码的意思是说,如果是数据包从物理网卡进入,显然是需要匹配和应用规则(比如NAT)的,如果这件事做完了,数据也就是要通过路由导入loopback接口了,此时就不要再使用conntrack了,然而此时skb的nfct可能已经被设置了,于是将其NOTRACK,并且将skb的路由缓存丢弃。Linux的IP路由是这么对待loopback的,如果路由查询的结果出口是loopback接口,就是直接设置dst,loopback的xmit将数据包发出,调用一个netif_rx重新接收,到达ip_rcv_finish的时候,由于已经有了dst,就不必再查询路由了。但是如果这样的话,我们的第二次路由查询-实际上是策略路由的查询将无法实现,因此必须drop掉原有的dst。
2.配置IP地址和Netfilter策略
IP地址:
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000
link/ether 00:0c:29:90:66:c5 brd ff:ff:ff:ff:ff:ff
inet 192.168.2.249/24 brd 192.168.2.255 scope global eth2
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:90:66:cf brd ff:ff:ff:ff:ff:ff
inet 192.168.40.249/24 scope global eth2
说明:暂用两块网卡,eth1连接内部,eth2连接外部
NAT表:
-A POSTROUTING -j SNAT -i eth1 --to-source 192.168.40.249
说明:将所有的发起于内部的数据包源IP都转换成本机的IP地址。
RAW表:
-A PREROUTING -i lo -j MARK --set-xmark 100
说明:从lo口进入,说明第一次路由查询导致的NAT已经完成,打上MARK让后续的路由逻辑将其识别为第二次真正的路由查询。
策略:
0: from all lookup local
- ››Linux实现基于Loopback的NVI(NAT Virtual Interfa...
- ››Linux远程访问windows时,出现"连接被对端重...
- ››linux中使用head命令和tail命令查看文件中的指定行...
- ››linux swap 分区调控(swap分区 lvm管理)
- ››Linux脚本中用户自定义终止符-EOF
- ››Linux测量kernel子模块加载时间的方法
- ››Linux内核Oracle相关参数信息
- ››linux下用tar命令将当前目录下文件按子目录压缩归...
- ››linux下如何做ghost
- ››linux中多线程解析
- ››linux下用cron定时执行任务的方法
- ››Linux进程阻塞的相关知识
更多精彩
赞助商链接