locked
How to block all and selectively enable in WFP based on NAT from User mode? RRS feed

  • Question

  • We have implemented a callout driver which performs as NAT, which works fine

    However I want to selectively allow clients (based on its IP ) to access internet thru the NAT, configured using user mode application. I tried the with  below whitelist sample,

    http://social.msdn.microsoft.com/Forums/en-US/wfp/thread/61349463-516a-4c41-bda3-fa2993d06a0e

    in FWPM_LAYER_INBOUND_IPPACKET_V4, FWPM_LAYER_ALE_AUTH_CONNECT_V4 layer.

    I am not able to block any ip. It's alllowing to share internet for all.

    Can you please suggest, is there any mistakes in below code to block all and selectively enable based on given ip?

    Thanks

    	UINT32   status  = NO_ERROR;
    	HANDLE   engineHandle = 0;
    	const UINT32  NUM_CONDITIONS = 2;
    	FWPM_SESSION  session;
    	FWPM_PROVIDER  provider;
    	FWPM_SUBLAYER  subLayer;
    	FWPM_FILTER_CONDITION pFilterConditions[NUM_CONDITIONS];
    	FWPM_FILTER  blockFilter;
    	FWPM_FILTER  permitFilter;
    	FWP_V4_ADDR_AND_MASK  intranetAddrAndMask;
    
    	ZeroMemory(&session,
    		sizeof(FWPM_SESSION));
    
    	ZeroMemory(&provider,
    		sizeof(FWPM_PROVIDER));
    
    	ZeroMemory(&subLayer,
    		sizeof(FWPM_SUBLAYER));
    
    	ZeroMemory(pFilterConditions,
    		sizeof(FWPM_FILTER_CONDITION) * NUM_CONDITIONS);
    
    	ZeroMemory(&blockFilter,
    		sizeof(FWPM_FILTER));
    
    	ZeroMemory(&permitFilter,
    		sizeof(FWPM_FILTER));
    
    	ZeroMemory(&intranetAddrAndMask,
    		sizeof(FWP_V4_ADDR_AND_MASK));
    
    	session.displayData.name = L"ATH-IS's User Mode Session";
    	session.flags  = 0;
    
    	status = UuidCreate(&(provider.providerKey));
    
    	if(status != RPC_S_OK &&   // 0
    		status != RPC_S_UUID_LOCAL_ONLY) // 1824
    	{
    		// RPC_S_UUID_NO_ADDRESS  // 1739
    		goto HLPR_BAIL_LABEL;
    	}
    	else
    		status = NO_ERROR;
    
    	provider.displayData.name = L"Nalli-IS Provider";
    	provider.flags  = FWPM_PROVIDER_FLAG_PERSISTENT;
    
    	status = UuidCreate(&(subLayer.subLayerKey));
    
    	if(status != RPC_S_OK &&   // 0
    		status != RPC_S_UUID_LOCAL_ONLY) // 1824
    	{
    		// RPC_S_UUID_NO_ADDRESS  // 1739
    		goto HLPR_BAIL_LABEL;
    	}
    	else
    		status = NO_ERROR;
    
    	subLayer.displayData.name = L"Nalli-IS's SubLayer";
    	subLayer.providerKey = &provider.providerKey;
    	subLayer.flags  = 0;
    	subLayer.weight = 0x100;
    
    	status = UuidCreate(&(blockFilter.filterKey));
    
    	if(status != RPC_S_OK &&   // 0
    		status != RPC_S_UUID_LOCAL_ONLY) // 1824
    	{
    		// RPC_S_UUID_NO_ADDRESS  // 1739
    		goto HLPR_BAIL_LABEL;
    	}
    	else
    		status = NO_ERROR;
    
    	status = UuidCreate(&(permitFilter.filterKey));
    
    	if(status != RPC_S_OK &&   // 0
    		status != RPC_S_UUID_LOCAL_ONLY) // 1824
    	{
    		// RPC_S_UUID_NO_ADDRESS  // 1739
    		goto HLPR_BAIL_LABEL;
    	}
    	else
    		status = NO_ERROR;
    
    	// Filter Condition -1
    	pFilterConditions[0].fieldKey  = FWPM_CONDITION_IP_REMOTE_ADDRESS;
    	pFilterConditions[0].matchType  = FWP_MATCH_EQUAL;
    	pFilterConditions[0].conditionValue.type = FWP_UINT32;
    	pFilterConditions[0].conditionValue.int32 = 0xC0A8ADCE; //192.168.173.206
    
    	// Filter Condition -2
    	pFilterConditions[1].fieldKey  = FWPM_CONDITION_IP_REMOTE_ADDRESS;
    	pFilterConditions[1].matchType  = FWP_MATCH_EQUAL;
    	pFilterConditions[1].conditionValue.type = FWP_UINT32;
    	pFilterConditions[1].conditionValue.int32 = 0xC0A8ADCF; //192.168.173.207
    
    	// Block all
    	blockFilter.displayData.name = L"Nalli-IS's Basic Block Filter";
    	blockFilter.flags  = FWPM_FILTER_FLAG_PERSISTENT;
    	blockFilter.providerKey  = &provider.providerKey;
    	blockFilter.layerKey  = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
    	blockFilter.subLayerKey  = subLayer.subLayerKey;
    	blockFilter.weight.type  = FWP_UINT8;
    	blockFilter.weight.uint8 = 0xF;
    	blockFilter.numFilterConditions = 0;
    	blockFilter.filterCondition = 0;
    	blockFilter.action.type  = FWP_ACTION_BLOCK;
    
    	// Allow only specified in the filte condition
    	permitFilter.displayData.name = L"Nalli-IS's Basic Permit Filter";
    	permitFilter.flags  = FWPM_FILTER_FLAG_PERSISTENT;
    	permitFilter.providerKey  = &provider.providerKey;
    	permitFilter.layerKey  = FWPM_LAYER_INBOUND_IPPACKET_V4;
    	permitFilter.subLayerKey  = subLayer.subLayerKey;
    	permitFilter.weight.type  = FWP_UINT8;
    	permitFilter.weight.uint8 = 0xF;
    	permitFilter.numFilterConditions = 2;
    	permitFilter.filterCondition = pFilterConditions;
    	permitFilter.action.type  = FWP_ACTION_PERMIT;
    
    	status = FwpmEngineOpen(0,
    		RPC_C_AUTHN_WINNT,
    		0,
    		&session,
    		&engineHandle);
    	if(status != NO_ERROR)
    		goto HLPR_BAIL_LABEL;
    
    	status = FwpmTransactionBegin(engineHandle,
    		0);
    	if(status != NO_ERROR)
    		goto HLPR_BAIL_LABEL;
    
    	status = FwpmProviderAdd(engineHandle,
    		&provider,
    		0);
    	if(status != NO_ERROR)
    		goto HLPR_BAIL_LABEL;
    
    	status = FwpmSubLayerAdd(engineHandle,
    		&subLayer,
    		0);
    	if(status != NO_ERROR)
    		goto HLPR_BAIL_LABEL;
    
    	status = FwpmFilterAdd(engineHandle,
    		&blockFilter,
    		0,
    		&(blockFilter.filterId));
    	if(status != NO_ERROR)
    		goto HLPR_BAIL_LABEL;
    
    	status = FwpmFilterAdd(engineHandle,
    		&permitFilter,
    		0,
    		&(permitFilter.filterId));
    	if(status != NO_ERROR)
    		goto HLPR_BAIL_LABEL;
    
    	status = FwpmTransactionCommit(engineHandle);
    	if(status != NO_ERROR)
    		goto HLPR_BAIL_LABEL;
    
    HLPR_BAIL_LABEL:
    
    	if(engineHandle)
    	{
    		if(status != NO_ERROR)
    			FwpmTransactionAbort(engineHandle);
    
    		FwpmEngineClose(engineHandle);
    	}

     

     

    Friday, February 18, 2011 9:30 AM

All replies

  • there's a couple of nitpicks with your code, and 1 item which will prevent what you are doing.

    nitpicks:

    Ideally you should use the corresponding data field as the type indicated (being a union, this will not affect the issue you are seeing):

       pFilterConditions[0].conditionValue.int32 = 0xC0A8ADCE; //192.168.173.206
       pFilterConditions[1].conditionValue.int32 = 0xC0A8ADCF; //192.168.173.207

    should be:

       pFilterConditions[0].conditionValue.uint32 = 0xC0A8ADCE; //192.168.173.206
       pFilterConditions[1].conditionValue.uint32 = 0xC0A8ADCF; //192.168.173.207

    The reason you are having problems is you have a BLOCK everything at AUTH_CONNECT_V4.  You then say Allow these 2 addresses at INBOUND_IPPACKET_V4.  This essentially means you will have no outbound initiated traffic. And (assumming these are the only filters on the machine) all traffic will make it inbound.

    If you are trying to achieve only allowing connections to those remote addresses, then you would want to put the PERMIT filters in the same layer as the BLOCK filter  (AUTH_CONNECT) with a higher weight.

    Hope this helps,

     


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------
    Friday, February 18, 2011 7:04 PM
    Moderator
  • thanks
    Monday, February 21, 2011 4:00 AM
  • Thank you for suggestions.

    I have tried with modifications suggested ( int32 ->uint32 and Both BLOCK and PERMIT filters at AUTH_CONNECT_V4 layer) , But still I am not able to block any remote PC accesing internet from the NAT machine.

    I have put both BLOCK and PERMIT filters as weight.uint8 = 0xF. Do I need to increase this value to bigger?

    I am not running any other filter other than NAT driver in my PC.

    Any help ?


    Thank you,
    Nalli.Subramanaym
     

    Monday, February 21, 2011 4:08 AM
  • if hte PC's are remote, then that traffic would never hit the AUTH_CONNECT layer (those layers are from locally initiated connections.  It sounds like you are using the host machine to relay traffic (i.e it comes in on interface X and you want to NAT it out interface Y) is this correct?  If so, you should be sitting at teh IP_FORWARD layers.

    As for weighting, ideally you would set your weight for the generic BLOCK all to the lowest weight, and then the more specific to a higher weight.  You are using semi-autoweight, which will handle this scenario, however for ease of diagnostics, you could move the BLOCK filter to weight.uint8 = 0x1;

    Hope this helps.


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------
    Monday, February 21, 2011 8:15 PM
    Moderator
  • Thank you Dusty for your quick help.

    Yes you are right. I am hosting the network on microsoft virtual mini adapter using softap mode and trying to forward internet traffic coming to it to one of physical network adapter( which has internet) presented in the PC.

    I am able to sucessfully provide the internet service to the clients connected to my hosted softap.

    In this senario, I wanted to block internet to some of the clients connected this softap enviorment. But not able to succeed.

    Now I even tried putting filter at IP_FORWARD layer. Still I am not able to block any system.

    Any help?

    Nalli.Subramanyam

    Tuesday, February 22, 2011 12:03 PM