8 Replies Latest reply on May 31, 2018 10:59 PM by morphyno

    Traffic filtering using PowerCLI

    vikrambasu Lurker

      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?

        • 1. Re: Traffic filtering using PowerCLI
          LucD Guru
          Community WarriorsvExpertUser Moderators

          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?

          • 2. Re: Traffic filtering using PowerCLI
            vikrambasu Lurker

            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.

            • 3. Re: Traffic filtering using PowerCLI
              LucD Guru
              User ModeratorsCommunity WarriorsvExpert

              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)

              1 person found this helpful
              • 4. Re: Traffic filtering using PowerCLI
                vikrambasu Lurker

                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.

                • 5. Re: Traffic filtering using PowerCLI
                  LucD Guru
                  vExpertCommunity WarriorsUser Moderators

                  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)  

                   

                  1 person found this helpful
                  • 6. Re: Traffic filtering using PowerCLI
                    LucD Guru
                    User ModeratorsvExpertCommunity Warriors

                    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)  

                     

                    1 person found this helpful
                    • 7. Re: Traffic filtering using PowerCLI
                      mattboren Master
                      vExpert

                      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

                      1 person found this helpful
                      • 8. Re: Traffic filtering using PowerCLI
                        morphyno Novice

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