Skip to content

永續性軟體工程: 遠端抓封包實錄

最近因為 10/24 要辦 CNCF Sustainability Week - Taiwan x Green Software Foundation 活動,看了一堆 ESG 相關的治理文章和技術書,因為剛好有些客戶是做跨國生意的,遲早會碰到和被問到這個議題,所以就從比較常接觸網路著手看了一下實務上怎麼做,節能減碳先從少收封包開始

[活動宣傳] CNCF Sustainability Week - Taiwan x Green Software Foundation

大家知道近年碳排放議題風風火火,從早期不知道在幹嘛的,到歐盟從 2023/10 月試運行碳邊境調整機制 (Carbon Border Adjustment Mechanism, CBAM),而美國 2024/1/1 要正式實施 清潔競爭法案 (Clean Competition Act, CCA),要抽碳關稅,目前牌價 55 USD/Kg CO2eq,要用來減少氣候汙染啦(或其他我也不知道的用途?)~

你一定想說這跟技術打工人員啥事,尤其是 Cloud Native 這邊,當你有這個想法的時候,不如就趕快報名 2023/10/24 線下活動!!!,當天有公司會贊助 Pizza,歡迎來吃東西兼聊天

緣起

因為我在 Target VM 是用 RHEL 9.2 進行日常工作,沒有 X.org / Gnome 可以用,有時候要在自己電腦上用 Wireshark 看封包要拉來拉去很不節能減碳,所以為了方便自己和確保資料傳輸安全,就拿出 ssh tunnel + linux pipeline 大法來做。這個方式不需要使用 rpcapd,你只要有 sshd + tcpdump 就可以了

但因為 Azure Egress 方向資料傳輸有算費用,還是要精打細算,順便節能減碳,所以才有這篇文章的誕生

預設狀況下,一個 TCP 封包上限是看 Maximum Segment Size (MSS) 正常狀況下上限為 1460 (MTU 1500 - IP Header 20 - TCP Header 20),先不考慮中間被 MSS clamping,譬如什麼 PPPoE 還是某設備偷改的狀況。若我只是要單純查修網路的話,譬如只是要觀測 TCP Retransmission / Duplicated ACK 等,其實我不需要把全部 Frame 收滿收好才能知道狀況,我只要能收到前段 TCP Header 就可以知道網路行為了,所以預期上只要每個 Frame 收 74 bytes 我就可以觀測狀況了,可以節省 20.45 倍 (1512 / 74) 的網路傳輸和儲存成本

試想如果原先只能監控 1 小時,透過限制 Frame,同樣傳輸和儲存成本,可以監控 20 小時以上,相當具備執行動力

既有架構圖及要點提示

  • a. 內部 WSL2 與外部 Windows 11 環境參數和執行: 因為 WSL 內的環境可以視同於在一台虛擬機上面,包含像 SSH 環境變數、等 PATH 都會跟外部的 Windows 11 不同,故從 WSL2 要對 Windows 11 執行 Wireshark 圖形介面的話,因為預設 WSL2 的 PATH 並沒有跟外部 Windows 11 有相通,所以最快的作法就是要用絕對路徑且 Linux 看得懂 /mnt/c/Program\ Files/Wireshark/Wireshark.exe 執行程式,或者是你把 Windows 11 的那一堆 PATH 塞到 WSL2 也可以
  • b. 愛用 SSH Key: 這個老梗了,請愛用 ssh-copy-id 實踐免密碼登入;如果要做到零信任的話,就把 AAD Identity 掛進去
  • c. DNAT: 基於安全控管和成本考量,我用 DNAT 為主;如果要做到零信任的話,應該要用 Azure Bastion,但這環境我自己用而已,我信任我自己
  • d. tcpdump 需要 root 權限: tcpdump 需要特權才能使用,不然會噴 tcpdump: eth0: You don't have permission to capture on that device 給你看,因為我的 SSH Key 是綁 Normal User,並沒有特別對 root 做什麼設定,我是採用 NOPASSWD: ALL 處理,上班不要學

1. 我全都要收下來!!!

# ssh <Target username>@<Target IP> -p <Target Port> -i <SSH Private Key if have> sudo tcpdump -U -s0 -w - -i <Target Interface> | wireshark -k -i -
ssh [email protected] -p 5566 -i ~/.ssh/wolala-rsa sudo tcpdump -U -s0 -w - -i eth0 | /mnt/c/Program\ Files/Wireshark/Wireshark.exe -k -i -

這個應該是最直覺的做法,但如果你測試的方式有上傳和下載大檔傳輸的時候,保證傳出來超大超胖,不符合本文減碳效益,所以我們需要對這個傳輸進行精煉瘦身,最直覺的方式就是用 tcpdump 內建的參數 -s, --snapshot-length 進行控制,預設狀況下,-s0 是可以收下 252144 bytes,為了相容早期版本的 tcpdump

2. 單純看 TCP 交握為主

# ssh <Target username>@<Target IP> -p <Target Port> -i <SSH Private Key if have> sudo tcpdump -U -s74 -w - -i <Target Interface> | wireshark -k -i -
ssh [email protected] -p 5566 -i ~/.ssh/wolala-rsa sudo tcpdump -U -s74 -w - -i eth0 | /mnt/c/Program\ Files/Wireshark/Wireshark.exe -k -i -

以 IPv4 + TCP 為例, 一個 Frame 組成如下:

  • Ethernet Header = 14 bytes (112 bits)
  • IP Header = 20 bytes (160 bits)
  • TCP Header = 最小 20 bytes (160 bits),建議 40 bytes (320 bits),因為 TCP Header 最小算到 Urgent Pointer 是 20 bytes,但是通常都會有一堆 TCP Option 皆在後面,譬如說像 Window Scale、SACK、MSS 都會放在這邊,所以最大可能會到 40 bytes 或超過
  • TCP Payload 另計

所以以網路團隊,不考慮觀測 TCP Payload,長期收封包分析 TCP Stream 狀況的話,建議設定個 74 bytes (14 + 20 + 40) 以上,才不會有 TCP Header 被截斷的議題發生,也不會收了一堆 TCP Payload 佔據儲存空間和出站流量。而被截斷的封包內容在 Wireshark 會呈現 Packet Size Limited during capture 這是正常狀況

3. 想要看 HTTP Header

# ssh <Target username>@<Target IP> -p <Target Port> -i <SSH Private Key if have> sudo tcpdump -U -s500 -w - -i <Target Interface> | wireshark -k -i -
ssh [email protected] -p 5566 -i ~/.ssh/wolala-rsa sudo tcpdump -U -s500 -w - -i eth0 | /mnt/c/Program\ Files/Wireshark/Wireshark.exe -k -i -

取材至 ByteByteGo - How does HTTPS work? (Episode 6)

我不會用 http filter 去過濾再收,還是收 tcp 為主,後面用 tcp.stream 過濾。這原因是 filter 單用 http 的話,會看不到 http GET / HTTP1.1 之前的 TCP Handshake 中 SYN / SYNACK / ACK 的狀況,大多數狀況都不是程式沒寫好,都是 TCP 那層被某個防火牆擋掉,但看 L7 或只看 HTTP 會看不出來,如下 No. 448, 449, 450 那三個封包

至於 HTTP Header 要多大,我的理解是因服務而定,有些服務或 CDN 會塞一堆 Header 再前面,可以自行調整大小,我這邊就抓一個 500 加減看

4. 單純看 ICMP 為主

# ssh <Target username>@<Target IP> -p <Target Port> -i <SSH Private Key if have> sudo tcpdump -U -s98 -w - -i <Target Interface> | wireshark -k -i -
ssh [email protected] -p 5566 -i ~/.ssh/wolala-rsa sudo tcpdump -U -s98 -w - -i eth0 | /mnt/c/Program\ Files/Wireshark/Wireshark.exe -k -i -

以 IPv4 + ICMP 為例,一個 Frame 組成如下:

  • Ethernet Header = 14 bytes (112 bits)
  • IP Header = 20 bytes (160 bits)
  • ICMP Header = 8 bytes
  • ICMP Data = 最小送出去 56 bytes,ICMP Timestamp 是放在 ICMP Data 裡面的前 8 bytes,但 Wireshark 裡面的 Data 會顯示 48 bytes,但回來的資訊不一定是 56 Bytes 而已,有可能會收到怪怪的封包 (Malformed Packet) 會塞超過這個數字以上

鑒於以上奇怪的狀況總和,若要收到精簡的 ICMP 封包的話,應該是要設定 98 bytes (14 + 20 + 8 + 56) 以上好一點

結論

  1. ssh 真的很萬用
  2. 收封包限制個 Frame Size 500,可以節省 70% 的消耗,還有不亞於全收 (1512) 的觀測效果
  3. 節能減碳,先從參加 CNCF Sustainability Week - Taiwan x Green Software Foundation 開始

Q&A

Q1: 為何不要在 Azure 裡面開 Windows VM,RDP 進去就好?

因為 Windows Server 我不算熟悉,linux 比較香

Q2: 永續性軟體工程 (Sustainability Engineering) 還是雲原生永續性 (Cloud Native Sustainability) 這跟我啥關係?

目前來看,反舉牽扯到永續性 (Sustainability) 的議題,最大目標就是要盡可能減少碳足跡,就算會造成效能變慢、或者是延遲增加,都是可以被接受的。以網路來看,就是盡量減少不必要的網路傳輸或負載,它的附帶效益目前看起來就是降低成本、優化既有技術

Q3: Sustainability 等於成本降低?

嚴格來說,不是對等的,為了要去做 Sustainability 可能要在別的地方投資不少,雖然主要看起來都是跟綠電相關。譬如說,原先服務放在老遠的區域,但為了極端化達到永續性工程,降低不必要的網路傳輸,選擇把 CDN 服務全部開起來,這成本就會花在別的地方了。但目前碳關稅有公開牌價可以推算,說不定算一算真的有個黃金交叉,只是我現在沒精算的很清晰

References