class="21861">
****************************************************************
作者的話:
本文系在閱讀Linux源碼及一些相關資料的基礎上寫成的。
歡迎就文章的各個方面提出建議和批評意見,作者希望更多的交流和探討。
歡迎在保留原文完整性的前提下在網上轉貼,需部分引用請通知作者。
傳統媒體轉載和引用此文,請務必經過作者同意。
歡迎在實際的應用中使用此文提出的思想,希望同時知會作者。
作者信箱:
[email protected] 歡迎來信!!
*****************************************************************
O、
由於網絡的日益普及,網絡的安全成為目前的熱門話題。本文對隧道技術的分析,
就側重安全領域,對利用隧道技術實現虛擬專網提出建議。
為什麼需要IP隧道?沒有接觸過這個概念的人自然提出這樣的疑問。實際上概念
最初的提出很簡單,為了在TCP/IP網絡中傳輸其他協議的數據包。設想IPX協議或
X.25封裝的數據包如何通過Internet網進行傳輸,在已經使用多年的橋接技術中是
通過在源協議數據包上再套上一個IP協議頭來實現,形成的IP數據包通過Internet後
卸去IP頭,還原成源協議數據包,傳送給目的站點。對源協議數據來說,就如被IP
帶著過了一條隧道。這種技術在業余無線網絡(Amateur;Packet;Radio;network,
應該怎麼翻,請告訴我)得到了最廣泛的應用。
利用IP隧道來傳送的協議包也包括IP數據包,本文主要分析的IPIP封包就是如此,從字
面來理解IPIP就對了,就是把一個IP數據包又套在一個IP包裡。為什麼要這麼做呢?
多此一舉嘛。其實不然,見過一些應用就會明白,移動IP(Mobile-IP)和IP多點廣播
(IP-Multicast)是兩個通常的例子。目前,IP隧道技術在構築虛擬專網(;Virtual;
Private;Network)中也顯示出極大的魅力。本文也將對利用IP隧道技術構築VPN做
簡單設想。
背景:隧道的多種理解和實現
Internet的研究者多年前就感到需要在網絡中建立隧道,最初的理解是在網絡
中建立一條固定的路徑,以繞過一些可能失效的網關。可以說,隧道就是一條
特定的路徑。
這樣的隧道是通過IP報頭中的源路由選項來實現的,在目前看來,這個方法的缺陷
十分明顯。要設置源路由選項就必須知道數據包要經過的確切路徑,而且目前
多數路由實現中都不支持源路由。
另一個實現隧道的機制是開發一種新的IP選項,用來表明源數據包的信息,原IP頭
可能成為此選項的一部分。這種隧道的意義與我們所說的隧道已十分接近。但它的
不足在於要對目前IP選項的實現和處理做較大的修改,也缺乏靈活性。
最後常用的一種實現方法是開發一種新的IP封包協議,仍然套用當前的IP頭格式。
通過IP封包,不須指明網絡路徑,封包就能透明地到達目的地。也可以通過封包空
間把未直接連接的機器綁在一起,從而創建虛擬網絡。這種方法易行、可靠、可擴
展性強,Linux采用了這一方法,這也是目前我們所理解的隧道思想。
一、
封包協議的結構和實現
封包協議的實現原理十分簡單。先看看通過隧道傳送的數據報在網絡中如何流動,
如圖一。
為了敘述簡便,我把在隧道中傳送的IP數據包稱為封包。
--------------;;;;-----------
/;;;;子網A;;;;;;;/;;;子網C;
//;;;
|;;|;;;;;;|;;;;;;;|
|;;;;;&;;;;|;;;;;;|;;;;;;;|
|;;;;;+;;;+++++;;;;|;;;;;;|;;;;;;*****;;;;|
|;;;;;+++++;;;+;;;;|;;;;;;|;;;;;;*;;;*;;;;|
|;;;;;+;;;;|;;;;;;|;;*****;;;*;;;;|
+;;;/;;-----------;;;*;;;;;;;*;;;;/;;----------
++>;#;*;**>(#);*;;;;;;;***>;#;++++;;;;
--------------;;/;**;;;;------------;;/;;;+
|;;**;;;|;;;;;;|;;;;+;|
|;;**;;;|;;;;;;|;;;;+;|
|;;*****;;;;*;;;|;;;;;;|;;;;+++++++;;;|
|;;;;;;*****;;;;|;;;;;;|;;V;;;|
|;;;;;;;|;;;;;;|;;&;;;|
/;;;;;/
子網B;;;/;;;;子網D;;;;/
-----------;;;;----------
++++++;;;;;;;原數據報
******;;;;;;;封裝後的數據包(封包)
#;;;;封裝/解封
&;;;;用戶主機
圖一.;;封包協議實現模型
看圖中的設備;#,分別處於隧道的兩端,分別起打包(封裝)和解包(解封)
的作用,在整個數據包的傳送路徑中,除了隧道兩端的;#;設備,其他網關把
數據包看成一個普通的IP包進行轉發。
設備;#;就是一個封包基於的兩個實現部件--封裝部件和解封部件。封裝和解封
部件(設備)都應當同時屬於兩個子網。封裝部件對接收到的數據報加上封包頭
,然後以解封部件地址作為目的地址轉發出去;而解封部件則在收到封包後,還
原原數據報,轉發到目的子網。
隧道的源端(封裝部件)對進入隧道的數據包進行封裝,形成封包。一個完整
的封包如圖二所示。
/;;+-----------------+
|;;|;;;;封包IP頭;;;;;|;
封包頭;;;|;;+-----------------+
|;;|;;;封包協議頭;;;;|
+-----------------+
/;;|;;;;原協議頭;;;;;|;
|;;+-----------------+
|;;|;|
原數據報;;|;;|;;;原協議數據;;;;|;
|;;.;.
|;;.;.
|;;|;|
+-----------------+
圖二.;;;;;;封包結構
二、
Linux中的實現
本人分析的版本是Linux2.0.34(RedHat5.2采用)。
在Linux中,隧道的實現主要基於兩個文件new_tunnel.c和ipip.c
同時Linux定義了一種新的協議類型--IPIP(IPPROTO_IPIP),與上面所說封包
類型類似。
基本思路
在Linux中IP;Tunnel的實現也分為兩個部件:封裝部件和解封部件,分別司職發送和接
收。但這兩個部分是在不同的層次以不同的方式實現的。
封裝部件是在數據鏈路層以虛設備的方式實現。所有源代碼見
/usr/src/linux/drivers/net/new_tunnel.c
為實現封裝,Linux實現一個稱為tunl的網絡設備(類似loopback設備),此設備
具有其他網絡設備共有的特征,對於使用此設備的上層應用來說,對這些網絡設備
不加區分,調用及處理方法當然也完全一樣。
tunnel_init()和tunnel_xmit()是new_tunnel.c中的兩個主要過程。
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())。
從以上IP;Tunnel實現的思想來看,思路十分清晰,但由於IP;Tunnel的特殊性,其
實現的層次並不單純。實際上,它的封裝和解封部件不能簡單地象上面所說的那樣
分層。tunl設備雖應算進鏈路層,但其發送程序中做了更多的工作,如制作IPIP頭
及新的IP頭(這些一般認為是傳輸層或網絡層的工作),調用ip_forward轉發新包
也不是一個網絡設備應當做的事。可以說,tunl借網絡設備之名,一把抓干了不少
工作,真是‘高效’。而解封部件宏觀上看在網絡層之上,解出IPIP頭,恢復原數據包
是它分內的事,但在它解出數據包(即原完整的協議數據包)後,它把這個包
放入相應的協議接收隊列。這種事可不是一個上層協議干的,這是網絡設備中斷
接收程序的義務。看到了,在這點上,它好象到了數據鏈路層。
是不是有點亂,隧道機制就是這樣,你有沒有更好的辦法?
三、
為實現VPN的擴展
實際上Linux只為實現隧道機制提供了一個框架,圖二中的封包協議頭在
Linux中被忽略了,也就是說,封包頭只含封包IP頭,其後緊跟原IP數據包。
這樣的結構用於傳輸公開數據沒有關系,但對於一個VPN來說,安全保密是
不可缺少的重要功能。我們希望通過隧道的數據可靠且不可竊取和冒充的,
那麼,加密和認證就必不可少。
為實現這一構想,設計以下封包協議頭:
0;;;;4;;;;;8;;16;;;24;;31;
+-----+-----+-----------+-----------