先把內外映射寫完整
NAT會改寫封包的地址或port,因此只用一側的來源port追交易很容易誤認設備。追蹤鍵至少包含內側五元組、外側五元組、時間範圍、connection epoch與request_id。五元組是來源地址、來源port、目的地址、目的port和傳輸協定。
示意:內側10.0.0.10:51000連到外側服務192.0.2.10:502,NAT把來源改成198.51.100.7:62001後轉送。重連可能建立新的映射198.51.100.7:62002;62001和62002不是兩個設備,也不能把62001當固定設備ID。
同一established TCP連線中,若觀察到來源port改變,不能當作透明的原連線遷移。一般NAT映射是連線狀態的一部分;映射過期、設備重啟或路徑改變後,通常需要重新建立TCP連線。是否支援特殊遷移要看實際協定,不可自行推定。
request_id由應用層提供,connection epoch由本端每次重連或通道重建時遞增;兩者用途不同。request_id追單次請求,epoch隔離舊callback或舊連線結果,不能只靠NAT外部port代替其中任何一個。
用時間線串兩側日誌
建立join表時保存:t1內側送出、t2 NAT轉換、t3外側服務收到、t4外側回覆、t5 NAT反向轉換、t6內側收到。每筆附介面、方向、內外五元組、epoch、request_id和封包摘要。時間必須可比較,至少記錄時鐘來源與可能誤差。
案例一:epoch=7、request_id=R41,內側10.0.0.10:51000經映射到198.51.100.7:62001,服務回覆後內側收到,六個時間點能以NAT log和兩側capture對齊。案例二:重連後epoch=8使用62002,R41的晚到回覆若帶舊連線證據,不得交給epoch=8的新pending。
若外側服務看到62001但內側日誌只記51000,沒有映射表就無法可靠join。若NAT log顯示映射已expire,外側晚到封包可能被丟棄;此時需核對是否應重建TCP;原應用請求若結果不明,先核實而不自動重送寫入。
TLS加密會限制應用payload的可見性。仍可追TCP五元組、NAT映射、握手、時間和加密連線識別,但不能從中間設備直接讀出request_id或功能內容;若需要應用關聯,應在端點安全記錄request_id和結果摘要。
若端點日誌使用UTC而NAT設備使用本地時間,先保存時區和校時誤差,再以可容許窗口join。時間差太大時不要硬把相鄰事件配成同一交易;先修正觀測基礎,否則會把兩次重連誤判為一次。
映射表中的方向也要保留。內側送出的SNAT與回程的反向DNAT不是兩筆獨立交易;把方向欄漏掉,可能將回覆誤認為另一個來源建立的新連線。
服務port固定不代表外側來源port固定。若負載平衡器、代理或第二層NAT存在,還要保存每一層映射和下一跳識別,否則只看最外側62001無法定位哪一層改寫或丟棄。
重連 過期與追蹤陷阱
NAT映射通常有閒置逾時。heartbeat或應用資料可能延長映射,但不能保證服務端應用健康;映射存在也不代表請求完成。若連線重建,先封存舊pending的已知或不明結果、遞增epoch,再以新五元組管理連線;新業務用新request_id,原請求的受控冪等重試保留原request_id,並保存舊映射的終止原因。
不能以外側port當設備身份:多個內側設備可能共享一個外部地址,外側port也會回收重用。設備身份應由授權的內側識別、憑證、應用註冊或端點紀錄提供;NAT欄位只用來重建傳輸路徑。
排查時若只看到外側62002,先查是否有新epoch和新TCP SYN;若沒有新握手卻宣稱port改變,查capture位置、NAT日誌時間、負載平衡或其實是另一條連線。若TLS正常但應用request_id缺失,查端點日誌關聯,不要解密或猜測payload。
正常結果是R41在epoch=7對應62001並收到回覆,重連後R42在epoch=8對應62002。失敗結果是把62002當設備ID,或把epoch=7晚到回覆交給epoch=8;前者身份錯,後者交易錯,兩者都要分開記錄。
驗收與適用限制
離線驗收至少測:固定映射、重連換port、映射expire、NAT設備重啟、兩設備共享外部地址、晚到回覆、TLS加密、兩側時鐘偏移、capture少一側,以及request_id相同但epoch不同。每列核對五元組、時間、映射、epoch和最終交易狀態。
驗收資料要避免把完整敏感payload存進多處log;使用摘要、長度和受控request_id即可。原始封包與NAT表屬於授權的網路證據,保存期限和存取權限要按專案規格處理。本文不建議為排查而任意改NAT逾時或放寬網路。
RFC、Microsoft或AWS文件可說明一般TCP、NAT與雲端狀態防火牆行為,但不能替現場路由、NAT產品、TLS終端或Q系列PLC通訊模組決定實作。本文案例已核對。
若沒有可信的兩側時間和映射紀錄,結論應停在「無法join」,先補可觀測性。不要以單一port、單一畫面或單一TLS連線狀態宣稱交易已完成。
完成join後仍要回到端點結果確認request_id是否真的完成;傳輸路徑一致只表示封包可追,不表示應用動作成功。
常見問題
若一筆交易跨越代理、NAT和TLS終端,應分段標示每層責任:哪一層看得到request_id、哪一層只能看加密流量、哪一層負責重連。不要把代理回覆時間直接當成設備完成時間,除非端點結果有明確關聯。
NAT映射資料也要設定保存期限與存取權限。過期後只能說找不到歷史映射,不能補猜外部port;若交易仍重要,應由端點保存已驗證的request_id與結果,而不是依賴網路設備永久保留。
當兩側capture只差一個封包時,先查過濾器、硬體卸載、介面鏡像和時間偏差,再推論NAT丟包。對加密連線可用握手和長度趨勢輔助,但不把流量形狀當成應用內容證據。
追蹤表也要標明資料來自端點、NAT或中間代理,並記下可信程度。不同來源互相矛盾時保留兩者和時間差,交由網路管理者確認,不以一側日誌覆蓋另一側證據。
若只剩外側封包而沒有內側或端點紀錄,結論應停在映射存在或封包抵達某觀測點,不能延伸成設備已執行交易。
問:外側62001變62002代表換了一台設備嗎?答:不代表;NAT外部port可能因重連或映射回收改變,不能當設備ID。
問:同一TCP連線中port改了可以繼續用嗎?答:不能自行假設透明遷移;一般映射狀態改變通常要重建連線,依產品與協定驗證。
問:TLS加密後還能追交易嗎?答:可追五元組、時間、映射、epoch和端點request_id,但中間設備不能直接讀payload。
問:只保留NAT log夠嗎?答:不一定;要與兩側時間、capture、端點日誌和request_id join,否則可能無法分辨重連和晚到回覆。
參考:IETF RFC 5382 NAT行為需求,作為NAT映射、端點與逾時概念的協定參考;實際設備行為仍需查產品文件。
參考:AWS NAT Gateway官方文件,作為NAT gateway連線、映射與逾時排查的雲端參考;不代表現場NAT或PLC API。