Wireshark分析完整的Web請求過程(虛擬機NAT上網)


環境:Win11預覽版+VmwarePro16+Ubuntu20.4+Wireshark

本文利用WireShark工具對虛擬機中通過NAT上網的機器進行Web請求的分析

虛擬機NAT上網:

NAT原理:

NAT原理1

vmware中nat上網的設備主要有:
1)vmnat8:可以理解為一個交換機
   2)VMware Network Adapter VMnet8:是虛擬出來的一塊網卡,VMnet8僅僅是和Vmnet8虛擬機交換機網絡通信的(192.168.128.0/24),並不提供路由功能。禁用掉VMware Network Adapter VMnet8網卡,虛擬機仍然能上網,只是真機與虛擬機之間不能通信。

NAT原理2

所謂NAT模式就是將虛擬機網卡隱藏在了一個NAT設備之后,在外界看來,只能看到宿主機物理網卡,甚至連NAT設備都看不到,NAT設備默默地轉換着虛擬機內部出來的連接的源地址,為了實現的一致和簡單,VMWare使用了用戶態連接代理的方式來實現NAT設備,因此NAT設備其實就是一個用戶態進程,它來執行地址轉換,如下圖所示:在這里插入圖片描述
下圖為Windows任務管理器中的進程

vmnat企圖通過一種不對稱的方式處理NAT,即對於從Guest OS發出的數據包,通過直接抓取VMNet8的裸IP報文,修改源IP地址后發出,對於進入Guest OS的數據包,由於目標地址是本機,理所當然進入vmnat進程,被創建的socket接收,然后通過socket的方式發入VMNet8這個虛擬網卡。

但是對於TCP而言,上述的方式不適用!因為在反向方向,vmnat會打斷序列號(數據進入應用層后會剝離IP頭和TCP頭,丟失一切協議元信息),這就會打斷Guest OS到遠端的TCP連接。另外,作為TCP的客戶端,不發起connect是無法單獨創建socket的,因此,簡單的辦法就是直接接管整個TCP。
在這里插入圖片描述

抓包分析:在這里插入圖片描述

這是在物理主機上通過對無線網卡抓包獲得的原始報文,可以看出:
IP層:
源地址:202.114.200.252(DNS服務器地址)
目的地址:172.27.18.165(本地物理主機地址)
TTL:61

在這里插入圖片描述
這是在虛擬機內通過對ens33網卡抓包獲得的報文(在物理主機上對VMnet8網卡抓包可得同樣結果),可以看出:
IP層:
源地址:192.168.232.2(DNS服務器地址)
目的地址:192.168.232.128(本地物理主機地址)
TTL:128

以上兩個抓包結果容易看出:在物理主機接收到真正的報文之后,位於物理主機上的NAT進程將其做了一定處理,然后交給虛擬機。
通過觀察TTL發現:第一次是61,第二次是128。而TTL在實際轉發過程中不可能增大,而且128是TTL的默認值,故推斷出NAT將整個IP報文的頭部全部替換。
還能得出結論:無論真實物理上的DNS服務器是多少,對於虛擬機來說,其DNS服務器是192.168.232.2(看具體情況)。

Questions:

  • 虛擬NAT設備是默認網關嗎 ?如何驗證 ?是域名服務器嗎 ?

是默認網關也是DNS服務器,驗證方法:
1)利用route命令查看路由表
2)ip route show 命令查看
3)traceroute+網址 查看訪問路徑
下文第一節的抓包結果也印證了這一點。

  • DNS為什么封裝在UDP而不是TCP中 ?

TCP需要連接,三次握手的過程消耗大量時間等資源,而UDP是無連接的,因此效率更高。而且如果DNS查詢結果的包丟失,由於存在備用DNS服務器,可以繼續查詢,從而大大降低了無連接帶來的風險。

  • 多次對相同域名DNS查詢的結果一定相同嗎 ?

不一定相同,因為域名和IP不是一一對應的。
事實上:一個IP地址可以對應多個域名,一個域名也可以解析為多個IP地址。一台主機可以托管多個網站,這種情況下這多個網站的IP地址可能就會相同。利用請求的請求頭信息將來自不同的域名的請求轉發給不同的程序去處理。一個域名解析多個IP地址這種情況一般是針對那種訪問量特別大的網站,為了負載均衡,訪問者會解析到最合適IP地址。

  • 應用層的ping為什么不經過運輸層的TCP/UDP而直接利用IP封裝 ?

ping工作在應用層,它直接使用網絡層的ICMP協議,而沒有使用傳輸層的TCP/UDP協議,我認為是為了節省不必要的開銷,如果多經過傳輸層,在封裝處理和網絡傳輸上都會多增加開銷,而這種開銷是沒有必要的。ICMP是為測試網絡連通性設計的,根本用不上傳輸層的流量控制、差錯控制等高級手段。

  • 為什么VMware的虛擬網卡VMnet8只是虛擬機與物理主機通信的接口,虛擬機並不是依靠其聯網,但是在NAT模式下物理主機上卻能對其抓包呢 ?

對於大部分的包,NAT對於從Guest OS發出的數據包,通過直接抓取VMNet8的裸IP報文,修改源IP地址后發出,對於進入Guest OS的數據包,由於目標地址是本機,理所當然進入vmnat進程,被創建的socket接收,然后通過socket的方式發入VMNet8這個虛擬網卡。所以VMNet8網卡會經過從物理網卡傳來被NAT處理過的包以及虛擬機要發送出去的待處理包(見第一節抓包分析)。

完整的瀏覽網頁的網絡過程:

階段一:DHCP獲取本機IP

  • 虛擬機開機,Windows下打開Wireshark對“VMware Network Adapter VMnet8”抓包。

生成DHCP請求報文

  • 系統生成DHCP請求報文,並將該報文放入目的端口67(DHCP服務器),源端口68(DHCP客戶)的UDP報文段中,該UDP報文段又被放入源IP:0.0.0.0目的IP:255.255.255.0的IP數據報中,再將該IP數據報放在目的MAC為FF:FF:FF:FF:FF:FF 源MAC為虛擬網卡的MAC地址的以太網幀中,如圖:
DHCP報文
  • 然后用戶主機將該幀發送到以太網交換機,以太網交換機轉發到所有的出端口(包括路由器端口)。

  • 路由器接收到該幀以后,從中逐層取出信息。
    在這里插入圖片描述

  • 然后DHCP服務器生成包含分配給本地虛擬主機的IP地址以及DNS服務器的IP地址,默認網關路由器的IP和子網掩碼的一個DHCP ACK報文,並逐層將該報文封裝進以太網幀中,以太網幀的源MAC是路由器連到歸屬網絡接口時的MAC地址,目的MAC是本地虛擬主機的MAC地址。

  • 本地虛擬主機收到DHCP ACK報文,從中提取分配給他的IP地址和DNS服務器的地址。
    在這里插入圖片描述

Questions:

  • DHCP ACK的源和目的MAC分別是什么?

對於傳輸層:UDP的源端口是68表示DHCP客戶,目的端口是67表示DHCP服務器。
對於網絡層:源IP地址為0.0.0.0,目的IP為廣播IP:255.255.255.255
對於鏈路層:源MAC為本機的MAC:(00:0c:29:26:38:ec)這也是當前主機的唯一標識符,目的MAC為:FF:FF:FF:FF:FF:FF

  • 包含DHCP ACK的以太網幀是如何准確發送到客戶手中的?

路由器上的DHCP服務器收到請求后,將封裝一個ACK報文,所屬幀的源MAC為路由器連接到歸屬網絡接口的MAC地址,目的MAC是本地主機的MAC。
該幀發給交換機,由於交換機是自學習的,所以他知道發送給該mac的包該向哪個端口轉發。

  • 客戶收到DHCP ACK后需要做什么 ?

先逐層解析該包,得到DHCP ACK信息,DHCP客戶端記錄下分配給他的IP和DNS服務器的IP。然后在IP轉發表中安裝默認網關的地址。

階段二:DNS獲取目的IP

  • 打開瀏覽器,鍵入URL:(image.baidu.com)。要向該URL發送HTTP請求,需要先知道其IP地址,由於只知道待訪問網站的網址而不知道其IP,所以要從DNS服務器獲取目的IP地址。

DNS查詢報文

  • 本地虛擬主機生成DNS查詢報文,並逐層封裝進以太網幀。然后將該幀發送給網關路由器,但目前只知道網關路由器的IP並不知道其MAC地址,所以還需要進一步的利用ARP來獲取網關路由器的MAC地址

ARP查詢

  • 本地主機生成一個目的IP地址為默認網關IP,目的MAC為廣播地址FF:FF:FF:FF:FF:FF 的含有ARP查詢報文的以太網幀中。並向交換機發送該幀,交換機將該幀發送給所有連接的設備(其中包含網關路由器)
  • 網關路由器收到ARP查詢報文,並生成一個ARP回答報文,報文指示其MAC地址 對應IP地址 ,再將該報文封裝進以太網幀中並發送回去。
    在這里插入圖片描述
  • 本地虛擬主機接收到ARP回答報文並從中讀取需要的MAC地址信息
  • 本地虛擬主機已經獲取到全部的DNS查詢所需的信息,所以向DNS服務器發送一條DNS查詢報文

在這里插入圖片描述

DNS流程

  • 本地虛擬主機生成的DNS查詢報文先發送給交換機,再交付給網關路由器,網關路由器從中提取出IP數據報並查找其目的地址,根據轉發表准發給相應的路由器,就這樣一步步的抓發到DNS服務器
  • DNS服務器收到該查詢報文后,從DNS數據庫中查詢image.baidu.com對應的IP地址,然后將DNS回答報文封裝經過以太網發送回本地虛擬主機
  • 本地虛擬主機最終獲得了待訪問的IP地址。

Questions:

  • 為什么已經獲得網關路由器的IP,還要利用ARP獲取其MAC地址 ?
  • DNS封裝在UDP還是TCP內 ? 為什么 ?

封裝在UDP中,因為TCP需要連接,三次握手的過程消耗大量時間等資源,而UDP是無連接的,因此效率更高。而且如果DNS查詢結果的包丟失,由於存在備用DNS服務器,可以繼續查詢,從而大大降低了無連接帶來的風險。

  • 域名到IP的解析遵循什么樣的規則 ?

解析經過:瀏覽器DNS緩存 -> 本地host配置 -> DNS服務器 -> 上層root server
1、host的解析首先是自上而下的
2、同域名多條記錄的時候,首域名記錄(域名a這種)的優先級高於非首域名記錄(域名b/c這種)
3、同樣緊鄰ip的 多條同域名記錄,優先級遵循第一條,且 非127.0.0.1的優先於127.0.0.1的
4、同域名多條記錄且均不緊鄰ip的,遵循第一條
5、0.0.0.0 會產生主機記錄但ping不通,因此不計入優先級計算范圍

階段三:HTTP獲取網頁資源

  • 經過前兩個階段的准備,本地虛擬主機已經獲取到了目的網址的IP,利用這些信息,本地虛擬主機就可以進行TCP的三次握手了。
  • 借助於本地虛擬主機的套接字就可以開始瀏覽網頁了,瀏覽器生成要獲取URL的HTTP GET報文並寫入套接字最終交付給image.baidu.com
  • image.baidu.com的HTTP服務器從TCP套接字讀取HTTP GET報文,然后生成響應報文,將其請求的Web內容放入其中,並寫入套接字
  • HTTP響應報文經過多層轉發,最終到達本地虛擬主機,主機上的瀏覽器從套接字中讀取Web網頁的 html,並最終將內容顯示在屏幕上。
    在這里插入圖片描述
  • 抓包分析上述HTTP相關的TCP三次握手和四次揮手。
    在這里插入圖片描述

為什么上述TCP的四次揮手只被捕捉到三次 ?

因為第二次和第三次合並了,FIN報文用在本端沒有數據發送給對方時,關閉從本端到對端的連接。但是並不影響從對方到本端的連接,也就是說本端仍然可以接收對方的數據。即發送通道關閉,接收通道正常。如果對方收到本端FIN報文時,對方的接收通道就會關閉。此時,如果對方也沒有數據發給本端,那么對方也會發送FIN給本端,用於關閉從對方到本端的連接,這時候就可能出現ACK和FIN合在一起的情況。當然,如果對方仍然有數據發送,那么就等數據發完,再發FIN來關閉連接,這時候就是四次揮手了。

Questions:

  • HTTP協議GET和POST的區別 ?

GET 用於獲取信息,是無副作用的,是冪等的,且可緩存
POST 用於修改服務器上的數據,有副作用,非冪等,不可緩存

  • HTTP無狀態有哪些弊端 ? 如何解決 ?

HTTP是一種無狀態協議,即服務器不保留與客戶交易時的任何狀態。
用戶登錄后,切換到其他界面,進行操作,服務器端是無法判斷是哪個用戶登錄的。 每次進行頁面跳轉的時候,得重新登錄。
解決方法:
1 .Cookie:Cookie 會根據從服務器端發送的響應報文內的一個叫做 Set-Cookie 的首部字段信息,通知客戶端保存 Cookie,當下次客戶端再往該服務器發送請求時,客戶端會自動在請求報文中加入 Cookie 值后發送出去。也就是 Cookie 是服務器生成的,但是發送給客戶端,並且由客戶端來保存。每次請求加上 Cookie就行了。服務器端發現客戶端發送過來的 Cookie 后,會去檢查究竟是從哪一個客戶端發來的連接請求,然后對比服務器上的記錄,最后得到之前的狀態信息。
2 .Session:客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄在服務器上,這就是 Session。客戶端瀏覽器再次訪問時,只需要從該 Session 中查找該客戶的狀態就可以了。雖然 Session 保存在服務器,對客戶端是透明的,它的正常運行仍然需要客戶端瀏覽器的支持。這是因為 Session 需要使用Cookie 作為識別標志。HTTP協議是無狀態的,Session 不能依據HTTP連接來判斷是否為同一客戶,因此服務器向客戶端瀏覽器發送一個名為 JSESSIONID 的 Cookie,它的值為該 Session 的 id(即放在HTTP響應報文頭部信息里的Set-Cookie)。Session依據該 Cookie 來識別是否為同一用戶。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM