Jump to content

隨著聯網設備數量的不斷增加,對互聯網協議(IP) 地址的需求已經超過了互聯網協議版本4 (IPv4) 地址的供應,導致採用互聯網協議版本6 (IPv6) 來減少加載IPv4 地址。

在您的虛擬專用網絡(VPN) 服務中使用IPv6 可以幫助您實現更好的安全性、支持更多功能並訪問更大的地址空間。該協議可以讓您的解決方案面向未來,使其能夠在特定的5G 網絡中運行,並支持支持IPv6 的企業和專用網絡。

在本文中,我們在解釋了IPv4 和IPv6 協議之間的差異後展示瞭如何將IPv6 支持添加到應用程序VPN。在我們的示例中,即使我們無法直接訪問IPv6 網絡,我們也會通過網絡地址轉換64 (NAT64) 添加IPv6 支持,並解釋NAT64 在IPv6 中的作用。您可以在可能無法對網絡進行細粒度控制的受限環境中使用我們在此處介紹的方法。受限環境是指只有IPv6 或IPv4 網絡可用的環境。在這樣的環境中,不可能到達存在於不受支持的地址空間中的某些目標服務器。

虛擬專用網絡簡介VPN 技術允許多台計算機通過軟件定義的虛擬網絡在互聯網上安全、私密地連接。這些虛擬網絡的創建獨立於底層物理網絡基礎設施的物理拓撲。您可以通過以下步驟實現此目的:

通過物理網絡打包和中繼VPN 數據包的虛擬網絡接口之間的隧道流量

將整個過程抽象為VPN 客戶端

這是一個簡單的VPN 設置示例:

image.png

基本的VPN 設置

在此設置中,如果客戶端設備1 想要向客戶端設備2 發送數據,則會發生以下情況:

客戶端設備1 可以使用10.0.0.2 地址通過其VPN 接口向VPN 服務器發送數據包。

接口查詢其配置信息並確定數據包的下一個目的地。當接口必須將數據包發送到另一台物理主機時,作為VPN 服務器的網絡適配器的物理接口將連同標頭一起傳輸整個數據包。

這個新數據包包含物理網絡的路由信息。

目標主機收到新數據包,解包原來的VPN 數據包,並以同樣的方式繼續路由。

這是包裝後的數據包的樣子:

image.png

包裹的VPN 數據包

請注意,VPN 接口的軟件實現生成物理接口的數據包,允許它在VPN 數據包被路由之前執行其他操作。例如,物理接口的數據包可以加密整個有效載荷,這樣物理主機就無法訪問嵌套的VPN 數據包,這是一個封裝在另一個VPN 數據包中的數據包。

這種在路由數據包之前嵌套數據包的想法也可以應用於常規數據包。以下是這個想法在這種情況下的工作方式:

VPN 服務要求操作系統通過其虛擬接口路由數據包。

VPN 接口根據其配置文件路由數據包。

例如,VPN 接口可以將數據包發送到VPN 服務器,VPN 服務器解壓縮到達的數據包,將它們代理到原始目的地,然後將響應返回給VPN 客戶端。

大多數人在考慮VPN 的工作原理時都會想到這種情況。虛擬專用網絡允許對客戶端的出站流量進行加密和代理,以提供額外的安全級別並向客戶端的互聯網服務提供商(ISP) 隱藏信息。

VPN 是在通信協議、加密和身份驗證的幫助下實現的,這些協議有助於在Internet 上安全地加密和傳輸數據。在下一節中,我們將討論哪些通信協議對於實施VPN 解決方案至關重要。

IPv4 和IPv6 概述及其與VPN 的連接大多數VPN 實施在開放系統互連模型的網絡層上運行。根據這個模型,VPN 實現處理IP 數據包並處理它們的路由。這需要VPN 網絡接口背後的軟件來實現Internet 協議,也可能需要一些傳輸層協議。

網絡協議是一組規則,描述數據的結構以及對等方應如何處理它。互聯網協議是一種特定的網絡協議,可以使互聯網上的設備之間進行通信。使用VPN 時,您通常需要使用多種協議,例如Internet 協議或傳輸控制協議(TCP),這些協議有助於通過Internet 在設備之間進行安全通信。 VPN 中使用IPv4 和IPv6 在設備之間傳輸數據。此外,已實現的TCP 可以根據從網絡接收到的原始字節重建TCP 數據包,並創建符合TCP 規則的新TCP 數據包。

實現一個網絡通信協議通常包括以下步驟:

編寫用於創建和解析數據包的函數

實現一個狀態機,它根據處理過的數據包的內容而改變

傳送數據包的方法不是協議的一部分,可以在協議實現過程之外進行處理。

現在,讓我們仔細看看兩個特定的協議:IPv4 和IPv6。這些是主要的互聯網協議,其中IPv4 是最常用的,而IPv6 是最新的。

IPv6 與IPv4:有何區別? IPv4是目前世界上使用最廣泛的協議,儘管它不是Internet 協議的最新版本。 IPv4 地址是32 位數字,以十進製表示法表示為由點分隔的四組數字;例如,192.168.0.1。

IPv4 最多支持大約43 億個唯一地址,因為地址字段只有4 個字節(或32 位)長。 IPv6使用128 位地址並提供更大的地址空間。這是IPv6 相對於IPv4 的主要優勢。由於連接互聯網的設備數量早已超過40 億大關,IPv4 的地址空間已經完全耗盡。在IPv6 網絡中,可能的地址數量為2^128,或大約340 六十億,大約是43 億的79 萬億倍。通過IPv4 網絡傳輸IPv6 流量還有幾個重要的好處:

image.png

IPv6 與IPv4 相比的優勢

基本IPv6 標頭僅包含協議運行的最重要信息。如果對等方需要在標頭中攜帶額外信息,他們可以將各種可選標頭鏈接在一起。這種方法減少了協議最常見用例的開銷,例如從A 向B 發送數據包。

image.png

IPv4 與IPv6 標頭

現在您已經知道切換到IPv6 協議的主要好處,讓我們來看看如何在IPv4 基礎設施上路由IPv6 流量。

使用IPv6 提高VPN 安全性要介紹任何協議,您需要閱讀文檔並實現狀態機和處理特定於所選協議的數據包的功能。但在此步驟中,您可能還會遇到一些問題。讓我們看一下在VPN 服務中實現IPv6 支持的標準機制。

當您允許來自IPv4 的IPv6 流量時,您可以實現以下目標:

允許客戶端應用訪問IPv6 網絡上的服務器

支持純IPv6 環境中的網絡

實施IPv6 協議的過程很簡單。 VPN 服務從其由操作系統管理的虛擬網絡接口獲取所有客戶端數據。此數據包括實際的協議標頭,直到VPN 服務必須處理的IP 標頭。 VPN 服務還必須能夠根據從虛擬網絡接口接收到的信息構建響應數據包。

使用IPv6 協議,處理數據包相當簡單:

VPN 服務會存儲原始標頭,直到它從目標服務器獲取響應。

VPN 服務通過交換源地址和目標地址並更新與負載相關的字段來重用標頭來構造響應數據包。

新標頭添加到響應數據之前,並寫回虛擬接口供操作系統處理。

您還可以使用其他編程語言在您的應用程序中實現VPN 服務,例如C/C++、Java、Python 和Rust。在本文中,我們探索了VPN 服務的Kotlin實現。當您需要實施每應用VPN 時,Kotlin 有一些好處,它允許您為每個應用創建單獨的VPN 連接以隔離網絡流量:

image.png

假設我們的VPN 服務可以直接訪問虛擬網絡接口的文件描述符。該服務通過多個套接字轉發數據包的有效負載,將數據包代理到外部世界。套接字本身和相關的元數據存儲在會話抽像中。然後,數據包由SessionHandler類處理。

以下是SessionHandler類在處理數據包時所做的事情:

解析數據包

根據存儲在相應會話中的信息決定如何處理它們

轉發數據包的內容

處理響應

在將響應放回網絡接口之前為客戶端重新打包響應

image.png

由於虛擬網絡接口由文件描述符表示,因此從中接收數據包就像從常規文件中讀取數據一樣容易:

image.png

原始字節很難處理,尤其是當您需要將它們解釋和操作為複雜的數據結構(如協議標頭)時。在Kotlin 中,可以創建可以解釋原始字節並提供用於更改標頭字段的簡單接口的精簡包裝器。此類包裝器提供與標頭中每個字段相對應的函數,提供對它們的輕鬆讀寫訪問。

您還可以將所有這些函數轉換為具有自定義getter 和setter 的字段。在這種情況下,使用包裝器的客戶端代碼看起來就像在操作常規數據類。 IP 標頭的包裝器如下所示:

classIPWrapper(bytes:ByteArray){

//wrapthebytesintotheByteBufferclassforeasierbytemanipulationandextrafunctionality

//besuretoaccountfortheByteBuffer'sstatefulnessandspecifyindicesexplicitlywhenaccessing

//thebytes

privatevalbuffer=ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN)

//theIPversionisstoredinthefirst4bitsoftheheader

varipVersion

//togetit,readthefirstbyteandshiftitby4bitstotheright

get()=(buffer.get(0).toInt()shr4)

//andtosetit,shiftthedesiredvaluetotheleftby4bitsandperformthebitwiseshiftOR

//onthefirstbyteoftheunderlyingbytearray

set(value){buffer.put(0,((valueshl4)or(buffer.get(0).toInt()and0x0F)).toByte())}

//IPv4andIPv6headerscontaindifferentfields,soifclientcodeattemptstoaccessafieldthat

//isnotpresentintheunderlyingpacket,throwanexception

varheaderLength

get()=

//checktheipversionbycallingtheipVersionmemberdeclaredearlier

if(ipVersion==4)(buffer.get(0)and0x0F)

//IPv6headerdoesnothaveafieldfortheheaderlength,sothereisnovaluethisgettercanreturn

elsethrowException('IPv6doesn'thaveaHeaderLengthfield!')

set(value){

//similarly,ifthefieldisthere,setit

if(ipVersion==4)buffer.put(0,((valueand0x0F)or(buffer.get(0).toInt()and0xF0)).toByte())

//ifit'snot,throwanexception

elsethrowException('IPv6doesn'thaveaHeaderLengthfield!')

}

//IPheaderscanbeofdifferentversions,andit'sconvenienttohaveasinglewrapperclass

//forbothIPv4andIPv6

varsrcIp

get()=InetAddress.getByAddress(run{

val(startPos,len)=

if(ipVersion==4)listOf(SOURCE_IP_POS_IPV4,ADDR_LEN_IPV4)

elselistOf(SOURCE_IP_POS_IPV6,ADDR_LEN_IPV6)

//whengettingtheIPaddress,simplycopythebytesthatrepresentitandpasstheresult

//intoJava'sInetAddress.getByAddressfunctionthatwilldotherestoftheparsing

buffer.array().copyOfRange(startPos,startPos+len)

})

set(value){

value.address.copyInto(

buffer.array(),

if(ipVersion==4)SOURCE_IP_POS_IPV4

elseSOURCE_IP_POS_IPV6

)

}

//dothesameforthedestinationaddress

vardestIp

get()=/*.*/

set(value)=/*.*/

//otherfieldscanbeimplementedinasimilarfashion

/*.*/

//thiswrappercanalsohavevariousconveniencefunctions;forexample,itcanprovide

//meansforeasilygettingthewrappedpacket'sheaderstoquicklycreateresponseheaders

funcopyHeaders()=/*.*/

//orhandlethechecksumcomputationsfortheIPandthenestedtransportheaders

funupdateChecksums()=/*.*/

}一旦SessionHandler 類收到數據包,它就可以將數據包字節放入IPWrapper對象並使用IPWrapper 類從IP 標頭訪問它需要的任何信息。例如,在創建響應數據包時,SessionHandler類可以簡單地複制標頭並更新字段,而不是創建一個全新的標頭:

image.png

您可以將生成的響應數據包寫回VPN 的網絡接口:

image.png

一旦SessionHandler 類將數據包的字節放入IPWrapper 類,路由軟件將解析VPN 服務生成的IP 標頭並將數據包路由到其目的地。在這種情況下,目標是本地應用程序,其出站流量已通過操作系統的路由規則重定向到VPN 的網絡接口。

現在,讓我們看看如果您只能訪問IPv4 網絡,如何檢查支持IPv6 的VPN。

使用NAT64 測試IPv6 實現雖然實施協議相對簡單,但測試才是真正挑戰的開始。那麼,NAT64、IPv4、IPv6是如何相互連接的呢?

IPv6 明顯優於IPv4,但支持IPv6 的基礎設施尚不存在。世界上許多ISP 仍然不支持IPv6,因此他們無法將IPv6 轉換為IPv4,反之亦然。因此,他們的客戶端無法訪問任何使用IPv6 的服務器。相反的情況也存在:有些網絡僅使用IPv6 運行,不處理IPv4 數據包。

要解決這些不兼容問題,您可以使用以下轉換機制之一:

image.png

IPv6 過渡機制

對於下面描述的方法,我們使用了NAT64——一種將所有40 億個IPv4 地址映射到IPv6 地址空間的保留塊的轉換機制。我們的客戶特別要求使用NAT64 在IPv4 地址和IPv6 地址之間進行轉換。

讓我們看看這種機制在實踐中是如何工作的,以及NAT64 為IPv6 做了什麼。假設連接使用不同IP 版本的網絡的路由器收到一個IPv6 數據包,其目標地址來自NAT64 地址範圍。這是接下來發生的事情:

路由器從收到的IPv6 數據包中刪除96 位長的NAT64 前綴,留下32 位的IPv4 地址。

之後,路由器為數據包創建一個新的IPv4 標頭,以便它可以繼續在網絡中傳輸。

當路由器收到IPv4 數據包並必須通過IPv6 網絡路由它時,也會發生同樣的情況:

路由器通過添加NAT64 前綴將IPv4 地址轉換為IPv6 地址。

路由器為數據包重新創建IP 標頭,然後通過IPv6 網絡路由數據包。

您可以使用這些轉換機制來測試IPv6 實現,尤其是在IPv6 網絡不可用的地方。要查看您的VPN 服務如何在純IPv4 環境中處理IPv6 數據包,請在您服務的VPN 接口上使用NAT64 範圍內的目標地址打開IPv6 套接字:

image.png

套接字傳輸

如果您的VPN 服務正常運行,它將接收這些數據包並像處理常規IPv6 數據包一樣處理它們。當這些數據包最終通過物理網絡接口進行路由時,它們將到達一個路由器,該路由器會將它們轉換為常規的IPv4 數據包。然後,您的VPN 服務將能夠從目標服務接收響應數據,為客戶端創建響應IPv6 數據包,並通過其虛擬接口發送。

結論雖然IPv4 仍然更受歡迎,但IPv6 為用戶和開發人員提供了更多好處。在本文中,我們解釋了為什麼需要在您的應用程序中將IPv4 轉換為IPv6,以及如何將對NAT64 的支持添加到您的應用程序中。在您無法完全控製網絡的受限環境中,也允許使用NAT64 將IPv6 地址映射到IPv4 目標。

0 Comments

Recommended Comments

There are no comments to display.

Guest
Add a comment...