VMware Cloud Community
vikrambasu
Contributor
Contributor

Traffic filtering using PowerCLI

I have been searching for a powercli script to add/update/drop traffic filtering in a Distributed Port Group. After looking through the forums I found something that might work but I am facing some issues.

$dvSwName = 'vDSwitch VDS'

$dvPgNames = 'vCenter Server'

$dvSw = Get-VDSwitch -Name $dvSwName

# Enable LBT

foreach($pg in (Get-View -Id  $dvSw.ExtensionData.Portgroup | Where {$dvPgNames -contains $_.Name})){

    $spec = New-Object VMware.Vim.DVPortgroupConfigSpec

    $spec.ConfigVersion = $pg.Config.ConfigVersion

    $spec.DefaultPortConfig = New-Object VMware.Vim.VMwareDVSPortSetting

    $spec.DefaultPortConfig.FilterPolicy = New-Object VMware.Vim.DvsFilterPolicy

    $filter = New-Object VMware.Vim.DvsTrafficFilterConfig

    $filter.AgentName = 'dvfilter-generic-vmware'

    $ruleSet = New-Object VMware.Vim.DvsTrafficRuleset

    $ruleSet.Enabled = $true

    $rule =New-Object VMware.Vim.DvsTrafficRule

    $rule.Description = 'Traffic Drop Rule'

    $rule.Direction = 'both' #'outgoingPackets'

    $action = New-Object VMware.Vim.DvsDropNetworkRuleAction

   

    $qualifier = New-Object VMware.Vim.DvsIpNetworkRuleQualifier

    $qualifier.Protocol = ${6}

    $qualifier.DestinationAddress = ${ip:192.168.9.97}

    $qualifier.SourceAddress = ${ip:192.168.9.97}

    #$action.QosTag = 4

    $rule.Action += $action

    $rule.Qualifier += $qualifier

    $ruleSet.Rules += $rule 

   

    $filter.TrafficRuleSet = $ruleSet

    $spec.DefaultPortConfig.FilterPolicy.FilterConfig += $filter

    $pg.ReconfigureDVPortgroup($spec)

}

1. This seems to create a Drop rule but the qualifier section does not seem to work. Protocol, DestinationAddress and SourceAddress are not used instead everything is taken as any instead.

How would I resolve this issue ?

2017-12-22 19_07_07-vSphere Web Client.png

2. The allow rule should follow a similar syntax I am assuming?

3. Also how do I remove an existing rule from the traffic filtering ruleset?

15 Replies
LucD
Leadership
Leadership

In the FilterConfig property you specify the rules you want to have.

If there are existing rules you want to remove just leave them out, otherwise copy them.

On the Drop/Accept, that depends on what type of Action object you add to the FilterConfig entries.

It can be DvsDropNetworkRuleAction, DvsAcceptNetworkRuleAction and some others.

Let me know if you need some sample code?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
vikrambasu
Contributor
Contributor

Thanks for the quick response.

So if I do not specify the entire ruleset everytime, old rules will be automatically removed.

In this script I am using the DvsDropNetworkRuleAction to Drop, but I cannot seem to correctly qualify that I only want particular IP addresses to be dropped.

Some sample code for Drop/Accept with qualifiers for Protocol, Address and Port would be much appreciated.

Reply
0 Kudos
LucD
Leadership
Leadership

The following is an example to add two rules to the filter.

A new rule is rather straightforward, there is an Action (Allow, Drop...) and a Qualifier (where you select the traffic)

Note that this script will replace all existing rules on the filter.

Hope this helps.

$vdsSwitchName = 'vds1'

$vdsPGName = 'testpg'

$vds = Get-VDSwitch -Name $vdsSwitchName

$pg = Get-VDPortgroup -Name $vdsPGName -VDSwitch $vds

$spec = New-Object VMware.Vim.DVPortgroupConfigSpec

$spec.ConfigVersion = $pg.ExtensionData.Config.ConfigVersion 

$spec.DefaultPortConfig = New-Object VMware.Vim.VMwareDVSPortSetting 

$spec.DefaultPortConfig.FilterPolicy = New-Object VMware.Vim.DvsFilterPolicy 

# Add rules

$filter = New-Object VMware.Vim.DvsTrafficFilterConfigSpec 

$filter.AgentName = 'dvfilter-generic-vmware'  

$filter.Operation = [VMware.Vim.ConfigSpecOperation]::add

$ruleSet = New-Object VMware.Vim.DvsTrafficRuleset 

$ruleSet.Enabled = $true 

# TCP, 192.168.7.0/24,any,port 512, port 1024, drop

$rule =New-Object VMware.Vim.DvsTrafficRule 

$rule.Description = 'Traffic Drop Rule (added by script 1)' 

$rule.Direction = 'both'

$action = New-Object VMware.Vim.DvsDropNetworkRuleAction 

$qualifier = New-Object VMware.Vim.DvsIpNetworkRuleQualifier 

$qualifier.SourceAddress = New-Object VMware.Vim.IpRange

$qualifier.SourceAddress.AddressPrefix = '192.168.7.0'

$qualifier.SourceAddress.PrefixLength = 24

$qualifier.Protocol = New-Object VMware.Vim.IntExpression

$qualifier.Protocol.Value = 6        # 1 : ICMP, 6 : TCP, 17 : UDP 

$qualifier.DestinationAddress = $null        # $null : any

$qualifier.SourceIpPort = New-Object VMware.Vim.DvsSingleIpPort

$qualifier.SourceIpPort.PortNumber = 512

$rule.Action += $action 

$rule.Qualifier += $qualifier 

$ruleSet.Rules += $rule   

# TCP, 192.168.8.0/16,192.168.9.121,any,1024-2048, allow

$rule =New-Object VMware.Vim.DvsTrafficRule 

$rule.Description = 'Traffic Allow Rule (added by script 2)' 

$rule.Direction = 'both'

$action = New-Object VMware.Vim.DvsAcceptNetworkRuleAction

$qualifier = New-Object VMware.Vim.DvsIpNetworkRuleQualifier 

$qualifier.SourceAddress = New-Object VMware.Vim.IpRange

$qualifier.SourceAddress.AddressPrefix = '192.168.8.0'

$qualifier.SourceAddress.PrefixLength = 16

$qualifier.Protocol = New-Object VMware.Vim.IntExpression

$qualifier.Protocol.Value = 6        # 1 : ICMP, 6 : TCP, 17 : UDP 

$qualifier.DestinationAddress = New-Object VMware.Vim.SingleIp

$qualifier.DestinationAddress.Address = '192.168.9.121'

$qualifier.DestinationIpPort = New-Object VMware.Vim.DvsIpPortRange

$qualifier.DestinationIpPort.StartPortNumber = 1024

$qualifier.DestinationIpPort.EndPortNumber = 2048

$rule.Action += $action 

$rule.Qualifier += $qualifier 

$ruleSet.Rules += $rule   

# Add to Spec

$filter.TrafficRuleSet = $ruleSet 

$spec.DefaultPortConfig.FilterPolicy.FilterConfig += $filter

$pg.ExtensionData.ReconfigureDVPortgroup($spec)


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

vikrambasu
Contributor
Contributor

Thanks @Lucd, this is pretty helpful as a one off script but trying to modify it is causing me some major challenges.

WIth the following script that I can create a Drop rule that blocks all traffic from a particular IP address such as 157.240.14.35 (www.facebook.com).

I can verify this by pinging 157.240.14.35 from the VM which fails.

$vdsSwitchName = 'vDSwitch VDS'

$vdsPGName = 'vmnet1'

$vds = Get-VDSwitch -Name $vdsSwitchName

$pg = Get-VDPortgroup -Name $vdsPGName -VDSwitch $vds

$spec = New-Object VMware.Vim.DVPortgroupConfigSpec

$spec.ConfigVersion = $pg.ExtensionData.Config.ConfigVersion

$spec.DefaultPortConfig = New-Object VMware.Vim.VMwareDVSPortSetting

$spec.DefaultPortConfig.FilterPolicy = New-Object VMware.Vim.DvsFilterPolicy

# Add rules

$filter = New-Object VMware.Vim.DvsTrafficFilterConfigSpec

$filter.AgentName = 'dvfilter-generic-vmware' 

$filter.Operation = [VMware.Vim.ConfigSpecOperation]::add

$ruleSet = New-Object VMware.Vim.DvsTrafficRuleset

$ruleSet.Enabled = $true

# TCP, 192.168.7.0/24,any,port 512, port 1024, drop

$rule =New-Object VMware.Vim.DvsTrafficRule

$rule.Description = 'Traffic Drop Rule (added by script 1)'

$rule.Direction = 'both'

$action = New-Object VMware.Vim.DvsDropNetworkRuleAction

$qualifier = New-Object VMware.Vim.DvsIpNetworkRuleQualifier

$qualifier.SourceAddress = New-Object VMware.Vim.SingleIp

$qualifier.SourceAddress.Address = '157.240.14.35'

$qualifier.DestinationAddress = $null        # $null : any

$rule.Action += $action

$rule.Qualifier += $qualifier

$ruleSet.Rules = $rule

$filter.TrafficRuleSet = $ruleSet

$spec.DefaultPortConfig.FilterPolicy.FilterConfig += $filter

$pg.ExtensionData.ReconfigureDVPortgroup($spec)

But trying to remove this rule by using the script is not working. If I run the same script but comment out

#$ruleSet.Rules = $rule

it seems to remove the rule but I still cannot ping the particular IP address 157.240.14.35.

Evidently there is a different set of code to properly delete any rules that I create.

Can you please provide me that code ?

---------

In addition if I add multiple rules by slightly changing some parts of the code and then try to delete them from the web client I get the following error message

"A specified parameter was not correct: Setting.filterConfig.agentName invalidArg.DuplicateAgentName"

Afterwards I can not longer add/update/delete any traffic filter rules, I need to create a new Distributed port group or restore a fresh configuration that was present before I started adding rules with the script.

Reply
0 Kudos
LucD
Leadership
Leadership

To remove a specific rule from the set, you have to call the same ReconfigureDVPortgroup method, but the operation shall be "edit".

You copy the Ruleset, except the rule you want to remove.

$vdsSwitchName = 'vDSwitch VDS' 

$vdsPGName = 'vmnet1' 

$ruleName = 'Network Traffic Rule 4'

 

$vds = Get-VDSwitch -Name $vdsSwitchName 

$pg = Get-VDPortgroup -Name $vdsPGName -VDSwitch $vds  

 

$spec = New-Object VMware.Vim.DVPortgroupConfigSpec  

 

$spec.ConfigVersion = $pg.ExtensionData.Config.ConfigVersion  

$spec.DefaultPortConfig = New-Object VMware.Vim.VMwareDVSPortSetting  

$spec.DefaultPortConfig.FilterPolicy = New-Object VMware.Vim.DvsFilterPolicy  

 

# Remove rule

$filter = New-Object VMware.Vim.DvsTrafficFilterConfigSpec

$filter.AgentName = 'dvfilter-generic-vmware'

$filter.Key = $tgtFilter.Key

$filter.Operation = [VMware.Vim.ConfigSpecOperation]::edit

$filter.TrafficRuleset = $pg.ExtensionData.Config.DefaultPortConfig.FilterPolicy.FilterConfig[0].TrafficRuleset

$newRules = $filter.TrafficRuleset.Rules | where{$_.Description -ne $ruleName}

$filter.TrafficRuleset.Rules = $newRules

$spec.DefaultPortConfig.FilterPolicy.FilterConfig += $filter 

$pg.ExtensionData.ReconfigureDVPortgroup($spec)  


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

LucD
Leadership
Leadership

Yes, the method allows you more than via the Web Client.

To remove all the filtering rules, you can use the "remove" operation.

$vdsSwitchName = 'vDSwitch VDS' 

$vdsPGName = 'vmnet1' 

 

$vds = Get-VDSwitch -Name $vdsSwitchName 

$pg = Get-VDPortgroup -Name $vdsPGName -VDSwitch $vds  

 

$spec = New-Object VMware.Vim.DVPortgroupConfigSpec  

 

$spec.ConfigVersion = $pg.ExtensionData.Config.ConfigVersion  

$spec.DefaultPortConfig = New-Object VMware.Vim.VMwareDVSPortSetting  

$spec.DefaultPortConfig.FilterPolicy = New-Object VMware.Vim.DvsFilterPolicy  

 

# Remove rule

$tgtFilter = $pg.ExtensionData.Config.DefaultPortConfig.FilterPolicy.FilterConfig[0]

$filter = New-Object VMware.Vim.DvsTrafficFilterConfigSpec

$filter.AgentName = 'dvfilter-generic-vmware'

$filter.Key = $tgtFilter.Key

$filter.Operation = [VMware.Vim.ConfigSpecOperation]::remove

$filter.TrafficRuleset = $tgtFilter.TrafficRuleset

$spec.DefaultPortConfig.FilterPolicy.FilterConfig += $filter 

$pg.ExtensionData.ReconfigureDVPortgroup($spec)  


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

mattboren
Expert
Expert

Greetings, LucD​, vikrambasu-

Looks like you guys have already sorted it out, but as I came across this thread today, I thought that I might add a tidbit here that may help in future traffic filtering/marking rule management -- cmdlets for those rulesets, rules, rule actions, rule qualifiers, etc.:  <vNuggletsPlug> I recently made a PowerShell module for this kind of activity, as we have similar needs.

The module is named "vNugglets.VDNetworking", and you can find it via PowerShell like:

Find-Module vNugglets.VDNetworking

You can save it and/or install it, too (Save-Module or Install-Module, of course). The GitHub repo (https://github.com/vNugglets/vNuggletsPSMod_vDNetworking) has the ReadMe and examples and whatnot. Please enjoy it if you have these needs in the future, and if you see ways to make it better, we'll be watching for pull your requests. </vNuggletsPlug>

Cheers

morphyno
Enthusiast
Enthusiast

Would anyone happen to know the limit of filter rulesets on a port group?

Reply
0 Kudos
Sharantyr3
Enthusiast
Enthusiast

Hello all, @LucD ,

 

I have an issue with your code. We are running vcenter 6.7.

I tried to insert a rule using web client, success.

I successfuly retrieved this rule using powercli and can see it.

Now I run your script to add a different rule not specifying "Operation" (so existing rules would be overwritten).

It works, and I can retrieve the new rule using powercli.

-but-

On the vcenter side, the old rule is still here, not the new one. And I can't add/remove/edit any rules anymore using web client : "A specified parameter was not correct: Setting.filterPolicy.filterConfig[]"

Only way to recover from this is delete all rules via powercli, then the original rule I created using web client is back on command line, and editing rules using web client works again.

Seems like there is a desynchronization between vcenter and vds filters when working with filters via powercli.

Do you see the same behavior ?

I think I am missing something.

I can provide you more infos and screenshots.

 

Thanks for any help

Reply
0 Kudos
LucD
Leadership
Leadership

This might be an issue between the Web Client and the vSphere internals.
I have seen this before  (with Alarms) where you can make a change to vSphere, while the Web Client is not able to display it.

I suggest retrieving the object with PowerCLI and checking what is in Setting.filterPolicy.filterConfig.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Sharantyr3
Enthusiast
Enthusiast

I think I figured it out, thanks to your other snippets of code !

Because I had already existing rules (with web client), your first code adds a new "FilterConfig" object with a new Key, but does not overwrite the previous one.

You already provided the answer in your previous answers, all I had to do was adding :

$tgtFilter = $pg.ExtensionData.Config.DefaultPortConfig.FilterPolicy.FilterConfig[0]
$filter.Key = $tgtFilter.Key

And specifying 

$filter.Operation = [VMware.Vim.ConfigSpecOperation]::edit

 

Sorry for not reading more carefully the first time 😅

Reply
0 Kudos
Sharantyr3
Enthusiast
Enthusiast

A kindly note for future readers as I got stuck a long time on this.

I am building a powercli script to import rules from CSV file and I found out you need to specify the SEQUENCE number in order to this to work !

In my loop on the csv file, I use a simple counter $i and at the end add this :

 

$rule.Sequence = $i
$rule.Action += $action
$rule.Qualifier += $qualifier
$ruleSet.Rules += $rule

 

If you don't do it, the rules will display on web client, but when you click on edit, you get "undefined" as rule name and can't do anything.

 

Hope this helps

Reply
0 Kudos
bohmannR
Contributor
Contributor

Is there a way to just view traffic filtering rules on VDS uplink rather than "add/update/drop" ?

Reply
0 Kudos
Sharantyr3
Enthusiast
Enthusiast

Yes, using the same code LucD provided :

 

$vdsSwitchName = 'VDS' 
$vdsPGName = 'PG' 
$vds = Get-VDSwitch -Name $vdsSwitchName 
$pg = Get-VDPortgroup -Name $vdsPGName -VDSwitch $vds  

$spec = New-Object VMware.Vim.DVPortgroupConfigSpec  
$spec.ConfigVersion = $pg.ExtensionData.Config.ConfigVersion  
$spec.DefaultPortConfig = New-Object VMware.Vim.VMwareDVSPortSetting  
$spec.DefaultPortConfig.FilterPolicy = New-Object VMware.Vim.DvsFilterPolicy  


$filter = New-Object VMware.Vim.DvsTrafficFilterConfigSpec
$filter.AgentName = 'dvfilter-generic-vmware'
$tgtFilter = $pg.ExtensionData.Config.DefaultPortConfig.FilterPolicy.FilterConfig[0]
$filter.Key = $tgtFilter.Key
$filter.TrafficRuleset = $pg.ExtensionData.Config.DefaultPortConfig.FilterPolicy.FilterConfig[0].TrafficRuleset
$Rules = $filter.TrafficRuleset.Rules
Reply
0 Kudos
wolficool
Contributor
Contributor

How i can handle it that i can also edit the Rule in the Webclient?

Maybe you can post the complete code??

Is there a way to add more Rules with these Script?

Reply
0 Kudos