使用系結或連線重新導向
Windows 篩選平台 (的連線/系結重新導向功能) 可讓應用層強制執行 (ALE) 圖說文字驅動程式,並視需要重新導向連線。
此功能適用于 Windows 7 和更新版本。
注意 在一個CLASSIFYFUNCTIONS_PROXYCALLOUTS.cpp 模組中 ,此驅動程式範例 包含示範連線/系結重新導向的程式碼。
一個有一個一個「一個」「一個」的「一個」連線重新導向圖說文字會重新導向應用程式的連線要求,讓應用程式連線到 Proxy 服務,而不是原始目的地。 Proxy 服務有兩個通訊端:一個用於重新導向的原始連線,另一個用於新的 Proxy 輸出連線。
此為一種不透明資料的緩衝區,在 FWPM_LAYER_ALE_AUTH_CONNECT_REDIRECT_V4 層和 FWPM_LAYER_ALE_AUTH_CONNECT_REDIRECT_V6 層的輸出 Proxy 連線上必須設定此緩衝區,以便重新導向的連線和原始連線以邏輯方式相關。
只有在系結-重新導向層中才支援變更流程的本機位址和埠。 連線-重新導向層不支援此功能。
用於重新導向的圖層
重新導向可由下列層級的圖說文字驅動程式執行,稱為「重新導向層」:
FWPM_LAYER_ALE_BIND_REDIRECT_V4 (FWPS_LAYER_ALE_BIND_REDIRECT_V4)
FWPM_LAYER_ALE_BIND_REDIRECT_V6 (FWPS_LAYER_ALE_BIND_REDIRECT_V6)
FWPM_LAYER_ALE_CONNECT_REDIRECT_V4 (FWPS_LAYER_ALE_CONNECT_REDIRECT_V4)
FWPM_LAYER_ALE_CONNECT_REDIRECT_V6 (FWPS_LAYER_ALE_CONNECT_REDIRECT_V6)
執行重新導向的圖層會決定變更的效果。 連線層的變更只會影響所連接的流程。 系結層的變更會影響使用該通訊端的所有連線。
重新導向層僅適用于 Windows 7 和更新版本的 Windows。 支援這些層級分類的圖說文字驅動程式必須使用 FwpsCalloutRegister1 或更新版本進行註冊,而不是舊版 FwpsCalloutRegister0 函式。
重要
重新導向不適用於所有類型的網路流量。 重新導向支援的封包類型會顯示在下列清單中:
- TCP
- UDP
- 沒有標頭 include 選項的原始 UDPv4
- 原始 ICMP
執行重新導向
若要重新導向連線,圖說文字驅動程式必須取得 TCP 4 元組資訊的可寫入複本、視需要對它進行變更,以及套用變更。 系統會提供一組新的函式來取得可寫入的圖層資料,並透過引擎套用它。 圖說文字驅動程式可以選擇在其 classifyFn 函式中內嵌進行變更,或在另一個函式中以非同步方式進行變更。
實作重新導向的圖說文字驅動程式必須使用 classificationFn1 或更新版本,而不是 將Fn0 分類 為其分類圖說文字函式。 若要使用 classifyFn1 或更新版本,必須呼叫 FwpsCalloutRegister1 或更新版本來註冊圖說文字,而不是舊的 FwpsCalloutRegister0。
若要執行內嵌圖說文字驅動程式的重新導向,必須在 其分類Fn的實作中執行下列步驟:
呼叫 FwpsRedirectHandleCreate0 以取得可用來重新導向 TCP 連線的控制碼。 此控制碼應該快取並用於所有重新導向。 (針對 Windows 7 和更早版本省略此步驟。)
在Windows 8和更新版本中,您必須在圖說文字驅動程式中使用FwpsQueryConnectionRedirectState0函式來查詢連線的重新導向狀態。 這必須完成,才能防止無限重新導向。
呼叫 FwpsAcquireClassifyHandle0 以取得將用於後續函式呼叫的控制碼。
呼叫 FwpsAcquireWritableLayerDataPointer0 以取得 呼叫 classifyFn 之圖層的可寫入資料結構。 將 writableLayerData out 參數轉換成對應至圖層的結構, FWPS_BIND_REQUEST0 或 FWPS_CONNECT_REQUEST0。
從 Windows 8 開始,如果您的圖說文字驅動程式重新導向至本機服務,您必須呼叫FwpsRedirectHandleCreate0以填入FWPS_CONNECT_REQUEST0結構的localRedirectHandle成員,才能讓本機 Proxy 正常運作。
視需要變更圖層資料:
將原始目的地儲存在本機重新導向內容中,如下列範例所示:
FWPS_CONNECT_REQUEST* connectRequest = redirectContext->connectRequest; // Replace "..." with your own redirect context size connectRequest->localRedirectContextSize = ...; // Store original destination IP/Port information in the localRedirectContext member connectRequest->localRedirectContext = ExAllocatePoolWithTag(…);
修改遠端位址,如下列範例所示:
// Ensure we don't need to worry about crossing any of the TCP/IP stack's zones if(INETADDR_ISANY((PSOCKADDR)&(connectRequest->localAddressAndPort))) { INETADDR_SETLOOPBACK((PSOCKADDR)&(connectRequest->remoteAddressAndPort)); } else { INETADDR_SET_ADDRESS((PSOCKADDR)&(connectRequest->remoteAddressAndPort), INETADDR_ADDRESS((PSOCKADDR)&(connectRequest->localAddressAndPort))); } INETADDR_SET_PORT((PSOCKADDR)&connectRequest->remoteAddressAndPort, RtlUshortByteSwap(params->proxyPort));
如果您的圖說文字驅動程式重新導向至本機服務,它應該在 FWPS_CONNECT_REQUEST0 結構的 localRedirectTargetPID 成員中設定 本機 Proxy PID。
如果您的圖說文字驅動程式重新導向至本機服務,它應該在 FWPS_CONNECT_REQUEST0 結構的 localRedirectHandle 成員中設定 FwpsRedirectHandleCreate0 所傳回的重新導向控制碼。
呼叫 FwpsApplyModifiedLayerData0 以套用對資料所做的變更。
在您的 Proxy 服務 (可能位於使用者模式或核心模式) 中,您必須查詢重新導向記錄和內容,如下列範例所示:
BYTE* redirectRecords; BYTE redirectContext[CONTEXT_SIZE]; listenSock = WSASocket(…); result = bind(listenSock, …); result = listen(listenSock, …); clientSock = WSAAccept(listenSock, …); // opaque data to be set on proxy connection result = WSAIoctl(clientSock, SIO_QUERY_WFP_CONNECTION_REDIRECT_RECORDS, redirectRecords, …); // callout allocated data, contains original destination information result = WSAIoctl(clientSock, SIO_QUERY_WFP_CONNECTION_REDIRECT_CONTEXT, redirectContext, …); // extract original destination IP and port from above context
在您的 Proxy 服務 (可能是使用者模式或核心模式) ,您必須在 Proxy 連線通訊端上設定重新導向記錄,如下列範例所示,才能建立新的輸出通訊端:
proxySock = WSASocket(…); result = WSAIoctl( proxySock, SIO_SET_WFP_CONNECTION_REDIRECT_RECORDS, redirectRecords, …);
呼叫 FwpsReleaseClassifyHandle0 以釋放步驟 2 中取得的分類控制碼。
呼叫 FwpsRedirectHandleDestroy0 以終結步驟 1 中取得的控制碼。
若要以非同步方式執行重新導向,圖說文字驅動程式必須執行下列步驟:
呼叫 FwpsRedirectHandleCreate0 以取得可用來重新導向 TCP 連線的控制碼。 (針對 Windows 7 和更早版本省略此步驟。)
在Windows 8和更新版本中,您必須在圖說文字驅動程式中使用FwpsQueryConnectionRedirectState0函式來查詢連線的重新導向狀態。
呼叫 FwpsAcquireClassifyHandle0 以取得將用於後續函式呼叫的控制碼。 此步驟和步驟 2 和 3 是在圖說文字驅動程式 的 classifyFn 圖說文字函式中執行。
呼叫 FwpsPendClassify0 以將分類置於擱置狀態,如下列範例所示:
FwpsPendClassify( redirectContext->classifyHandle, 0, &redirectContext->classifyOut); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
注意
如果您是以 Windows 7 為目標,則必須在不同的背景工作角色函式中執行下列步驟。 如果您的目標是Windows 8或更新版本,您可以從classifyFn內執行非同步重新導向的所有步驟,並忽略步驟 5。
將分類控制碼和可寫入的圖層資料傳送至另一個函式,以進行非同步處理。 其餘步驟會在該函式中執行,而不是 在 callout 驅動程式的 classifyFn實作中執行。
呼叫 FwpsAcquireWritableLayerDataPointer0 以取得 呼叫 classifyFn 之圖層的可寫入資料結構。 將 writableLayerData out 參數轉換成對應至圖層的結構, FWPS_BIND_REQUEST0 或 FWPS_CONNECT_REQUEST0。
從 Windows 8 開始,如果您的圖說文字驅動程式在本機重新導向,您必須呼叫FwpsRedirectHandleCreate0以填入FWPS_CONNECT_REQUEST0結構的localRedirectHandle成員,才能進行 Proxy 處理工作。
將任何注標特定內容資訊儲存在私人內容結構中,如下列範例所示:
redirectContext->classifyHandle = classifyHandle; redirectContext->connectRequest = connectRequest; redirectContext->classifyOut = *classifyOut; // deep copy // store original destination IP, port
視需要變更圖層資料。
呼叫 FwpsApplyModifiedLayerData0 以套用對資料所做的變更。 如果您想要在另一個圖說文字進一步修改資料時重新授權,請設定 FWPS_CLASSIFY_FLAG_REAUTHORIZE_IF_MODIFIED_BY_OTHERS 旗標。
呼叫 FwpsCompleteClassify0 以非同步方式完成分類作業,如下列範例所示:
FwpsCompleteClassify( redirectContext->classifyHandle, 0, &redirectContext->classifyOut); classifyOut->actionType = FWP_ACTION_PERMIT; classifyOut->rights |= FWPS_RIGHT_ACTION_WRITE;
呼叫 FwpsReleaseClassifyHandle0 以釋放步驟 1 中取得的分類控制碼。
處理多個圖說文字的連線重新導向
一個以上的圖說文字驅動程式可能會起始相同流程的連線重新導向。 執行連線重新導向的圖說文字應該注意其他要求並適當地回應。
每當圖說文字畫上分類時,應該設定 FWPS_RIGHT_ACTION_WRITE 旗標。 您的圖說文字應該測試 FWPS_RIGHT_ACTION_WRITE 旗標,以檢查圖說文字傳回動作的許可權。 如果未設定此旗標,您的圖說文字仍然可以傳回 FWP_ACTION_BLOCK 動作,以保留先前圖說文字所傳回 的FWP_ACTION_PERMIT 動作。
在Windows 8和更新版本中,您的圖說文字驅動程式必須查詢連線的重新導向狀態 (,以查看您的圖說文字驅動程式或其他圖說文字驅動程式是否已使用FwpsQueryConnectionRedirectState0函式來修改它) 。 如果圖說驅動程式重新導向連線,或先前由圖說文字驅動程式重新導向,圖說文字驅動程式應該不會執行任何動作。 否則,它也應該檢查本機重新導向,如下列範例所示:
FwpsAcquireWritableLayerDataPointer(...,(PVOID*)&connectRequest), ...);
if(connectRequest->previousVersion->modifierFilterId != filterId)
{
if(connectRequest->previousVersion->localRedirectHandle)
{
classifyOut->actionType = FWP_ACTION_PERMIT;
classifyOut->rights &= FWPS_RIGHT_ACTION_WRITE;
FwpsApplyModifiedLayerData(
classifyHandle,
(PVOID)connectRequest,
FWPS_CLASSIFY_FLAG_REAUTHORIZE_IF_MODIFIED_BY_OTHERS);
}
}
如果連線是本機 Proxy,您的圖說文字驅動程式不應該嘗試重新導向它。
使用連線重新導向的圖說文字驅動程式應該在 ALE 授權連接層註冊 (FWPS_LAYER_ALE_AUTH_CONNECT_V4 或 FWPS_LAYER_ALE_AUTH_CONNECT_V6) ,並檢查下列兩個中繼資料值,以取得設定 FWP_CONDITION_FLAG_IS_CONNECTION_REDIRECTED 旗標的指示:
FWPS_METADATA_FIELD_LOCAL_REDIRECT_TARGET_PID 包含負責重新導向流程之進程的進程識別碼。
FWPS_METADATA_FIELD_ORIGINAL_DESTINATION 包含流程原始目的地的位址。
FWPS_CONNECT_REQUEST0結構包含名為localRedirectTargetPID的成員。 若要讓任何回送連線重新導向有效,此欄位必須填入將負責重新導向流程之程式的 PID。 這是引擎在 ALE 授權連接層上以 FWPS_METADATA_FIELD_LOCAL_REDIRECT_TARGET_ID傳遞的相同資料。
從 Windows 8 開始,Proxy 服務必須使用WSAIoctl對 Proxy 服務的原始端點發出SIO_QUERY_WFP_CONNECTION_REDIRECT_RECORDS和SIO_QUERY_WFP_CONNECTION_REDIRECT_CONTEXT IOCTL。 此外,必須在新的 ( Proxyed) 通訊端上使用 WSAIoctl發出SIO_SET_WFP_CONNECTION_REDIRECT_RECORDS IOCTL。
相關主題
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應