Использование привязки или перенаправления подключения
Функция перенаправления подключения и привязки платформы фильтрации Windows (МПП) позволяет драйверам принудительного применения на уровне приложений (ALE) проверять и при необходимости перенаправлять подключения.
Эта функция доступна в Windows 7 и более поздних версиях.
Обратите внимание , что модуль ClassifyFunctions_ProxyCallouts.cpp в примере драйвера МПП включает код, демонстрирующий перенаправление подключения и привязки.
Выноска перенаправления подключений ВПП перенаправляет запрос на подключение приложения, чтобы приложение подключилось к прокси-службе вместо исходного назначения. Прокси-служба имеет два сокета: один для перенаправленного исходного подключения и один для нового исходящего подключения.
Запись перенаправления МПП — это буфер непрозрачных данных, которые МПП должна установить на исходящем прокси-подключении на FWPM_LAYER_ALE_AUTH_CONNECT_REDIRECT_V4 и FWPM_LAYER_ALE_AUTH_CONNECT_REDIRECT_V6 уровнях, чтобы перенаправленное соединение и исходное соединение логически связаны.
Изменение локального адреса и порта потока поддерживается только в слое привязываемого перенаправления. Эта функция не поддерживается на уровне подключения.
Слои, используемые для перенаправления
Драйверы выноски могут преформировать перенаправление на следующих уровнях, которые называются "слоями перенаправления":
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
- Необработанный UDPv4 без параметра включения заголовка
- Необработанный ICMP
Выполнение перенаправления
Чтобы перенаправить подключение, драйвер выноски должен получить записываемую копию сведений TCP 4-кортежа, внести в него изменения по мере необходимости и применить изменения. Набор новых функций предоставляется для получения записываемых данных слоя и применения его с помощью подсистемы. Драйверы выноски могут вносить изменения в встроенные функции classifyFn или асинхронно в другой функции.
Драйверы выноски, реализующие перенаправление, должны использовать классификациюFn1 или более поздней версии вместо классификацииFn0 в качестве функции выноски классификации. Чтобы использовать классификациюFn1 или более поздней версии, выноска должна быть зарегистрирована путем вызова FwpsCalloutRegister1 или более поздней версии, а не более старых FwpsCalloutRegister0.
Чтобы выполнить перенаправление встроенного драйвера выноски, необходимо выполнить следующие действия в реализации classifyFn:
Вызовите FwpsRedirectHandleCreate0 , чтобы получить дескриптор, который можно использовать для перенаправления TCP-подключений. Этот дескриптор следует кэшировать и использовать для всех перенаправлений. (Этот шаг не указан для Windows 7 и более ранних версий.)
В Windows 8 и более поздних версиях необходимо запросить состояние перенаправления подключения с помощью функции FwpsQueryConnectionRedirectState0 в драйвере выноски. Это необходимо сделать, чтобы предотвратить бесконечное перенаправление.
Вызов FwpsAcquireClassifyHandle0 для получения дескриптора, который будет использоваться для последующих вызовов функций.
Вызовите FwpsAcquireWritableLayerDataPointer0, чтобы получить структуру данных, доступных для записи, для слоя, в котором был вызван классифицируемыйFn. Приведение параметра writableLayerData к структуре, соответствующей уровню, либо FWPS_BIND_REQUEST0 или FWPS_CONNECT_REQUEST0.
Начиная с Windows 8, если драйвер выноски перенаправляется в локальную службу, необходимо вызвать FwpsRedirectHandleCreate0, чтобы заполнить элемент localRedirectHandle структуры FWPS_CONNECT_REQUEST0, чтобы сделать работу локального прокси-сервера.
Внесите изменения в данные слоя по мере необходимости:
Сохраните исходное назначение в контексте локального перенаправления, как показано в следующем примере:
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));
Если драйвер выноски перенаправляется в локальную службу, он должен задать ИДЕНТИФИКАТОР локального прокси-сервера в члене localRedirectTargetPID структуры FWPS_CONNECT_REQUEST0.
Если драйвер выноски перенаправляется в локальную службу, он должен задать дескриптор перенаправления, возвращенный FwpsRedirectHandleCreate0 в элементе localRedirectHandle структуры FWPS_CONNECT_REQUEST0.
Вызовите FwpsApplyModifiedLayerData0 , чтобы применить изменения, внесенные к данным.
В прокси-службе (которая может находиться в пользовательском режиме или режиме ядра), необходимо запрашивать записи перенаправления и контексты, как показано в следующем примере:
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
В прокси-службе (которая может находиться в пользовательском режиме или в режиме ядра), необходимо задать записи перенаправления в сокет прокси-подключения, как показано в следующем примере, чтобы создать новый исходящий сокет:
proxySock = WSASocket(…); result = WSAIoctl( proxySock, SIO_SET_WFP_CONNECTION_REDIRECT_RECORDS, redirectRecords, …);
Вызовите FwpsReleaseClassifyHandle0 , чтобы освободить дескриптор классификации, полученный на шаге 2.
Вызовите FwpsRedirectHandleDebis0 , чтобы уничтожить дескриптор, полученный на шаге 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 или более поздней версии, вы можете выполнить все действия для асинхронного перенаправления из классаifyFn и игнорировать шаг 5.
Отправьте дескриптор классификации и данные уровня, доступные для записи, в другую функцию для асинхронной обработки. Остальные шаги выполняются в этой функции, а не в реализации драйвера выноски classifyFn.
Вызовите FwpsAcquireWritableLayerDataPointer0, чтобы получить структуру данных, доступных для записи, для слоя, в котором был вызван классифицируемыйFn. Приведение параметра writableLayerData к структуре, соответствующей уровню, либо FWPS_BIND_REQUEST0 или FWPS_CONNECT_REQUEST0.
Начиная с Windows 8, если драйвер выноски перенаправляется локально, необходимо вызвать FwpsRedirectHandleCreate0, чтобы заполнить элемент localRedirectHandle структуры FWPS_CONNECT_REQUEST0, чтобы сделать работу прокси-сервера.
Сохраните все сведения о контексте для конкретного выноски в структуре частного контекста, как показано в следующем примере:
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);
}
}
Если подключение подключено к локальному прокси-серверу, драйвер выноски не должен пытаться перенаправить его.
Драйверы выноски, использующие перенаправление подключения, должны зарегистрировать на уровне подключения авторизации 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. Чтобы любое перенаправление подключения к циклу было допустимым, это поле должно быть заполнено идентификатором идентификатора процесса, который будет отвечать за перенаправленный поток. Это те же данные, которые модуль передает на уровнях подключения авторизации ALE, как FWPS_METADATA_FIELD_LOCAL_REDIRECT_TARGET_ID.
Начиная с Windows 8, прокси-служба должна выдавать SIO_QUERY_WFP_CONNECTION_REDIRECT_RECORDS и SIO_QUERY_WFP_CONNECTION_REDIRECT_CONTEXT IOCTLs, используя WSAIoctl, против исходной конечной точки прокси-службы. Кроме того, необходимо выпустить SIO_SET_WFP_CONNECTION_REDIRECT_RECORDS IOCTL с помощью WSAIoctl на новом (прокси-сервере).