Linux ipip隧道及实现

  IP隧道技术:是路由器把一种网络层协议封装到另一个协议中以跨过网络传送到另一个路由器的处理过程。IP 隧道(IP tunneling)是将一个IP报文封装在另一个IP报文的技术,这可以使得目标为一个IP地址的数据报文能被封装和转发到另一个IP地址。IP隧道技术亦称为IP封装技术(IP encapsulation)。IP隧道主要用于移动主机和虚拟私有网络(Virtual Private Network),在其中隧道都是静态建立的,隧道一端有一个IP地址,另一端也有唯一的IP地址。移动IPv4主要有三种隧道技术,它们分别是:IP in IP、最小封装以及通用路由封装。更多信息可以参看百度百科:IP隧道隧道技术。

  Linux系统内核实现的IP隧道技术主要有三种(PPP、PPTP和L2TP等协议或软件不是基于内核模块的):ipip、gre、sit 。这三种隧道技术都需要内核模块 tunnel4.ko 的支持。

  ipip 需要内核模块 ipip.ko ,该方式最为简单!但是你不能通过IP-in-IP隧道转发广播或者IPv6数据包。你只是连接了两个一般情况下无法直接通讯的IPv4网络而已。至于兼容性,这部分代码已经有很长一段历史了,它的兼容性可以上溯到1.3版的内核。据网上查到信息,Linux的IP-in-IP隧道不能与其他操作系统或路由器互相通讯。它很简单,也很有效。

  GRE 需要内核模块 ip_gre.ko ,GRE是最初由CISCO开发出来的隧道协议,能够做一些IP-in-IP隧道做不到的事情。比如,你可以使用GRE隧道传输多播数据包和IPv6数据包。

  sit 他的作用是连接 ipv4 与 ipv6 的网络。个人感觉不如gre使用广泛 。

  实际应用中,以上提到的三种ip tunnel 技术和VPN技术一样,多用于跨公网的网络中(当然跨网段的内网环境也适用)。如上图所示,我搞了两台虚机,其中eth0网段就类似于常见的公网网络。 eth1网络为各自的私网 。最终实现效果是实现两台主机的 eth1网络可以互通。这里测试中使用的是基于gre模式进行的实现,如果使用ipip、sit,只需要把modprobe后面的模块换掉,把ip tunnel 命令中mode后面的字符替换掉即可。

  两边互ping发现可以ping ,即为实验成功。这里需要注意iptables项,执行iptables -F是必须的,不然两边不通。如果在需要开启防火墙的情况下,也可以执行如下步骤:

  假如这边还有台主机C,C主机只有一块网卡,其IP为192.168.1.100,和a主机同在eth1网段,可以将a主机配置为一个简单的种由器,其可以访问b主机的IP 192.168.2.90 。只需要在a主机中做如下配置即可。

  提到的linux下的三种模块级的tunnel技术传输都是不加密的,这是和 很多VPN技术比较大的一个区别。同时三都之间在实现原理上也略有区别。

  上图是ipip tunnel 的原理图,明显是其点对点的一种tunnel 。这个非常容易理解,这也是其不能广播的原因。据网上的资料说sit 也属于点对点的tunnel,这个由于未翻阅到sit tunnel 比较详细的信息,不能确定其属于不属于简单的点对点 tunnel ,个人感觉sit 不属于简单的点对点 tunnel ,因为在一些路由网络设备中发现其有支持,和gre tunnel 一样。

  由于ip tunnel 技术目前只技术linux技术 ,所以上面的两台主机只能运行在类linux主机上。

  重点说下gre tunnel,除了外层的 IP 头和内层的 IP 头之间多了一个GRE头之外,它最大的不同是, tunnel不是建立在最终的 host 上,而是在中间的 router 上 !换句话说,对于端点host A 和 host B来说,该tunnel是透明的(对比上面的 ipip tunnel)。添加外部的 IP 头是在 router A 上完成的,而去掉外面的 IP 头是在 router B上完成的,两个端点的 host 上几乎什么都不用做(除了配置路由,把发送到 10.0.2.0 的包路由到 router A)!

  从这个原理就可以了解到,gre tunnel 是支持广播和多播的。所以除了上面的route A和route B需要为类linux平台,上面的host a 和host b选用什么类型的系统无所谓。

  稍微难理解的是接收过程,即 router B 上面进行的操作。这里需要指出的一点是,GRE tunnel 自己定义了一个新的 IP proto,也就是 IPPROTO_GRE。当 router B 收到从 router A 过来的这个包时,它暂时还不知道这个是 GRE 的包,它首先会把它当作普通的 IP 包处理。因为外部的 IP 头的目的地址是该路由器的地址,所以它自己会接收这个包,把它交给上层,到了 IP 层之后才发现这个包不是 TCP,UDP,而是 GRE,这时内核会转交给 GRE 模块处理。

  所以真正处理这个包的函数是 ipgre_rcv() 。ipgre_rcv() 所做的工作是:通过外层IP 头找到对应的 tunnel,然后剥去外层 IP 头,把这个“新的”包重新交给 IP 栈去处理,像接收到普通 IP 包一样。到了这里,“新的”包处理和其它普通的 IP 包已经没有什么两样了:根据 IP 头中目的地址转发给相应的 host。注意:这里我所谓的“新的”包其实并不新,内核用的还是同一个copy,只是skbuff 里相应的指针变了。

上一篇:葡京官网开户美食扎根产区也能从天山走向世界?“天地人”优势打造世界级
下一篇:大数医达:医学界的 !gps导航地图 !百度地图和GPS导航 中关

欢迎扫描关注我们的微信公众平台!

欢迎扫描关注我们的微信公众平台!