【翻譯】ietf-quic-draft-24: 8. Address Validation

英文原文鏈接:8. Address Validation

  地址有效性被 QUIC 用於防止流量放大攻擊。在這種攻擊下,攻擊者使用受害者的地址作爲包的源地
址併發送給服務端。如果服務端生成更多或者更大的包作爲攻擊包的響應,攻擊者則可以利用服務端向受
害者發送更多的數據,這些數據量比攻擊者發送的數據量要大。
  放大攻擊的主要防禦手段就是驗證能接收包的端點的傳輸層地址的有效性。地址有效性驗證是在連接
建立階段(詳見 8.1 小節)或連接遷移階段(詳見 8.2 小節)完成的,

8.1. Address Validation During Connection Establishment

  連接的建立隱式地爲兩端提供了地址有效性驗證,接收到一個用握手的密鑰保護的包意味着客戶單接收
到了從服務端發送的 Initial 包。一旦服務端成功處理了一個客戶端發送的 Handshake 包,那麼它
可以認爲客戶端的地址已經被驗證爲有效。
  在驗證客戶端的地址有效之前,服務端不可以發送超過它接受到的數據的三倍大小的數據;這限制了
任何通過僞造源地址進行放大攻擊的攻擊強度;在確定這個限制值時,服務端只需要計算已經成功處理
的包的總大小。

  客戶端必須保證包含 Initial 包的 UDP 報文至少有 1200 字節的載荷,可通過填充來達到該大
小。客戶端發送填充的報文可以確保服務端不會過度受到放大限制的約束。
  包丟失,尤其是服務端的 Handshake 包丟失,會造成服務端無法發送數據,假設此時服務端還沒
達到發送上限且客戶端也沒有數據發送;爲了避免造成握手死鎖發生,客戶端應該在探測超時時發送一個
包,如 [QUIC-RECOVERY] 所述。如果客戶端沒有重傳數據並且也沒有 Handshake 密鑰,它應該發送
一個包含 Initial 包的 UDP 報文,報文載荷至少爲 1200 字節;如果客戶端有 Handshake 密鑰,
則它應該發送一個 Handshake 包。 

  服務端也許希望在開始加密握手之前驗證客戶端地址的有效性;QUIC 在完成握手之前,會使用包含在
Initial 包中的令牌來提供地址有效性驗證,這個令牌在連接建立階段通過 Retry 包(
詳見 8.1.1 小節)傳輸給客戶端,或者在之前的連接上通過 NEW_TOKEN 幀(詳見 8.1.2 小節)來
傳輸給客戶端。
  除了在地址驗證之前強制限制發送的數據量,服務端還會被擁塞控制限制可以發送多少數據;
而客戶端只被擁塞控制限制。

8.1.1. Address Validation using Retry Packets

  一旦收到客戶端的 Initial 包,服務端可以通過發送包含令牌的 Retry 包來請求客戶端地址有效性
驗證;客戶端在收到這個 Retry 包後必須將該令牌附加待發送的 Initial 包中(同一條連接)。服
務端在收到帶有令牌的 Initial 包時,可以選擇中止連接,或者允許該包被繼續處理。

  只要攻擊者不可能爲它自己的地址生成一個有效的令牌,那麼合法客戶端就可以通過返回服務端
的令牌來向服務端證明自己的合法性。

  服務端可以使用 Retry 包來使狀態延後轉移,這增加了連接建立的處理成本。要求服務端提供一
個不同的連接 ID 以及傳輸參數 original_connection_id(18.2 小節所定義),將強制服務端證明
自己或與自己交互的實體接收到了客戶端的原始 Initial 包(譯者注:否則任何實體都可以更換連接 
ID)。 Retry 包的使用見下圖:

8.1.2. Address Validation for Future Connections

  服務端可以在一次連接中爲客戶端提供一個用於驗證地址有效性的令牌,這個令牌也可用於隨後的連接。
地址有效性驗證對 0-RTT 尤其重要,因爲服務端可能會向客戶端發送大量的數據來響應 0-RTT 數據。

  服務端使用 NEW_TOKEN 幀(詳見 19.7 小節)向客戶端提供一個驗證地址有效性的令牌,這個令牌可
以用於隨後的連接。客戶端必須在後續連接的 Initial 包中包含這個令牌來驗證地址的有效性,除非收到一
個用於替換舊令牌的 Retry 包,客戶端不可以在後續連接中使用從 Retry 包中獲取的令牌;服務端可以丟
棄未帶合法令牌的 Initial 包。

  令牌需要以這樣的方式去構造,即允許服務端區分它是否來自 Retry 包。

  令牌不可以包含未加密的特殊信息,這些信息可以被監聽者利用並將令牌與連接關聯起來。例如,它不
能包含連接 ID,或者地址信息,除非這些信息是加密的。

  不像在 Retry 中創建的令牌,其他令牌在創建到被使用有一段時間差。因此,令牌應該有一個過期時間,
可以是一個明確的過期時間,或者是一個可以用於動態計算過期時間的時間戳。服務端可以存儲這個過期
時間,或者把過期時間加密在令牌中。

  客戶端的兩條連接不會共用同一個端口,因此驗證端口是不可能成功的。

  如果客戶端從之前連接的 NEW_TOKEN 幀收到一個令牌,並且客戶端認爲之前連接與當前連接是同樣
的服務端,那麼它應該把收到的這個令牌包含在 Initial 包的 Token 域,這樣可以減少一個用於驗證客戶端
地址的 RTT。

  令牌允許服務端將創建令牌的連接和使用該令牌的連接建立關聯。客戶端如果不想繼續使用某個服務端
的令牌,可以丟棄從 NEW_TOKEN 獲取的令牌。從 Retry 包中獲取的令牌必須在當前嘗試建連時被立即
使用,而不應在後續的嘗試建連時被使用。

  客戶端不應該在不同連接中複用一個令牌。複用令牌將允許網絡鏈路中的節點將連接和令牌建立關聯
(詳見 9.5 小節)。客戶端不可以複用一個令牌除非它相信本端在最後一次使用令牌後發生了網絡切換
(本地 IP 或網卡改變)。客戶端需要重新啓動連接,如果在握手完成前發生了   本地地址的任何改變。

  客戶端可能在一條連接上收到多個令牌。假如不討論令牌與連接的關聯性問題,任何令牌是可以用於任
何嘗試建連的過程。服務端可以發送額外的令牌來使得多個嘗試建連的地址有效,或者替換舊的已失效令
牌。對於客戶端來說,這樣的二義性意味着發送最近未使用的令牌是更高效的做法。即使保存使用舊的令
牌沒有負面影響,客戶端可以認爲在向服務端驗證地址有效性時,舊令牌的價值會比較小。

  當服務端接收到帶有驗證地址有效性的令牌的 Initial 包時,它必須嘗試驗證令牌的合法性,除非它
已經完成了地址有效性驗證。如果令牌是非法的,服務端應該認爲客戶端的地址無效,並可能發送一個
Retry 包。如果地址有效性驗證成功,服務端應該允許握手繼續進行。

    注意:把客戶端當成是無效的而不是直接把包丟棄的根本原因在於,客戶端也許在之前的連接上通過 
  NEW_TOKEN 幀接收了令牌,如果服務端丟失了狀態信息則無法驗證另外的有效性,如果丟棄了包那
  麼會導致連接失敗。服務端應該把 NEW_TOKEN 幀和 Retry 包中的令牌按不同的方式編碼,而且對於 
  Retry 包中的令牌的驗證需要更加嚴格。

  在一個無狀態設計中,服務端可以使用加密認證的令牌來向客戶端傳遞隨後在服務端可以恢復的信息,
也可以使用這樣的令牌來驗證客戶端地址的有效性。令牌未被集成到加密握手中,因此它們未被認證。
例如,客戶端可以重複使用一個令牌;爲了相關攻擊利用這個特性,服務端    可以限制令牌只包含用於
驗證客戶端地址的信息。

  攻擊者可以重放令牌從而使服務端作爲 DDOS 攻擊的放大器。爲了免受這類攻擊的傷害,服務端應該
確保通過 Retry 包發送的令牌只在較短的一段時間內有效。通過 NEW_TOKEN 幀(詳見 19.7 小節)提
供的令牌可以有較長的有效期,但不應該在一段較短的時間內被接受多次。如果可能的話,鼓勵服務端
只允許令牌的有效次數爲一。

8.1.3. Address Validation Token Integrity

  驗證地址有效性的令牌必須難以被猜到,在令牌中包含一個足夠大的隨機值可以保證這一點,但需要服
務端記住發給某個客戶端的隨機值。
  
  基於令牌的方案允許服務端將與地址有效性驗證的狀態轉移到客戶端。爲了是這種設計能夠起作用,令
牌必須被完整性保護防止被客戶意外端修改或者篡改。沒有完整性保護的話,惡意客戶端可以生成或者猜
到可以被服務端接受的隨機值。只有服務端會要求訪問令牌的完整性保護密鑰。
  
  不需要爲令牌單獨指定一個格式,因爲令牌既由服務端生成,又由它自己消費。令牌可以包含客戶端的
地址信息(IP 和 端口)、時間戳以及服務端在驗證令牌有效時需要的任何信息。

8.2. Path Validation

  在連接遷移(詳見 9.6 小節)的時候正在遷移的一端會使用路徑有效性來確認一個新的本地地址到對端
的可達性。在路徑有效性驗證中,端點會測試一個特定的本地地址與一個特定的對端地址的可達性,地址
是 IP、端口的兩元組。
  
  路徑有效性會測試能發送包到對端並且能從對端收到包。重要的是,它會驗證從遷移端收到的包沒有攜
帶僞造的源地址。

  任何一端都可以在任何時候驗證路徑有效性,比如,一個端點可以檢查對端在一段靜默期後是否仍然
是它原來的地址。

  路徑有效性並不是被設計爲一種 NAT 的穿透機制,儘管路徑有效性對於建立支持穿透的 NAT 綁定來
說是高效的,但預期是對端在沒有先發送包的情況下可以收到包。高效的 NAT 穿透需要額外的同步機
制,而這種機制在這裏並沒有提供。

  端點可以把 PATH_CHALLENGE 和 PATH_RESPONSE 幀與其他幀組合發送。特別地,端點可以填
充攜帶 PATH_CHALLENGE 幀的包來發現 PMTU,也可以將 PATH_RESPONSE 與它自己的 
PATH_CHALLENGE 組合發送。

  當探測新的路徑的時候,端點希望保證對端有一個沒有使用的連接 ID 來發送響應。端點可以在同一個
包中發送 NEW_CONNECTION_ID 和 PATH_CHALLENGE 幀,這可以保證對端有一個未使用的連接
ID 用於發送響應。

8.3. Initiating Path Validation

  端點在被驗證的路徑上發送包含一個隨機值的 PATH_CHALLENGE 幀來驗證路徑的有效性。
  
  端點可以發送多個 PATH_CHALLENGE 幀確保被送達對方,然而,端點不應該在同一個包中發送多個
PATH_CHALLENGE 幀。端點也不應以高於 Initial 的頻率發送 PATH_CHALLENGE 幀,這樣可以確保
連接遷移不會在新路徑上增加連接建立的成本。

  端點必須在每一個 PATH_CHALLENGE 幀中使用不可預測的數據,從而可以將 PATH_CHALLENGE 幀
與對端的響應關聯起來。

8.4. Path Validation Responses

  在收到 PATH_CHALLENGE 幀時,端點必須立即通過 PATH_RESPONSE 幀回顯 PATH_CHALLENGE 
幀中的數據。
  端點最多可以爲每一個 PATH_CHALLENGE 幀響應一個 PATH_RESPONSE 幀(詳見 13.3 小節)。
對端發送多個 PATH_CHALLENGE 幀是爲了確保可以收到 PATH_RESPONSE 幀。

8.5. Successful Path Validation

  一個新的地址只有在收到 PATH_RESPONSE 幀時被認爲是有效地,且該幀必須包含之前 
PATH_CHALLENGE 幀的數據。收到包含 PATH_CHALLENGE 幀的包的確認並不足以證明路徑有效,
因爲這個確認可以被一個惡意的端點僞造。

8.6. Failed Path Validation

  驗證路徑有效只有在嘗試驗證的一方主動放棄時纔會失敗。

  端點應該基於定時器來主動放棄驗證路徑有效,在設置這個定時器時,實現需要考慮到新的路徑的 RTT 可
能比原來路徑的長,建議設爲當前 PTO 三倍大小的值與 QUIC-RECOVERY 中定義的初始超時值
(2*kInitialRtt)的較大值,即:
   validation_timeout = max(3*PTO, 6*kInitialRtt)
 注意,端點可以在新的路徑接收包含其他幀的包,但爲了成功驗證路徑有效,PATH_RESPONSE 幀以及合
 適的數據是需要的。

  當端點主動放棄驗證路徑有效時,即認爲該路徑不可用。這不一定意味着是一個連接失敗,端點可以繼續
在其他路徑發送包。如果沒有可用的路徑,端點可以等待直到有一個新路徑可用,或者關閉連接。
  
  除了失敗還有其他原因導致放棄驗證路徑有效。主要是當一個連接開始遷移到新的路徑時,一箇舊路徑有
效性的驗證正在處理。

相關鏈接

QUIC-RECOVERY

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章