Linux中IP隧道的分析与建议

操作方法

  • 01

    Linux中IP隧道的分析与建议 ----随着计算机网络的日益普及,网络的安全成为目前的热门话题。本文以Linux 2.0.34(RedHat5.2采用)为基础,对隧道技术进行分析,并侧重安全领域对在Linux环境下利用隧道技术实现虚拟专网提出建议。 ----为什么需要IP隧道?没有接触过这个概念的人自然会提出这样的疑问。实际上概念最初的提出很简单,就是为了在TCP/IP网络中传输其他协议的数据包。设想一下IPX协议或X.25封装的数据包如何通过Internet网进行传输,在已经使用多年的桥接技术中是通过在源协议数据包上再套上一个IP协议头来实现的,形成的IP数据包通过Internet后卸去IP头,还原成源协议数据包,再传送给目的站点。对源协议数据来说,就如同被IP带着过了一条隧道。这种技术在业余无线网络(Amateur Packet Radio Network)中得到了广泛的应用,目前的移动式IP(mobileIP)技术已经在此基础上得到了很好的发展。 ----利用IP隧道来传送的协议包也包括IP数据包,本文主要分析的IPIP封包就是如此。所谓IPIP,就是把一个IP数据包又套在一个IP包里。为什么要这么做呢?其实并非多此一举。见过一些应用就会明白,移动IP(Mobile-IP)和IP多点广播(IP-Multicast)是两个典型的例子。目前,IP隧道技术在构筑虚拟专网(VPN,Virtual Private Network)中也显示了出极大的生命力。本文也将对利用IP隧道技术构筑VPN做简单设想。 IP隧道的多种理解和实现 ----Internet的研究者多年前就感到需要在网络中建立隧道,最初的理解是在网络中建立一条固定的路径,以绕过一些可能失效的网关。可以说,隧道就是一条特定的路径。这样的隧道是通过IP报头中的源路由选项来实现的。在目前看来,这种方法的缺陷十分明显。要设置源路由选项就必须知道数据包要经过的确切路径,而目前多数路由实现中都不支持源路由。 ----另一种实现隧道的机制是开发一种新的IP选项,用来表明源数据包的信息,原IP头可能成为此选项的一部分。这种隧道的意义与我们所说的隧道已十分接近。但它的不足在于要对目前IP选项的实现和处理做较大的修改,此外它还缺乏灵活性。 ----最常用的一种实现方法是开发一种新的IP封包(encapsulation)协议,仍然套用当前的IP头格式。通过IP封包,不须指明网络路径,封包就能透明地到达目的地。也可以通过封包空间把未直接连接的机器绑在一起,从而创建虚拟网络。这种方法易行、可靠、可扩展性强。Linux采用了这一方法,这就是目前我们所理解的隧道思想。 封包协议结构 ----封包协议的实现原理十分简单,从图一中可以看到通过隧道传送的数据报在网络中是如何流动的。为了叙述简便,下文中把在隧道中传送的IP数据包称为封包。 图一封包协议实现模型 ----图一中的设备#都处于隧道的两端(中间的(#)设备只做简单的转发),分别起打包(封装)和解包(解封)的作用。在整个数据包的传送路径中,除了隧道两端的#设备,其他网关把数据包看成一个普通的IP包进行转发。设备#就是一个基于封包的两个实现部件———封装部件和解封部件。封装和解封部件(设备)都应当同时属于两个子网。封装部件对接收到的数据报加上封包头,然后以解封部件地址作为目的地址转发出去;而解封部件则在收到封包后,还原为数据报,转发到目的子网。 ----隧道的源端(封装部件)对进入隧道的数据包进行封装,形成封包。图二是一个完整的封包示意图。 图二封包结构 Linux封包实现 ----在Linux中,隧道的实现主要涉及两个文件:new-tunnel.c和ipip.c。另外,Linux还定义了一种新的协议类型———IPIP(IPPROTO-IPIP),它类似于上面所说的封包类型。 ----在Linux中IP Tunnel的实现也分为两个部件:封装部件和解封部件,分别司职发送和接收。但这两个部件是在不同的层次上以不同的方式实现的。 ----封装部件是在数据链路层以虚设备的方式实现的,所有源代码见: /usr/src/linux/drivers/net/new-tunnel.c ----为实现封装,Linux实现一个称为tunl的网络设备(类似于loopback设备),它具有其他网络设备共有的特征。对于使用此设备的上层应用来说,对这些网络设备不加区分,调用及处理方法当然也完全一样。 ----new-tunnel.c中的两个主要过程是tunnel-init()和tunnel-xmit(),其中tunnel-init()初始化与设备tunl相关的device结构,而tunnel-xmit()在从tunl设备发送数据时被调用,tunl设备作为实现IP隧道技术的封装部分,在此过程中完成对相应的数据报进行封装所需的全部操作,形成IPIP类型的IP包,并重新转发此数据包(ip-forward())。 ----解封部件在IP的上层实现,系统把它作为一个虚的传输层(实际上与传输层毫无关系),具体处理见文件: /usr/src/linux/net/ipv4/ipip.c。 ----我们知道,每一个IP数据包均交给ip-rcv函数处理,在进行一些必要的判断后,ip-rcv对于发送给本机的数据包将交给上层处理程序。对于IPIP包来说,其处理函数是ipip-rcv(与TCP包的处理函数tcp-rcv一样,IP层不加区分)。也就是说,当一个目的地址为本机的封包到达后,ip-rcv函数进行一些基本检查并除去IP头,然后交由ipip-rcv解封。 ----ipip-rcv的作用就是去掉封包头,还原数据包,然后把还原后的数据包放入相应的接收队列(netif-rx())中。 ----上述的IPTunnel实现思路十分清晰,但由于IP Tunnel的特殊性,其实现的层次并不单纯。它的封装和解封部件不能简单地像上面所说的那样分层。tunl设备虽然应算进链路层,但其发送程序还做了很多其他的工作,如制作IPIP头及新的IP头(这些一般认为是传输层或网络层的工作)。调用ip-forward转发新包也不是一个网络设备应当做的事。可以说,tunl借网络设备之名,做的工作却很多,因此相当“高效”。而解封部件宏观上看在网络层之上,解出IPIP头,恢复原数据包是它分内的事,但在它解出数据包(即原完整的协议数据包)后,它把这个包放入相应的协议接收队列。这项任务可不是一个上层协议干的,这是网络设备中断接收程序的义务。在这点上,它好像又到了数据链路层。隧道机制就是这样的。 为实现VPN的扩展 ----实际上Linux只为实现隧道机制提供了一个框架,图二中的封包协议头在Linux中被忽略了,也就是说,封包头只含封包IP头,其后紧跟原IP数据包。这样的结构用于传输公开数据没有关系,但对于一个VPN来说,安全保密是不可缺少的重要功能。我们希望通过隧道的数据可靠且不可窃取或假冒,因此加密和认证就必不可少。为实现这一构想,可设计以下封包协议头: 图三IPIP头设想图 ----其中type用于建立不同目的的隧道(可能处理上有差别),OldPacketLen是进入隧道的原数据包长度,DeviceID是对数据包进行封装的设备标识,EncapID是此封包的ID号,Flags是标志位,初步定义如下: 0 保留 1 有否加密 2 有否做摘要 3 有否签名 4 保留 5 是否传送消息密钥 6 消息密钥是否加密 7 消息密钥是否需保留 8-15 保留 ----IPIP Options用来传送一些必要的数据,比如消息密钥、签名等,其格式为, 类 型 长 度 数 据 ----有了上述定义,就可以扩展Linux IP Tunnel为VPN服务了。首先,改写new-tunnel.c和ipip.c两个文件,加入对IPIP头的处理。然后,要实现一种密钥的管理和传送机制。当然,对称密钥是必需的,而对IP数据包加密要使用序列密码。 ----在一个VPN的隧道中,一个封包的格式应如图四所示。 图四VPN封包结构 ----针对上述构想,通过对安全强度和通信速度的权衡,可以采用从不加密但速度快到高度机密但速度慢等不同的策略。当然还可以就加密强度本身作出选择,比如选择128位还是512位、1024位的加密算法。 ----当然,该方案在错误检测等方面还有需要完善的地方

(0)

相关推荐

  • 发现Linux中IP地址冲突的方法

    你们都知道什么是IP地址,是吧?它们被分配给网络上的设备来代表它们.它们通过DHCP服务器分配并且会经常改变.现在有两种IP地址.动态的一种会经常改变(几天一次),而静态的就如它的名字那样是静态的,意 ...

  • Linux系统新手学习的11点建议

    随着Linux应用的扩展许多朋友开始接触Linux,根据学习Windwos的经验往往有一些茫然的感觉:不知从何处开始学起。这里介绍学习Linux的一些建议。 一、从基础开始:常常有些朋友在Linux论 ...

  • Linux中提示No such file or directory解决方法

    问题描述 解决方法 分析原因,可能因为我平台迁移碰到权限问题我们来进行权限转换 1)在Windows下转换: 利用一些编辑器如UltraEdit或EditPlus等工具先将脚本编码转换,再放到Linu ...

  • linux中编写并发队列类

    这篇文章主要介绍了linux中编写并发队列类,功能有:并发阻塞队列、有超时限制、有大小限制 设计并发队列 代码如下: #include <pthread.h> #include <l ...

  • Linux中errno使用

    当linux中的C api函数发生异常时,一般会将errno变量(需include errno.h)赋一个整数值,不同的值表示不同的含义,可以通过查看该值推测出错的原因,在实际编程中用这一招解决了不少 ...

  • Linux中如何对服务器进行压力测试

    http_load是基于Linux平台的一种性能测工具.它是以并行复用的方式运行,仅适用于Web页面的性能测试,不适用于访问数据库,而且测试结果分析是有限的,平台依赖Linux .http_load可 ...

  • Linux中生成Core Dump系统异常信息记录文件的教程

    Linux中生成Core Dump系统异常信息记录文件的教程

  • 浅谈Linux中free命令以及它的一些有用选项

    Linux 系统管理员面临的一大挑战是如何在没有任何停机时间的情况下维护系统的良好运行.管理内存使用是 Linux 管理员又一个具有挑战性的任务.free 是 Linux 中一个标准的并且被广泛使用的 ...

  • 怎么在Linux中建立FTP服务器

    Linux是以后操作系统的趋势所在,目前的大部分国产操作系统,甚至于安卓系统都是与Linux离不开关系.其中,FTP作为其中共享手段存在已久,我们今天就来看看怎么搭建简单的FTP服务器吧. 操作方法 ...