⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 835.html

📁 著名的linux英雄站点的文档打包
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<br>
<br>
<br>
<br>
<br>
背景:隧道的多种理解和实现 <br>
<br>
<br>
<br>
Internet的研究者多年前就感到需要在网络中建立隧道,最初的理解是在网络 <br>
<br>
中建立一条固定的路径,以绕过一些可能失效的网关。可以说,隧道就是一条 <br>
<br>
特定的路径。 <br>
<br>
这样的隧道是通过IP报头中的源路由选项来实现的,在目前看来,这个方法的缺陷 <br>
<br>
十分明显。要设置源路由选项就必须知道数据包要经过的确切路径,而且目前 <br>
<br>
多数路由实现中都不支持源路由。 <br>
<br>
<br>
<br>
另一个实现隧道的机制是开发一种新的IP选项,用来表明源数据包的信息,原IP头 <br>
<br>
可能成为此选项的一部分。这种隧道的意义与我们所说的隧道已十分接近。但它的 <br>
<br>
不足在于要对目前IP选项的实现和处理做较大的修改,也缺乏灵活性。 <br>
<br>
<br>
<br>
最后常用的一种实现方法是开发一种新的IP封包协议,仍然套用当前的IP头格式。 <br>
<br>
通过IP封包,不须指明网络路径,封包就能透明地到达目的地。也可以通过封包空 <br>
<br>
间把未直接连接的机器绑在一起,从而创建虚拟网络。这种方法易行、可靠、可扩 <br>
<br>
展性强,Linux采用了这一方法,这也是目前我们所理解的隧道思想。 <br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
一、 <br>
<br>
封包协议的结构和实现 <br>
<br>
<br>
<br>
封包协议的实现原理十分简单。先看看通过隧道传送的数据报在网络中如何流动, <br>
<br>
如图一。 <br>
<br>
为了叙述简便,我把在隧道中传送的IP数据包称为封包。 <br>
<br>
<br>
<br>
     --------------                    ----------- <br>
<br>
    /    子网A                       /   子网C    <br>
<br>
   /                                /              <br>
<br>
  |                  |              |               | <br>
<br>
  |     &            |              |               | <br>
<br>
  |     +   +++++    |              |      *****    | <br>
<br>
  |     +++++   +    |              |      *   *    | <br>
<br>
  |             +    |              |  *****   *    | <br>
<br>
               +   /  -----------   *       *    /  ---------- <br>
<br>
               ++&gt; # *         **&gt;(#) *       ***&gt; # ++++       <br>
<br>
     --------------  / *        *    ------------  /   +         <br>
<br>
                    |  *        *   |              |    +         | <br>
<br>
                    |  *        *   |              |    +         | <br>
<br>
                    |  *****    *   |              |    +++++++   | <br>
<br>
                    |      *****    |              |          V   | <br>
<br>
                    |               |              |          &   | <br>
<br>
                                  /                             / <br>
<br>
                         子网B   /                    子网D    / <br>
<br>
                       -----------                    ---------- <br>
<br>
<br>
<br>
                     ++++++       原数据报 <br>
<br>
                     ******       封装后的数据包(封包) <br>
<br>
                     #            封装/解封 <br>
<br>
                     &            用户主机 <br>
<br>
<br>
<br>
                         图一.  封包协议实现模型 <br>
<br>
                          <br>
<br>
<br>
<br>
看图中的设备 #,分别处于隧道的两端,分别起打包(封装)和解包(解封) <br>
<br>
的作用,在整个数据包的传送路径中,除了隧道两端的 # 设备,其他网关把 <br>
<br>
数据包看成一个普通的IP包进行转发。 <br>
<br>
设备 # 就是一个封包基于的两个实现部件--封装部件和解封部件。封装和解封 <br>
<br>
部件(设备)都应当同时属于两个子网。封装部件对接收到的数据报加上封包头 <br>
<br>
,然后以解封部件地址作为目的地址转发出去;而解封部件则在收到封包后,还 <br>
<br>
原原数据报,转发到目的子网。 <br>
<br>
<br>
<br>
隧道的源端(封装部件)对进入隧道的数据包进行封装,形成封包。一个完整 <br>
<br>
的封包如图二所示。 <br>
<br>
<br>
<br>
                    /  +-----------------+ <br>
<br>
                    |  |    封包IP头     |  <br>
<br>
           封包头   |  +-----------------+ <br>
<br>
                    |  |   封包协议头    | <br>
<br>
                      +-----------------+ <br>
<br>
                    /  |    原协议头     |    <br>
<br>
                    |  +-----------------+ <br>
<br>
                    |  |                 | <br>
<br>
          原数据报  |  |   原协议数据    |  <br>
<br>
                    |  .                 . <br>
<br>
                    |  .                 . <br>
<br>
                    |  |                 | <br>
<br>
                      +-----------------+ <br>
<br>
<br>
<br>
                  图二.      封包结构 <br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
二、 <br>
<br>
Linux中的实现 <br>
<br>
<br>
<br>
本人分析的版本是Linux2.0.34(RedHat5.2采用)。 <br>
<br>
<br>
<br>
在Linux中,隧道的实现主要基于两个文件new_tunnel.c和ipip.c <br>
<br>
<br>
<br>
同时Linux定义了一种新的协议类型--IPIP(IPPROTO_IPIP),与上面所说封包 <br>
<br>
类型类似。 <br>
<br>
<br>
<br>
基本思路 <br>
<br>
在Linux中IP Tunnel的实现也分为两个部件:封装部件和解封部件,分别司职发送和接 <br>
<br>
收。但这两个部分是在不同的层次以不同的方式实现的。 <br>
<br>
封装部件是在数据链路层以虚设备的方式实现。所有源代码见 <br>
<br>
/usr/src/linux/drivers/net/new_tunnel.c <br>
<br>
为实现封装,Linux实现一个称为tunl的网络设备(类似loopback设备),此设备 <br>
<br>
具有其他网络设备共有的特征,对于使用此设备的上层应用来说,对这些网络设备 <br>
<br>
不加区分,调用及处理方法当然也完全一样。 <br>
<br>
        tunnel_init()和tunnel_xmit()是new_tunnel.c中的两个主要过程。 <br>
<br>
        tunnel_init()初始化与设备tunl相关的device结构。 <br>
<br>
    而tunnel_xmit()在从tunl设备发送数据时被调用,tunl设备作为实现IP隧道 <br>
<br>
技术的封装部分,在此过程中完成对相应的数据报进行封装所需的全部操作, <br>
<br>
形成IPIP类型的IP包,并重新转发此数据包(ip_forward())。 <br>
<br>
解封部件在IP的上层实现,系统把它作为一个虚的传输层(实际上与传输层毫无 <br>
<br>
关系),具体处理见文件 <br>
<br>
         /usr/src/linux/net/ipv4/ipip.c。 <br>
<br>
我们知道,每一个IP数据包均交由ip_rcv函数处理,在进行一些必要的判断后,ip_rcv <br>
<br>
对于发送给本机的数据包将交给上层处理程序。对于IPIP包来说,其处理函数是 <br>
<br>
ipip_rcv(就如TCP包的处理函数是tcp_rcv一样,IP层不加区分)。也就是说,当 <br>
<br>
一个目的地址为本机的封包到达后,ip_rcv函数进行一些基本检查并除去IP头,然后 <br>
<br>
交由ipip_rcv解封。 <br>
<br>
ipip_rcv所做的工作就是去掉封包头,还原数据包,然后把还原后的数据包放入相应的 <br>
<br>
接收队列(netif_rx())。 <br>
<br>
<br>
<br>
从以上IP Tunnel实现的思想来看,思路十分清晰,但由于IP Tunnel的特殊性,其 <br>
<br>
实现的层次并不单纯。实际上,它的封装和解封部件不能简单地象上面所说的那样 <br>
<br>
分层。tunl设备虽应算进链路层,但其发送程序中做了更多的工作,如制作IPIP头 <br>
<br>
及新的IP头(这些一般认为是传输层或网络层的工作),调用ip_forward转发新包 <br>
<br>
也不是一个网络设备应当做的事。可以说,tunl借网络设备之名,一把抓干了不少 <br>
<br>
工作,真是‘高效’。而解封部件宏观上看在网络层之上,解出IPIP头,恢复原数据包 <br>
<br>
是它分内的事,但在它解出数据包(即原完整的协议数据包)后,它把这个包 <br>
<br>
放入相应的协议接收队列。这种事可不是一个上层协议干的,这是网络设备中断 <br>
<br>
接收程序的义务。看到了,在这点上,它好象到了数据链路层。 <br>
<br>
是不是有点乱,隧道机制就是这样,你有没有更好的办法? <br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
三、 <br>
<br>
为实现VPN的扩展 <br>
<br>
<br>
<br>
实际上Linux只为实现隧道机制提供了一个框架,图二中的封包协议头在 <br>
<br>
Linux中被忽略了,也就是说,封包头只含封包IP头,其后紧跟原IP数据包。 <br>
<br>
这样的结构用于传输公开数据没有关系,但对于一个VPN来说,安全保密是 <br>
<br>
不可缺少的重要功能。我们希望通过隧道的数据可靠且不可窃取和冒充的, <br>
<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -