前言
來自于朋友分享的一個案例,最后定位的原因是光貓問題,而類似這類的設備所產生的網絡問題,也曾碰到過兩三次,但這一次的數據包現象挺特別,分析思路和過程也有所不同,故記錄分享一下。
問題背景
用戶所反饋的故障現象就是網頁打不開,經過現場工程師的初步排查及整理,反饋如下:
- 用戶使用光貓的 Wifi 訪問個別公網域名打不開;
- 用戶使用有線網絡訪問沒有問題;
- 網絡拓撲示意:筆記本終端 -> 光貓 -> 交換機 -> 互聯網設備;
- 其中光貓簡單看成是無線路由器,Wifi+DHCP+Nat;
- 捕獲數據包的節點:筆記本終端、光貓出口和互聯網出口。
問題分析
筆記本終端
既然是筆記本終端打不開域名的故障現象,那么就可以先從筆記本捕獲數據包開始入手。客戶端 IP 192.168.0.1 和服務器端 IP 222.1.1.1 在標準的 TCP 三次握手和 TLS 握手完成之后,可見正常傳輸了一段時間后出現了大量的異常,通過專家信息統計,也可以看到出現了包括疑似虛假重傳/重傳,以及 Dup ACK 等問題。
直接跳轉至異常處,可以看見從數據包 No.101 開始至最后,連續出現了 TCP Spurious Retransmission
+ TCP Dup ACK
的問題組合。
實際上有經驗的工程師單從客戶端的捕獲文件,就已經可以初步判斷出現了什么問題,說明如下:
- 因為是在客戶端 192.168.0.1 本地抓包,所以從服務器端發給客戶端的數據分段,如果出現
TCP Spurious Retransmission
標識,說明在之前客戶端曾經收到過同樣 Seq Num 的數據分段,并響應了 ACK ,所以當再次收到相同 Seq Num 的數據分段時,會標記成 TCP 虛假重傳(所表達的意思就是:我收到了,也確認過了,但你還發同樣的數據,所以我認為是虛假重傳,我不需要);
- 由于客戶端收到了所謂的重復數據分段,因此也不能默默承受不做些什么,所以每收到一個重復數據分段,它就會響應一個 Dup ACK,其中 ACK Num 91925,表明說已經確認收到了 Seq Num 91925 之前的所有數據分段,希望下一次接收 Seq Num 從 91925 開始的數據分段,所以 No.101-106 6 個 TCP 數據分段對應 No.107-112 6 個 TCP Dup ACK,而再往后一樣的重復現象,3 個 TCP 數據分段對應 3 個 TCP Dup ACK;
- 但為什么服務器端會一直重傳報文呢?實際上如果能在服務器端上抓包,就會很明顯的發現,在這段異常期間,在服務器端是收不到客戶端所發送的 ACK 數據包,既然服務器端正常發送了數據分段,在超時時間內沒有收到 ACK 確認,因此就會產生重傳。
因此故障的根本原因是客戶端的 ACK 無法傳輸至服務器端,導致服務器端無法正常發送之后的數據,因此反映在客戶端應用現象上,就是打不開訪問的域名。
一般來說類似的問題可能就這樣結束了,因為訪問公網域名走的互聯網環境,很難有中間網絡的權限和排障信息,客戶端發了,服務器端沒收到,丟在中間網絡了,丟在哪,無從得知。但由于現場工程師也同時捕獲了本地其他兩個節點的數據包文件,光貓出口和互聯網出口,因此也就可以繼續分析一波。
互聯網出口
先看互聯網出口數據包文件,客戶端 IP 111.1.1.1(互聯網設備 SNAT)和服務器端 IP 222.1.1.1,仍是在文件最后出現了一堆異常。
根據數據包所顯示的異常現象,結合上述客戶端分析,說明如下:
- No.74 為最后一次看到的從客戶端發送給服務器端的 ACK ,其 Seq Num 為 63335;
- 服務器端實際所發送的數據分段,其 Seq Num 已經到了 91925;
- No.74 客戶端 ACK 正常傳輸到了服務器端,由于沒有包括 SACK 以及 3 個 Dup ACK 的支撐,服務器端一直等到 RTO 超時后,才進行了 No.86 Seq Num 63335 至之后的所有數據分段的超時重傳。
該數據包文件的異常現象,說明在本地的互聯網出口時就已經沒有捕獲到客戶端發給服務器端的 ACK 數據包,ACK 丟失在內部網絡,而不是互聯網,因此繼續研究下一個捕獲節點,光貓出口。
光貓出口
光貓出口數據客戶端 IP 10.1.1.1(光貓 SNAT)和服務器端 IP 222.1.1.1,直奔異常處,可以看到數據包現象與在客戶端上所捕獲的數據包現象基本一致,光貓出口有 ACK,而互聯網出口 無 ACK,初步說明 ACK 丟失在光貓至互聯網出口中間的網絡上。
除了已有的三個數據包文件之外,在沒有其他輸入信息的情況下,需要繼續深入光貓出口數據包文件,找尋下可能的問題原因。
大多數情況下的問題,在數據包上都會或多或少有些跡象。通過觀察服務器端發送數據分段的重傳現象,會發現是從 Seq Num 63335 開始,說明客戶端所響應的 ACK 都沒有正常返回至服務器端,因此可以過濾源 IP 為客戶端 10.1.1.1 的數據包,如下。
可以看到相關的異常數據包現象,說明如下:
- 同樣是客戶端源 IP 10.1.1.1 發送的 ACK,但從 No.79 開始,ACK Len 長度由之前的 68 變為了 122,而 TCP Len 均為 0;
- 最后一個 Len 為 68 的 ACK 是 No.73,它的 ACK Num 即為 63335,所以之后 Len 為 122 的 ACK 都發生了問題,沒有正常到達服務器端;
- 而從 No.107 開始之后的 ACK 數據包,ACK Num 均為 91925,全部標識為 Dup ACK,說明收到了重復的數據分段,也就是上圖中的 No.101 開始的 TCP 虛假重傳數據分段。
TCP Len 為 0 的純 ACK ,為什么整個數據包長度會由 68 變成了 122,通過對比 No.73 和 No.79 兩個 ACK 數據包詳情發現了問題所在,除了正常 ACK 滿足數據幀最小長度 64 字節所填充的 Padding 全 0 數據之外,在 No.79 這個異常 ACK 中又多出現了一段 Trailer 全 0 數據,長度為 54 字節。
因此從 No.79 開始所出現的 Len 為 122 的 ACK 異常數據包,也就是被光貓額外填充了 54 字節的全 0 數據,在到達互聯網出口設備的這一段路徑上,發生了丟棄。
問題總結
將這個現象反饋至現場后,進一步排查,發現在光貓至互聯網出口設備之間,還有一個防火墻設備,通過檢查和測試,確認了是防火墻設備的包長度檢測功能阻斷了這些異常 ACK ,至此找到了導致問題發生的根本原因,詭異的光貓,不是嘛 🙄