題幹與適用場景
行動客戶端經常切網和重連,團隊希望利用 QUIC 0-RTT 在握手完成前傳送應用資料。服務既有讀取介面,也有扣款、建立訂單和更新權杖等有副作用的操作。
回答要說明 0-RTT 的安全邊界,而不是只說「它更快」。重點是重放、負載平衡、多區域部署和客戶端回退。
面試官考察點
協議事實
候選人應知道 0-RTT 資料缺少完整的重放保護,伺服器不能把它當作已完成認證的 1-RTT 請求。
請求分類
強回答會按副作用、冪等性、時效性和授權狀態分類,而不是按 HTTP 方法名稱機械放行。
分散式防護
需要討論票據、重放視窗、跨節點共享狀態、負載平衡和拒絕後的重試語義。
可驗證性
要能提出攻擊重放測試、指標、日誌脫敏和逐步啟用策略,證明安全性而非依賴設定截圖。
回答前需要澄清的問題
- 哪些介面只讀,哪些介面會寫入帳務或訂單狀態?
- 0-RTT 票據的有效期、簽發範圍和綁定身分是什麼?
- 服務是否跨區域、跨版本部署,節點能否共享重放狀態?
- 客戶端收到 0-RTT rejected 後,是否會自動以 1-RTT 重試?
- 請求是否包含一次性 nonce、冪等鍵或業務版本號?
- 合規或稽核是否要求證明同一請求未被重複執行?
30 秒回答框架
「我先把 0-RTT 視為未完成握手的資料面,只允許無副作用或明確冪等的讀取請求。寫請求預設等待 1-RTT;若業務確實需要提前傳送,就使用短時票據、請求 nonce、共享重放檢測和冪等業務鍵。伺服器拒絕 0-RTT 時,客戶端用同一請求在 1-RTT 重試,並用 request_id 去重。發布前做重放攻擊測試,按介面逐步開啟。」
分步驟深入解答
第一步:建立請求分類
把介面分為只讀、冪等寫、非冪等寫和安全敏感操作。只讀查詢通常可候選;建立訂單、扣款、發獎和權杖輪換預設禁止 0-RTT。即使 PUT 語義冪等,也要檢查序列組合是否產生副作用。
第二步:定義票據與範圍
票據綁定服務、協議版本、客戶端身分範圍和過期時間。不要讓一個環境簽發的票據跨租戶或跨區域無限重用。密鑰輪換後舊票據應快速失效,伺服器記錄拒絕原因。
第三步:設計重放防護
對允許的 0-RTT 請求要求 nonce 或冪等鍵,並在短視窗內做去重。多節點部署可使用區域級共享儲存、帶 TTL 的鍵集合,或把請求限制到能保證一致性的路由。防護狀態不可阻塞主握手路徑。
第四步:處理拒絕與重試
伺服器可拒絕 0-RTT;客戶端必須等待握手完成後以 1-RTT 重試,不能把早期請求和重試當兩次業務操作。回應攜帶 requestid、attempt 和 replaysafe 標記,方便下游去重。
第五步:保護負載平衡與快取
邊緣層只把重放安全的請求轉發到支援 0-RTT 的後端。快取鍵不能包含會變化的票據,私有回應不得被共享快取。跨區域路由切換時,優先降級到 1-RTT,避免重放狀態不一致。
第六步:驗證與漸進發布
在測試環境錄製並重複送出同一 0-RTT 封包,覆蓋不同節點、區域、票據過期和版本升級。先對只讀介面小流量啟用,再觀察拒絕率、重複攔截率、業務副作用告警和握手延遲,最後決定是否擴大範圍。
高品質示範回答
「我不會把 0-RTT 當成通用加速開關。伺服器先維護介面清單:無副作用讀取可啟用;冪等寫只有在業務鍵和 nonce 能保證重複執行結果一致時才考慮;扣款、建立訂單、發放權益和更新權杖一律等 1-RTT。
票據綁定租戶、服務版本和有效期,密鑰輪換讓舊票據盡快失效。允許的請求帶 requestid 與冪等鍵,邊緣和後端在短 TTL 共享集合中檢測重放;無法共享狀態的跨區切換直接拒絕 0-RTT。拒絕後客戶端等待握手完成,以同一 requestid 在 1-RTT 重試,伺服器按 revision 或冪等鍵只保留一次業務效果。
我會用重放封包、並發重放、節點切換、票據過期和版本混跑做攻擊測試,並監控 0-RTT 接受率、拒絕率、重放攔截率、重複業務告警、票據年齡和 p95 首位元組延遲。發布採用只讀介面到低風險寫介面的分階段開關。」
常見錯誤
- 看到 GET 就無條件放行 → 查詢也可能觸發計費或日誌副作用 → 按業務效果分類並審查組合操作。
- 把 0-RTT 當成已認證請求 → 重放者可重複提交早期資料 → 等待 1-RTT 或建立明確的重放防護。
- 只在單機記憶體去重 → 負載平衡後另一節點再次執行 → 使用共享短 TTL 狀態或限制路由並降級。
- 拒絕後重新產生業務鍵 → 1-RTT 重試變成新操作 → 重用 request_id 與冪等鍵。
- 票據長期有效 → 密鑰和權限變化後風險持續 → 綁定範圍、縮短 TTL 並輪換密鑰。
- 只測延遲不測攻擊 → 上線後才發現副作用重複 → 錄製、重放並驗證業務效果只發生一次。
- 把快取和票據混為一談 → 私有回應被錯誤共享 → 快取鍵、授權和 0-RTT 狀態分層設計。
追問及應對
追問一:冪等操作就一定能用 0-RTT 嗎?
不一定。多步組合可能把多個冪等動作組成非冪等序列,還要考慮權限、庫存、配額和外部通知等副作用。必須以業務效果驗證。
追問二:伺服器如何知道請求是否被重放?
可用短 TTL 的 nonce 或 request_id 集合、票據使用視窗和跨節點共享狀態。檢測失敗時寧可拒絕 0-RTT,改走 1-RTT。
追問三:0-RTT 被拒絕後會遺失資料嗎?
應用協議應定義回退。客戶端保留請求,完成握手後以 1-RTT 重試;伺服器透過冪等鍵保證早期嘗試若已生效也不會重複。
追問四:為什麼跨區域部署更難?
重放狀態、票據密鑰和版本可能不同。共享狀態成本高時,應按區域綁定票據,切換區域立即拒絕早期資料。
追問五:如何逐步關閉 0-RTT?
先停止簽發新票據,再讓舊票據自然過期或主動拒絕,觀察拒絕率與回退成功率。保留 1-RTT 路徑和告警,避免客戶端無聲失敗。
來源一:RFC 9001
RFC 9001 說明 0-RTT 缺少重放保護,應用資料必須由應用協議定義可接受的使用方式,不能預設承載有副作用的操作。
來源二:RFC 9308
RFC 9308 說明重放可能讓伺服器多次處理同一資料,並建議限制為無持久效果或冪等操作,同時分析組合操作的風險。
來源三:Algoroq 網路面試指南
公開網路面試指南把 QUIC、0-RTT、低延遲與重放風險放在同一追問鏈中,為本題的面試場景提供依據。