Chapter 13
Hardening the vSphere Environment

In this chapter, you will learn to:

  • Use the Hardening Guides
  • Work with the Guidelines
  • ESXi Hosts
  • Virtual Machines
  • vNetwork
  • vCenter Server
  • Bring It All Together

Hardening a system involves closing the potential security holes. Examples of security holes include unnecessary software and user accounts, unused services, and unused network ports. Hardening a system improves the security of that system by decreasing the number of potential attack vectors. Don’t risk running an insecure system, unless you run a completely isolated system or you simply do not care if the system becomes compromised. And, don’t forget that there are many legal requirements that oblige you to secure your systems.

If you had to discover all of the potential risks and harden your vSphere environment from scratch, you would be facing a tremendous task. Thankfully, we need not undertake such a huge task on our own. Since vSphere 4.0, VMware has published Security Hardening Guides (www.vmware.com/security/hardening-guides) that list most, if not all, of the potential holes. The Hardening Guides not only list the potential holes, but also show you actions you can take to close those holes.

Use the Hardening Guides

You can use the Hardening Guides to, well, guide you as to the settings and configurations on which to focus in your virtual infrastructure from the security perspective. While locking down every setting and closing every potential hole listed will help with making the environment more secure, there needs to be, of course, the balance of security with usability and functionality. The virtual infrastructure must provide the required services and resources, or else it is not providing value. So, you get to consider the guidelines in the Hardening Guides and determine which to follow and which to note as “accepted security risks,” as appropriate for your environment.

As vSphere has progressed, VMware has continued a trend toward more secure default configurations. As the admin, you should therefore have fewer and fewer tasks in the hardening process. When creating the vSphere 5.0 Hardening Guide, VMware also made things much easier on admins by including information about how to assess and remediate the suggested settings by ESXi Shell, vCLI, and PowerCLI commands for most of the items. They also included a link to the pertinent vSphere API involved.

With the vSphere 6.0 Hardening Guide, VMware again eased use and consumption of the guide by updating its layout. They moved all programmatic guidelines to a single Microsoft Excel worksheet. (Best practice and operational guidelines are now separate from the guidelines that lend themselves to automated remediation. The operational guidance is now available as part of the vSphere Security documentation and in a separate Excel file at the Hardening Guides website.) The Guideline IDs have been expanded by prefixing the target type, making the IDs more useful and informative.

The vSphere 6.0 Security Hardening Guide uses a straightforward classification scheme. The guidelines are organized around these four areas (followed here by the Guideline ID prefix):

  • ESXi Hosts (ESXi)
  • Virtual Machines (VM)
  • Virtual Networking (vNetwork)
  • vCenter Server (vCenter)

Each guideline has been assigned one or more of three risk profiles as follows:

  1. Risk Profile 1: Guidelines that should be implemented only in the highest security environments
  2. Risk Profile 2: Guidelines that should be implemented in sensitive environments
  3. Risk Profile 3: Guidelines that should be implemented in all environments

For each guideline, the document describes a method to remediate the potential threat. These methods include parameter settings (what to set or unset) and component configuration (installing and/or configuring components, enabling/disabling items). Despite all of these improvements to the Hardening Guides, there are still some guidelines that do not include PowerCLI assessment and/or remediation information. So, here we have a chapter for that.

Work with the Guidelines

This chapter focuses on the security guidance from the Hardening Guides and particularly on the guidelines that do not have PowerCLI assessment and/or remediation commands available. Although we do not address the operational guidance, you should understand that such guidance is equally important to follow. Operational guideline VM.minimize-console-use is such an example. It advises you to minimize the access to and use of the VM console, because this access also provides the user with control over power actions and removable devices that “might potentially allow a malicious user to bring down a virtual machine.” That’s sound advice, but it’s hard to automate. The next sections show ways to automate the assessment and/or remediation of the programmatic guidelines.

ESXi Hosts

Of the ESXi.* guidelines in the 6.0 Hardening Guide, there are several for which VMware has not yet provided assessment and/or remediation code. So, for these, we need to make our own assessment and remediation code. Of these guidelines, many require setting values for advanced settings of the ESXi hosts for remediation.

First, let’s look at the ESXi.set-dcui-access guideline. This item deals with the list of authorized users with Direct Console User Interface (DCUI) access. By using the Get- and Set-AdvancedSetting cmdlets, you can assess and, as needed, remediate this advanced ESXi setting, DCUI.Access. Listing 13-1 gives an example of assessing this setting, and then remediating the setting to limit the DCUI access and keep the target VMHosts that much safer. Now you won’t have to worry about that potential attack vector, because we removed the extraneous access that was somehow left over from when vPiney was doing some testing and added this access for his local account.

Listing 13-1: Assessing/remediating guideline ESXi.set-dcui-access

Get-VMHost | Get-AdvancedSetting -Name DCUI.Access |
  Select-Object Entity,Name,Value

Entity           Name         Value
------           ----         -----
desxi07.dom.int  DCUI.Access  vPiney_local, root
desxi08.dom.int  DCUI.Access  vPiney_local, root


## remediate/remove user
Get-VMHost | Get-AdvancedSetting -Name DCUI.Access | Set-AdvancedSetting `
  -Value root -Confirm:$false | Select-Object Entity,Name,Value
Entity           Name         Value
------           ----         -----
desxi07.dom.int  DCUI.Access  root
desxi08.dom.int  DCUI.Access  root

The remediation portion of the script removed user vPiney_local from the list of users with DCUI access; the testing that involved that account has long since been completed, and we want to maintain “just enough access” to help keep things more secure. Notice that setting this value wasn’t additive but instead it overwrote the original value with the new value that we supplied, root. So, we effectively removed the given user by specifying the value of just the users whom we want to retain access. If normal lockdown mode is enabled, the DCUI.Access setting allows a list of highly trusted users to override lockdown mode and to access the DCUI. Remediation might go the other direction, and require you to add users who need access through the DCUI to the authorized users list. To do so, specify users who should retain access as the value of the -Value parameter of Set-AdvancedSetting.

A related guideline, ESXi.audit-exception-users, deals with host-wide access (not DCUI access as addressed in the previous guideline). Lockdown exception users do not lose their permissions when the host enters lockdown mode. The Hardening Guide assigns an Audit Only action type to this guideline. The PowerCLI commands provided in this guideline to report on the current lockdown exceptions for hosts write much of the data to the PowerShell console, whereas automated operations generally prefer objects (for further manipulation and consumption down the pipeline). The code in Listing 13-2 will get you such objects.

Listing 13-2: Getting VMHost lockdown exception users

Get-View -ViewType HostSystem -Property Name,ConfigManager.HostAccessManager |
  Foreach-Object {
  $oThisHostSystem = $_
  $oThisHostAccessMgr = Get-View -Id $_.ConfigManager.HostAccessManager
  New-Object -Type PSObject -Property ([ordered]@{
    Name = $oThisHostSystem.Name
    LockdownExceptionUser = $oThisHostAccessMgr.QueryLockdownExceptions()
    HostAccessManager = $oThisHostAccessMgr
    MoRef = $oThisHostSystem.MoRef
  })
}

Listing 13-2 returns informational objects like the following:

Name              LockdownExcept...  HostAccessManager    MoRef
----              -----------------  -----------------    -----
desxi07v.dom.int  {myAcct0}          VMware.Vim.HostA...  HostSystem-host-148
desxi08v.dom.int  {myAcct0}          VMware.Vim.HostA...  HostSystem-host-219

Notice that these returned objects show that the myAcct0 account is in the lockdown exception list on two of our VMHosts. Auditing is handled for this guideline; you can now easily export the resulting data to your favorite data format—for example, CSV, XML, or JSON.

But what if you need to remediate this item and remove a lockdown exception? PowerCLI and the vSphere API are there for you, of course. Using the HostAccessManager object for a given ESXi HostSystem, you can run the UpdateLockdownExceptions method (which is why we returned HostAccessManager as a property for the output objects from Listing 13-2). Let’s say that you assigned the objects returned by the code from Listing 13-2 to the variable $arrLockdownExceptionInfo. Now you can use that information to remove the exception user from your environment as follows:

$arrLockdownExceptionInfo | Foreach-Object {
  $_.HostAccessManager.UpdateLockdownExceptions($null)}

Now, running the code in Listing 13-2 again, you can see that the lockdown exception is gone for each host:

Name              LockdownExcept...  HostAccessManager    MoRef
----              -----------------  -----------------    -----
desxi07v.dom.int  {}                 VMware.Vim.HostA...  HostSystem-host-148
desxi08v.dom.int  {}                 VMware.Vim.HostA...  HostSystem-host-219

Some environments may have a legitimate need to have accounts in the lockdown exception list. So, for convenience, we created a function for setting lockdown exception users (see Listing 13-3).

Listing 13-3: Setting VMHost lockdown exception users

function Set-VMHostLockdownException {
  <# .Description
    Function to set the Lockdown exception users for a VMHost.
    .Example
    Set-VMHostLockdownException -UserName dommySvcAcct
    Set given user as the only Lockdown exception for all VMHosts (effectively
      removes other users)
    .Example
    Get-VMHost *dev.dom.int | Set-VMHostLockdownException -UserName `
      domMySvcAcct2 -Append
    Add given user to the Lockdown exception list of users for targeted VMHosts
    .Example
    Set-VMHostLockdownException -UserName:$null -Id $arrHostSystems.MoRef
    Clear the list of Lockdown exception users for VMHosts from myCluster;
      the $arrHostSystems array holds the HostSystem View objects for the
      VMHosts in cluster "myCluster", and accessing the .MoRef property of the
      array gives all of the HostSystems' MoRefs as the value to -Id
    .Outputs
    PSObject with information about the new Lockdown exceptions for the given
      VMHost
  #>
  [CmdletBinding(SupportsShouldProcess=$true,
    DefaultParameterSetName="ByVMHost")]
  Param(
    ## User name(s) with which to update lockdown exceptions. To remove all
    #    user exceptions, specify $null as the value. For Active Directory
    #    user, specify name in "domainuser" format
    [parameter(Mandatory=$true)][AllowNull()][string[]]$UserName,
    ## VMHost for which to set Lockdown exceptions. If none specified, will act
    #    on all VMHosts
    [parameter(ValueFromPipeline=$true,ParameterSetName="ByVMHost")]
    [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMHost,
    ## ID of VMHost for which to set lockdown exceptions
    [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,
      ParameterSetName="ByVMHostId")][Alias("MoRef","Id")]
    [VMware.Vim.ManagedObjectReference[]]$VMHostId,
    ## Switch:  append given user to existing list of exceptions? If not,
    #    replaces current list with specified user
    [Switch]$Append
  )

  begin {
    $hshParamForGetHostView = @{Property = "Name",
      "ConfigManager.HostAccessManager"}
  }

  process {
    ## get other params for Get-View call for getting the desired HostSystems
    Switch ($PsCmdlet.ParameterSetName) {
      "ByVMHost" {
        if ($null -ne $VMHost) {$hshParamForGetHostView["Id"] = $VMHost.Id}
        ## else, add param that will get all HostSystems
        else {$hshParamForGetHostView["ViewType"] = "HostSystem"}
        break}
      "ByVMHostId" {$hshParamForGetHostView["Id"] = $VMHostId}
    }

    ## get the HostSystem View objects for which to make updates, then do it
    Get-View @hshParamForGetHostView | Foreach-Object {
      $oThisHostSystem = $_
      $oThisHostAccessMgr = Get-View -Id $_.ConfigManager.HostAccessManager
      ## make the list of Lockdown exceptions to set
      $arrLockdownExcepToSet = if ($Append) {
          @($oThisHostAccessMgr.QueryLockdownExceptions()) + $UserName
        }
        else {$UserName}

      $strShouldProcessOperationMsg = if ($null -eq $arrLockdownExcepToSet) {
        "Remove Lockdown exceptions"
      } else {
        "Set Lockdown exceptions to '$($arrLockdownExcepToSet -join ', ')'"
      }
      if ($PsCmdlet.ShouldProcess("VMHost '$($oThisHostSystem.Name)'", `
          $strShouldProcessOperationMsg)) {
        try {
          ## update the Lockdown exceptions
          $oThisHostAccessMgr.UpdateLockdownExceptions($arrLockdownExcepToSet)
          $arrNewLockdownExceptions =
            $oThisHostAccessMgr.QueryLockdownExceptions()
          ## return info object
          New-Object -Type PSObject -Property ([ordered]@{
            Name = $oThisHostSystem.Name
            LockdownExceptionUser =
              $(if ($arrNewLockdownExceptions.Count -ne 0) {
                $arrNewLockdownExceptions})
            MoRef = $oThisHostSystem.MoRef
          })
        }
        catch {Throw "encountered issue setting Lockdown exceptions for `
          VMHost '$($oThisHostSystem.Name)'. The error: $_"}
      }
    }
  }
}

Suppose you need to add a lockdown exception for the service account that a third-party application uses for host access. You can use the Set-VMHostLockdownException function from Listing 13-3:

Set-VMHostLockdownException -UserName dommySvcAcct0

Name              LockdownExceptionUser  MoRef
----              ---------------------  -----
desxi07v.dom.int  DOMmySvcAcct0         HostSystem-host-148
desxi08v.dom.int  DOMmySvcAcct0         HostSystem-host-219

You should be aware that the UpdateLockdownExceptions API method requires you to specify the full list of lockdown exceptions—it is not additive. The function in Listing 13-3 takes this into account, and provides for appending users by specifying the –Append switch parameter.

A possibly more handy feature (and more in keeping with tighter security), the Set-VMHostLockdownException function in Listing 13-3 makes it easy to empty the lockdown exception list. You can give the $null value to the -UserName parameter to do so. The result is similar to the direct API call to UpdateLockdownExceptions, but nicely encapsulated in a function that returns the resulting configuration.

Set-VMHostLockdownException -UserName $null

Name              LockdownExceptionUser  MoRef
----              ---------------------  -----
desxi07v.dom.int                         HostSystem-host-148
desxi08v.dom.int                         HostSystem-host-219

As for some of the PowerShell niceties in the Set-VMHostLockdownException function from Listing 13-3, you see an example of using parameter splatting, which dynamically builds a hash table of parameters/values, and then uses that hash table as the parameters for a given cmdlet (Get-View in this case, everyone’s favorite!). See the PowerShell help topic about_Splatting for more about splatting. The additional PowerShell nicety, the -WhatIf support in this function, helps answer the question: “What is this going to do if I issue this line?”

Now for some more advanced ESXi host settings. There are currently four other guidelines that involve ESXi advanced settings and for which the Hardening Guide has no PowerCLI assessment or remediation code. Table 13-1 lists the Guideline IDs and setting names.

Table 13-1: Additional ESXi guidelines and the corresponding advanced setting names

Guideline IDESXi advanced setting name
ESXi.set-account-auto-unlock-timeSecurity.AccountUnlockTime
ESXi.set-account-lockoutSecurity.AccountLockFailures
ESXi.set-dcui-timeoutUserVars.DcuiTimeOut
vNetwork.enable-bpdu-filterNet.BlockGuestBPDU

Although you could essentially repeat the code we provided earlier in Listing 13-1 for setting each of these advanced options individually, this is an interesting opportunity to create an advanced function that you can use to assess and remediate multiple advanced settings. Listing 13-4 provides such a function.

Listing 13-4: Assessing/remediating multiple ESXi advanced settings

function Assert-HardeningGuideESXiAdvSetting {
  <#  .Description
    Function to assess and/or remediate several of the advanced settings
    called out in the VMware Hardening Guide (but that do not have PowerCLI
    assessment/remediation code in the guide)
    .Example
    Assert-HardeningGuideESXiAdvSetting
    Report on the current values of the given advanced settings for all
    VMHosts,
    and whether they meet the values that the hardening guide recommends
    .Example
    Get-VMHost myhost0, myhost1 |
      Assert-HardeningGuideESXiAdvSetting -Remediate:$true
    Set the advanced settings' values to those that the
    hardening guide recommends
    .Outputs
    If remediating,
    Selected.VMware.VimAutomation.ViCore.Impl.V1.AdvancedSettingImpl of
    any settings that were updated, or
    Selected.VMware.VimAutomation.ViCore.Impl.V1.AdvancedSettingImpl of
    all associated settings if reporting only (default)
  #>
  [CmdletBinding(SupportsShouldProcess=$true)]
  Param(
    ## VMHost to assess/remediate. If none specified, will act on all
    #   VMHosts in the VIServer to which current session is connected
    [parameter(ValueFromPipeline=$true)]
    [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMHost,
    ## Switch: Remediate the entity? Default is $false, which
    #   causes function to only report
    [switch]$Remediate = $false
  )

  begin {
    ## array of objects with info about advanced settings and desired values to
    #   set per the hardening guide (for guidelines that have no PowerCLI
    #   assessment/remediation code in the hardening guide)
    $arrHardGuideSettingInfo =
      @{Name = "Security.AccountUnlockTime";
        GuidelineId = "ESXi.set-account-auto-unlock-time"; Value = 900},
      @{Name = "Security.AccountLockFailures";
        GuidelineId = "ESXi.set-account-lockout"; Value = 3},
      @{Name = "UserVars.DcuiTimeOut";
        GuidelineId = "ESXi.set-dcui-timeout"; Value = 600},
      @{Name = "Net.BlockGuestBPDU";
        GuidelineId = "vNetwork.enable-bpdu-filter"; Value = 1} |
      Foreach-Object {New-Object -Type PSObject -Property $_}
  }

  process {
    $arrVMHostOfInterest = if ($PsBoundParameters.ContainsKey("VMHost"))
      {$VMHost} else {Get-VMHost}
    $arrAdvSettings_theseHosts = Get-AdvancedSetting -Entity `
      $arrVMHostOfInterest -Name $arrHardGuideSettingInfo.Name
    $arrAdvSettings_theseHosts | Foreach-Object {
      $oThisSetting = $_
      $oThisHGItem = $arrHardGuideSettingInfo |
        Where-Object {$_.Name -eq $oThisSetting.Name}
      $bIsSuggestedValue = $oThisHGItem.Value -eq $_.Value
      if ($Remediate) {
        if (-not $bIsSuggestedValue) {
          if ($PsCmdlet.ShouldProcess($oThisSetting.Entity, `
            ("Set {0} from {1} to {2}" -f $oThisSetting.Name, `
            $oThisSetting.Value, $oThisHGItem.Value))) {
              Set-AdvancedSetting -AdvancedSetting $oThisSetting -Value `
                $oThisHGItem.Value -Confirm:$false |
                Select-Object Entity, Name, Value
          }
        }
      }
      ## else, report the current settings' values, and whether they
      #   match the values that the hardening guide suggests
      else {
        Select-Object -InputObject $_ Entity, Name, Value,
          @{n="GuidelineId"; e={$oThisHGItem.GuidelineId}},
          @{n="IsSuggestedValue"; e={$bIsSuggestedValue}}
      }
    }
  }
}

Using this function is straightforward. To assess the four settings for all VMHosts (the default scope if no particular VMHost is specified), use this:

Assert-HardeningGuideESXiAdvSetting

Entity  Name                     Value GuidelineId            IsSuggestedValue
------  ----                     ----- -----------            ----------------
desxi07 UserVars.DcuiTimeOut       600 ESXi.set-dcui-timeo...             True
desxi07 Net.BlockGuestBPDU           0 vNetwork.enable-bpd...            False
desxi07 Security.AccountLockF...     3 ESXi.set-account-lo...             True
desxi07 Security.AccountUnloc...   120 ESXi.set-account-au...            False
desxi08 UserVars.DcuiTimeOut       600 ESXi.set-dcui-timeo...             True
desxi08 Net.BlockGuestBPDU           1 vNetwork.enable-bpd...             True
desxi08 Security.AccountLockF...    10 ESXi.set-account-lo...            False
desxi08 Security.AccountUnloc...   900 ESXi.set-account-au...             True

To remediate any of the settings on any of the hosts that do not have the value suggested by the guideline, add the -Remediate parameter, like so:

Assert-HardeningGuideESXiAdvSetting -Remediate:$true

Entity              Name                             Value
------              ----                             -----
desxi07.dom.int     Net.BlockGuestBPDU                   1
desxi07.dom.int     Security.AccountUnlockTime         900
desxi08.dom.int     Security.AccountLockFailures         3

Notice that the remediation returns just the changed advanced settings (it only acts on the settings that were not of the suggested value). And, of course, the function supports -WhatIf so that you can give it a dry run and see what settings would change, if any. To verify that all of the VMHosts have the suggested/desired values per the Hardening Guide, you can just invoke the function again:

Assert-HardeningGuideESXiAdvSetting

Entity  Name                     Value GuidelineId            IsSuggestedValue
------  ----                     ----- -----------            ----------------
desxi07 UserVars.DcuiTimeOut       600 ESXi.set-dcui-timeo...             True
desxi07 Net.BlockGuestBPDU           1 vNetwork.enable-bpd...             True
desxi07 Security.AccountLockF...     3 ESXi.set-account-lo...             True
desxi07 Security.AccountUnloc...   900 ESXi.set-account-au...             True
desxi08 UserVars.DcuiTimeOut       600 ESXi.set-dcui-timeo...             True
desxi08 Net.BlockGuestBPDU           1 vNetwork.enable-bpd...             True
desxi08 Security.AccountLockF...     3 ESXi.set-account-lo...             True
desxi08 Security.AccountUnloc...   900 ESXi.set-account-au...             True

Now the VMHosts all have values for these advanced settings as suggested by the Hardening Guide. We made the function in Listing 13-4 easily extensible, too. By using the variable $arrHardGuideSettingInfo, an array of PSObjects in the begin script block of the Assert-HardeningGuideESXiAdvSetting function, it is trivial to add more guidelines or advanced settings which to assess/remediate for VMHosts. For example, let’s say that VMware has now put forth a new guideline recommending that the “Net.SuperSecureSetting.Enable” advanced setting should be set to $true on all ESXi hosts. You can just add another hash table with the pertinent advanced setting name, Guideline ID, and value. The subsequent call in the function to the New-Object cmdlet makes another new PSObject from the hash table that you added. The process script block will assess and remediate that new setting (“Net.SuperSecureSetting.Enable”) in addition to the others, and now you have extended the function to be that much more useful! (Be sure to share it with the world when you do.)

One other ESXi-related guideline is ID ESXi.firewall-enabled. The Hardening Guide suggests that you leverage the ESXi host firewall to restrict access to services running on the host. While the PowerCLI remediation value in the Hardening Guide is N/A, that may be due to the semi-operational nature of this guideline. It is not a blanket, enable-these-firewall-rules-for-all-environments scenario—it depends on your particular environment and your needs for your ESXi hosts. For example, if your environment uses NFS v4.1 datastores, syslog, and NSX, you would have the nfs41Client, NSX Distributed Logical Router Service, and syslog VMHost firewall exceptions enabled, allowing such traffic in and out of the ESXi host. So, when looking at enabled firewall exceptions on a VMHost, you need to consider what features you are using, which will dictate which exceptions you should enable.

Out of the box, the ESXi default firewall policy is that IncomingEnabled and OutgoingEnabled are both $false. So, if there is not a firewall exception, traffic to and from a VMHost should be blocked. You can verify VMHosts’ default firewall policy by using this:

Get-VMHost vMixty0[56].dom.int | Get-VMHostFirewallDefaultPolicy

IncomingEnabled  OutgoingEnabled
---------------  ---------------
False            False
False            False

Should you ever need to configure an ESXi host’s firewall default policy, you could use something like the following code. This example assumes that someone changed the default firewall policies on the given VMHosts to $true at some point, and shows the resulting DefaultPolicy values are again at $false:

Get-VMHostFirewallDefaultPolicy -VMHost vMixty0[56].dom.int |
  Set-VMHostFirewallDefaultPolicy -AllowIncoming $false -AllowOutgoing $false

IncomingEnabled  OutgoingEnabled
---------------  ---------------
False            False
False            False

The Hardening Guide has an assessment command example that allows you to get the current VMHost firewall exceptions using the Get-VMHostFirewallException cmdlet. You can use the associated Set-VMHostFirewallException cmdlet when you need to change an exception. For example, suppose that it is time to use Network Time Protocol (NTP) to synchronize the clocks in your environment across the network. You would have used the Set-VMHostService cmdlet to set the policy of the ntpd service to Automatic, but you need to enable a firewall exception so that the related NTP communications succeed. The following will enable the NTP firewall exceptions on the given VMHosts:

Get-VMHost vMixty0[56].* | Get-VMHostFirewallException -Name "NTP Client" |
  Set-VMHostFirewallException -Enabled:$true

Name           Enabled IncomingPorts  OutgoingPorts  Protocols  ServiceRunning
----           ------- -------------  -------------  ---------  --------------
NTP Client     True                   123            UDP        True
NTP Client     True                   123            UDP        True

Granted, if you were using something like the vSphere Web Client to configure NTP on a VMHost (or some other host-related configurations that require firewall exceptions), the Web Client takes care of enabling and disabling the corresponding firewall exception. But, this is PowerCLI time. GUI? What GUI? So we take care of the firewall exception configuration on our own.

Virtual Machines

There are several guidelines for virtual machines in the Hardening Guide (about 40 of them), many of which deal with advanced settings of the virtual machine objects. VMware has done a great job with these virtual machine guidelines; PowerCLI assessment and remediation commands are provided for nearly all of them.

One VM guideline whose remediation command could use a bit of expansion is Guideline ID VM.disable-independent-nonpersistent. This guideline helps you avoid using independent nonpersistent disks and removes the ability of attackers to cover their tracks by rebooting and power-cycling a VM with an IndependentNonPersistent disk. The PowerCLI remediation command for this guideline shows the cmdlets to use, but it does not include the full set of parameters needed for remediation. The code in Listing 13-5 changes IndependentNonPersistent virtual disks to IndependentPersistent disks.

Listing 13-5: Changing persistence of independent-nonpersistent vDisks

## the disk persistence mode to which to change
$strTargetMode = "IndependentPersistent"

Get-VM | Foreach-Object {
  $VM = $_
  ## if this VM has any IndependentNonPersistent disks
  if ($arrIndNonPerDiskThisVM = Get-HardDisk -VM $VM | Where-Object {
    $_.Persistence -eq "IndependentNonPersistent"}) {
    ## if the VM has a snapshot, write a warning that cannot convert its disk
    if ($arrSnapsThisVM = Get-Snapshot -VM $VM) {
      $intNumSnapsThisVM = ($arrSnapsThisVM | Measure-Object).Count
      ## compose a warning message to write out
      $strMsgHasSnap = "VM '$($VM.Name)' has {0}. Cannot convert its `
        IndependentNonPersistent disks to '$strTargetMode'" -f `
        $(if ($intNumSnapsThisVM -eq 1) {"a snapshot"} else {"snapshots"})
      Write-Warning $strMsgHasSnap
    }
    ## else, set the persistence of its IndependentNonPersistent disks
    else {
      Set-HardDisk -HardDisk $arrIndNonPerDiskThisVM -Persistence `
        $strTargetMode -Confirm:$false
    }
  }
}

The code in Listing 13-5 also takes advantage of PowerShell’s ability to perform an assignment operation inside the conditional expression for the if statements. This can help to keep the code tight, versus performing those two actions separately. It’s handy for efficiency, though it does require a bit more understanding for future code maintenance.

The only other VM guideline that is currently short on PowerCLI commands in the Hardening Guide is Guideline ID VM.verify-network-filter. This guideline is also assigned an Audit Only action type. Using the PowerCLI assessment command documented in the Hardening Guide, you can find all the VMs with a VMX setting for an Ethernet filter. Although it would be better to manage the VM network filters via the products that created them (using the vSphere Network Appliance API, or DvFilter API), you may have to remove an Ethernet filter “manually” from a VM. If, in auditing, you determine that there is a VM with settings that you decide should no longer be there, you can use the Remove-AdvancedSetting cmdlet to remove the VM advanced setting. Say you have a VM with an unwanted ethernet0.filter0.name advanced setting with a filter module value; you can remove this setting by using the following:

Get-VM vmCourntie0 | Get-AdvancedSetting -Name ethernet0.filter0.name |
  Remove-AdvancedSetting

vNetwork

The Hardening Guide provides assessment PowerCLI commands for most of the vNetwork guidelines. As PowerCLI’s cmdlet coverage continues to grow, you can simplify some of those commands. For example, checking virtual switch security settings became much easier with the introduction of the Get-SecurityPolicy and Get-VDSecurityPolicy cmdlets in PowerCLI 5.5 (Release 2 and Release 1, respectively). And the accompanying Set-SecurityPolicy and Get-VDSecurityPolicy cmdlets provide a means by which to manage security settings.

The vNetwork vSwitch/vPortgroup assessment commands in the Hardening Guide are a bit more involved than necessary (thanks to the new *SecurityPolicy cmdlets), and the Guide provides no remediation commands. Therefore, Listings 13-6 and 13-7 offer ways in which to check and set the security settings. These guidelines deal with the Forged Transmits, MAC Address Changes, and Promiscuous Mode security settings of virtual switches and virtual port groups.

Listing 13-6 addresses vSphere standard switches and port groups for the Hardening Guidelines with IDs of vNetwork.reject-forged-transmit, vNetwork.reject-mac-changes, and vNetwork.reject-promiscuous-mode. Listing 13-7 addresses vSphere distributed switches and port groups for the Hardening Guidelines with IDs of vNetwork.reject-forged-transmit-dvportgroup, vNetwork.reject-mac-changes-dvportgroup, and vNetwork.reject-promiscuous-mode-dvportgroup.

Listing 13-6: Reporting and updating standard switch/port group security policies

## Assess in more straightforward manner than in the hardening guide:
Get-VMHost | Get-VirtualSwitch -Standard | Get-SecurityPolicy

VirtualSwitch  AllowPromiscuous  ForgedTransmits  MacChanges
-------------  ----------------  ---------------  ----------
vSwitch0       False             True             True
vSwitch1       False             True             True

Get-VMHost | Get-VirtualSwitch -Standard | Get-VirtualPortGroup |
  Get-SecurityPolicy

VirtualPortGroup  AllowPromiscuous   ForgedTransmits  MacChanges
----------------  ----------------   ---------------  ----------
MgmtNetwork       False              True             True
dNet0             False              True             True
vESXiNet0         True               True             True

## remediate
Get-VMHost | Get-VirtualSwitch -Standard | Get-SecurityPolicy |
  Set-SecurityPolicy -AllowPromiscuous:$false -ForgedTransmits:$false `
  -MacChanges:$false

VirtualSwitch  AllowPromiscuous  ForgedTransmits  MacChanges
-------------  ----------------  ---------------  ----------
vSwitch0       False             False            False
vSwitch1       False             False            False

Get-VMHost | Get-VirtualSwitch -Standard | Get-VirtualPortGroup |
  Get-SecurityPolicy | Set-SecurityPolicy -AllowPromiscuousInherited:$true `
  -ForgedTransmitsInherited:$true -MacChangesInherited:$true
VirtualPortGroup  AllowPromiscuous   ForgedTransmits  MacChanges
----------------  ----------------   ---------------  ----------
MgmtNetwork       False              False            False
dNet0             False              False            False
vESXiNet0         False              False            False

Notice that we set the explicit security policies to the desired setting on the virtual switches, and then updated the security policies of the virtual port groups on these virtual switches to inherit the settings from the virtual switches’ configurations. You see the same technique in Listing 13-7, but it uses the VMware.VimAutomation.Vds PowerCLI module for dealing with virtual distributed networking components.

Listing 13-7: Reporting and updating distributed switch/port group security policies

Import-Module VMware.VimAutomation.Vds
## Assess in more straightforward manner than in the hardening guide:
Get-VDSwitch | Get-VDSecurityPolicy

VDSwitch    AllowPromiscuous  MacChanges  ForgedTransmits
--------    ----------------  ----------  ---------------
vDSw-Dev0   True              True        False
vDSw-Prod1  False             True        True

Get-VDSwitch | Get-VDPortgroup | Get-VDSecurityPolicy

VDPortgroup  AllowPromiscuous  MacChanges  ForgedTransmits
-----------  ----------------  ----------  ---------------
dvPG01       True              False       False
vMotion      True              False       True

## remediate
Get-VDSwitch | Get-VDSecurityPolicy | Set-VDSecurityPolicy `
  -AllowPromiscuous:$false -MacChanges:$false -ForgedTransmits:$false
VDSwitch    AllowPromiscuous  MacChanges  ForgedTransmits
--------    ----------------  ----------  ---------------
vDSw-Dev0   False             False       False
vDSw-Prod1  False             False       False

Get-VDSwitch | Get-VDPortgroup | Get-VDSecurityPolicy | Set-VDSecurityPolicy `
  -AllowPromiscuousInherited:$true -ForgedTransmitsInherited:$true `
  -MacChangesInherited:$true

VDPortgroup  AllowPromiscuous  MacChanges  ForgedTransmits
-----------  ----------------  ----------  ---------------
dvPG01       False             False       False
vMotion      False             False       False

The next vNetwork guideline that needs some PowerCLI help is Guideline ID vNetwork.limit-network-healthcheck. The Hardening Guide recommends, “Enable VDS network healthcheck only if you need it.” Because there is no cmdlet for directly checking and managing these healthcheck options, we created the function shown in Listing 13-8.

Listing 13-8: Assessing and remediating network healthcheck options

function Assert-HardeningGuideVNetworkHealthChk {
  <#  .Description
    Function to assess and/or remediate the VMware Hardening Guide item with
    Guideline ID "vNetwork.limit-network-healthcheck" (which do not have
    PowerCLI assessment/remediation code in the guide).  The guideline
    recommends disabling these health check items, since, as the guide states,
    "once enabled, the healthcheck packets contain information on host#,
    vds# port#, which an attacker would find useful"
    .Example
    Assert-HardeningGuideVNetworkHealthChk
    Report on the current values of the health check configuration items for
    all virtual distributed switches
    .Example
    Get-VDSwitch myVDSwitch0, myVDSwitch1 |
      Assert-HardeningGuideVNetworkHealthChk -Remediate:$true
    Disable any enabled health check setting on vDSwitches, as the hardening
    guide recommends
    .Outputs
    If remediating, the VMware.VimAutomation.Vds.Impl.V1.VmwareVDSwitchImpl
    object for each VDSwitch updated. If just reporting, the
    Selected.VMware.Vim.VMwareDVSVlanMtuHealthCheckConfig and
    Selected.VMware.Vim.VMwareDVSTeamingHealthCheckConfig object for each
    VDSwitch involved
  #>
  [CmdletBinding(SupportsShouldProcess=$true)]
  Param(
    ## Virtual distributed switch to assess/remediate. If none specified, will
    #   act on all vDSwitches in the VIServer to which current session is
    #   connected
    [parameter(ValueFromPipeline=$true)][PSObject[]]$VDSwitch,
    ## Switch: Remediate the entity? Default is $false, which causes function to
    #   only report
    [switch]$Remediate = $false
  )

  begin {
    ## the desired value for the HealthCheckConfig properties
    $bDesiredConfigValue = $false
  }

  process {
    $arrVDSwitchOfInterest = if ($PsBoundParameters.ContainsKey("VDSwitch")) {
        if ($VDSwitch.GetType().Name -eq "VmwareVDSwitchImpl") {$VDSwitch}
        else {Get-VDSwitch -Name $VDSwitch}
      } else {Get-VDSwitch}
    ## get the HealthCheckConfig information for the VDSwitch(es)
    $arrHealthCheckConfigInfo = $arrVDSwitchOfInterest | Foreach-Object {
        $oThisVDSwitch = $_
        $oThisVDSwitch.ExtensionData.Config.HealthCheckConfig |
          Select-Object @{n="VDSwitch"; e={$oThisVDSwitch}},
            @{n="HealthCheckConfigType"; e={$_.GetType().Name}},
            @{n="Enabled"; e={$_.Enable}},
            @{n="IsSuggestedValue"; e={$bDesiredConfigValue -eq $_.Enable}}
      }

    if ($Remediate) {
      ## get just the VDSwitches who have a healthcheckconfig value that is
      #   not the suggested value
      $arrVDSwitchToRemediate = $arrHealthCheckConfigInfo |
        Where-Object {$_.IsSuggestedValue -eq $false} |
        Select-Object -Unique -ExpandProperty VDSwitch
      ## make the healthCheckConfig items to use for updating the
      #   DVSHealthCheckConfig
      $arrDVSHealthCheckConfigItems =
        "VMware.Vim.VMwareDVSTeamingHealthCheckConfig",
        "VMware.Vim.VMwareDVSVlanMtuHealthCheckConfig" |
        Foreach-Object {
          New-Object -TypeName $_ -Property @{Enable = $bDesiredConfigValue}
        }
      if (($arrVDSwitchToRemediate | Measure-Object).Count -eq 0) {
        Write-Verbose "All VDSwitches specified have the suggested values for
          their Health Check configurations"}
      else {
        $arrVDSwitchToRemediate | Foreach-Object {
          $oThisVDSwitch = $_
          if ($PsCmdlet.ShouldProcess($oThisVDSwitch.Name,
            "Disable Health Checking")) {
            try {
              $oTaskId =
                $oThisVDSwitch.ExtensionData.UpdateDVSHealthCheckConfig_Task(`
                  $arrDVSHealthCheckConfigItems)
              ## wait for the task; this task should return nothing, but
              #   sending to Out-Null for cleanliness
              Wait-Task -Task (Get-Task -Id $oTaskId) | Out-Null
              $oTask_final = Get-Task -Id $oTaskId
              ## if the task succeeded, return the newly updated VDSwitch
              if ($oTask_final.State -eq "Success") {
                Get-VDSwitch -Id $oThisVDSwitch.Id
              }
              else {
                Write-Error "Problem setting Health Check Config on VDSwitch
                  '$($oThisVDSwitch.Name)'. The reconfiguration task result:
                  '$($oTask_final.Result)'. And, the task error:
                  '$($oTask_final.ExtensionData.Info.Error)'"
                }
            } catch {Write-Error "Problem initiating the configuration task for
                VDSwitch '$($oThisVDSwitch.Name)'"}
          }
        }
      }
    }
    else {
      ## else just return the health check config info items
      $arrHealthCheckConfigInfo
    }
  }
}

Here are a pair of examples of using the Assert-HardeningGuideVNetworkHealthChk function from Listing 13-8, first to assess the vNetwork healthcheck settings, and then to remediate the settings:

## Assess
Assert-HardeningGuideVNetworkHealthChk

VDSwitch   HealthCheckConfigType              Enabled  IsSuggestedValue
--------   ---------------------              -------  ----------------
vDSwitch0  VMwareDVSVlanMtuHealthCheckConfig     True             False
vDSwitch0  VMwareDVSTeamingHealthCheckConfig     True             False
vDSwitch1  VMwareDVSVlanMtuHealthCheckConfig    False              True
vDSwitch1  VMwareDVSTeamingHealthCheckConfig    False              True

## remediate; returns the updated vSwitch object after updating the Health
#   Check config
Assert-HardeningGuideVNetworkHealthChk -Remediate

Name      NumPorts Mtu  Version Vendor
----      -------- ---  ------- ------
vDSwitch0 256      9000 6.0.0   VMware, Inc.

## next assessment shows all is well; so good!
Assert-HardeningGuideVNetworkHealthChk

VDSwitch   HealthCheckConfigType              Enabled  IsSuggestedValue
--------   ---------------------              -------  ----------------
vDSwitch0  VMwareDVSVlanMtuHealthCheckConfig    False              True
vDSwitch0  VMwareDVSTeamingHealthCheckConfig    False              True
vDSwitch1  VMwareDVSVlanMtuHealthCheckConfig    False              True
vDSwitch1  VMwareDVSTeamingHealthCheckConfig    False              True

As with the other advanced functions in this chapter, the function in Listing 13-8 supports ShouldProcess, which allows you to use it in what if mode with the -WhatIf parameter.

Another vNetwork guideline for which we need to make some PowerCLI assessment and remediation commands is Guideline ID vNetwork.restrict-port-level-overrides. Here, the Hardening Guide advises, “Restrict port-level configuration overrides on VDS.” PowerCLI growth provides us with a way to check and set the vSphere distributed port group port-level overrides, in the form of the cmdlets Get-VDPortGroupOverridePolicy and Set-VDPortGroupOverridePolicy, both available since PowerCLI 5.5 Release 1. The Set-VDPortGroupOverridePolicy cmdlet from PowerCLI 6.0 allows you to set five of the nine DVPortgroupPolicy and VMwareDVSPortgroupPolicy OverrideAllowed properties. The PowerCLI Help shows how to use the cmdlet.

To add a little more value, we created an advanced function (see Listing 13-9) that you can use to assess and/or remediate all nine of the vSphere distributed port group (vDPortgroup) override configurations for this guideline.

Listing 13-9: Assessing and remediating vDPortgroup override options

function Assert-HardeningGuideVNetworkPortOverride {
  <#  .Description
    Function to assess and/or remediate the VMware Hardening Guide item with
    Guideline ID "vNetwork.restrict-port-level-overrides" (which do not have
    PowerCLI assessment/remediation code in the guide). This guideline is to,
    "Restrict port-level configuration overrides on VDS". This function will
    assess/update the VDPortgroup policy's OverrideAllowed properties
    .Example
    Assert-HardeningGuideVNetworkPortOverride
    Assess the OverrideAllowed settings for all VDPortgroups
    .Example
    Get-VDSwitch myVDSwitch0 | Get-VDPortgroup |
      Assert-HardeningGuideVNetworkPortOverride -Remediate:$true
    Get the VDPortgroups of the given VDSwitch, and remediate the
    OverrideAllowed settings for each per the hardening guide
    .Outputs
    If remediating, the VMware.VimAutomation.Vds.Impl.V1.VmwareVDPortgroupImpl
    object for each VDPortgroup updated. If just reporting, a PSCustomObject
    for each VDPortgroup with information about the given override policies,
    and whether the VDPortgroup config is that as suggested in the hardening
    guide
  #>
  [CmdletBinding(SupportsShouldProcess=$true)]
  Param(
    ## Virtual distributed portgroup to assess/remediate. If none specified,
    #   will act on all VDPortgroups in the VIServer to which current session
    #   is connected
    [parameter(ValueFromPipeline=$true)][PSObject[]]$VDPortgroup,
    ## Switch: Remediate the entity? Default is $false, which causes function
    #   to only report
    [switch]$Remediate = $false
  )

  begin {
    ## the desired value for each of the OverrideAllowed properties
    $bDesiredConfigValue = $false
    ## the names of the "*OverrideAllowed" properties to assess/update
    $arrOverridePropNames = Write-Output BlockOverrideAllowed,
      VendorConfigOverrideAllowed,VlanOverrideAllowed,ipfixOverrideAllowed,
      trafficFilterOverrideAllowed,NetworkResourcePoolOverrideAllowed,
      SecurityPolicyOverrideAllowed,ShapingOverrideAllowed,
      UplinkTeamingOverrideAllowed
  }

  process {
    $arrVDPGOfInterest = if ($PsBoundParameters.ContainsKey("VDPortgroup")) {
        if ($VDPortgroup.GetType().Name -eq "VmwareVDPortgroupImpl") {
          $VDPortgroup
        }
        else {Get-VDPortgroup -Name $VDPortgroup}
      } else {Get-VDPortgroup}

    ## make some objects with the VDPortgroups' Policy values, and note if they
    #   are all the suggested value
    $arrVDPGPolicyInfo = $arrVDPGOfInterest | Foreach-Object {
      $oDVSPGPolicy_thisPG = $_.Extensiondata.Config.Policy
      New-Object -Type PSObject -Property ([ordered]@{
        VDPortgroup = $_
        VDSwitch = $_.VDSwitch
        ## are all of the given properties of the policy of this PG set to the
        #   desired config value?
        HasSuggestedValues = $bDesiredConfigValue -eq ($arrOverridePropNames |
          Foreach-Object {$oDVSPGPolicy_thisPG.$_} | Select-Object -Unique)
        BlockPorts = $oDVSPGPolicy_thisPG.BlockOverrideAllowed
        TrafficShaping = $oDVSPGPolicy_thisPG.ShapingOverrideAllowed
        VendorConfiguration = $oDVSPGPolicy_thisPG.VendorConfigOverrideAllowed
        VLAN = $oDVSPGPolicy_thisPG.VlanOverrideAllowed
        UplinkTeaming = $oDVSPGPolicy_thisPG.UplinkTeamingOverrideAllowed
        ResourceAllocation =
          $oDVSPGPolicy_thisPG.NetworkResourcePoolOverrideAllowed
        SecurityPolicy = $oDVSPGPolicy_thisPG.SecurityPolicyOverrideAllowed
        NetFlow = $oDVSPGPolicy_thisPG.ipfixOverrideAllowed
        TrafficFilteringMarking =
          $oDVSPGPolicy_thisPG.trafficFilterOverrideAllowed
      })
    }

    if ($Remediate) {
      ## get just the VDPortgroups who have an OverrideAllowed value that is
      #   not the suggested value
      $arrVDPGToRemediate = $arrVDPGPolicyInfo | Where-Object {
        $_.HasSuggestedValues -eq $false} |
        Select-Object -Unique -ExpandProperty VDPortgroup

      if (($arrVDPGToRemediate | Measure-Object).Count -eq 0) {Write-Verbose
        "All VDPortgroups specified have the suggested values for their
        OverrideAllowed policies"}
      else {
        $arrVDPGToRemediate | Foreach-Object {
          $oThisVDPG = $_
          if ($PsCmdlet.ShouldProcess($oThisVDPG.Name,
            "Reconfigure OverrideAllowed policies to '$bDesiredConfigValue'"
            )) {
            $oDVSPGPolicy_thisPG = $oThisVDPG.Extensiondata.Config.Policy
            $arrOverridePropNames | Foreach-Object {$oDVSPGPolicy_thisPG.$_ =
              $bDesiredConfigValue}
            ## make a new DVPGConfigSpec with just the configVersion and policy
            #   properties set, so as not to deal with other settings
            $oNewDVPGConfigSpec = New-Object -TypeName
              VMware.Vim.DVPortGroupConfigSpec -Property `
              @{configVersion = $_.ExtensionData.Config.ConfigVersion; policy =
                $oDVSPGPolicy_thisPG}
            try {
              $oTaskId = $oThisVDPG.ExtensionData.ReconfigureDVPortgroup_Task(
                $oNewDVPGConfigSpec)
              ## wait for the task; this task should return nothing, but
              #   sending to Out-Null for cleanliness
              Wait-Task -Task (Get-Task -Id $oTaskId) | Out-Null
              $oTask_final = Get-Task -Id $oTaskId
              ## if the task succeeded, return the newly updated VDPG
              if ($oTask_final.State -eq "Success") {Get-VDPortgroup -Id `
                $oThisVDPG.Id}
              else {Write-Error "Problem reconfiguring VDPortgroup
                '$($oThisVDPG.Name)'. The reconfiguration task result:
                '$($oTask_final.Result)'. And, the task error:
                '$($oTask_final.ExtensionData.Info.Error)'"}
            } catch {Write-Error "Problem initiating the reconfiguration task
              for VDPortgroup '$($oThisVDPG.Name)'"}
          }
        }
      }
    }
    else {
      ## else just return the VDPG policy info objects
      $arrVDPGPolicyInfo
    }
  }
}

The following snippets give examples of how to use Assert-HardeningGuideVNetworkPortOverride from Listing 13-9 to assess and remediate the vDPortgroup override settings:

## Assess
Assert-HardeningGuideVNetworkPortOverride

VDPortgroup             : vDS-Primary-DVUplinks-160
VDSwitch                : vDSwitch0
HasSuggestedValues      : False
BlockPorts              : True
TrafficShaping          : True
VendorConfiguration     : False
VLAN                    : False
UplinkTeaming           : True
ResourceAllocation      : True
SecurityPolicy          : True
NetFlow                 : False
TrafficFilteringMarking : False

VDPortgroup             : vDS-jcpwp0
VDSwitch                : vDSwitch0
HasSuggestedValues      : False
BlockPorts              : False
TrafficShaping          : False
VendorConfiguration     : False
VLAN                    : True
UplinkTeaming           : True
ResourceAllocation      : False
SecurityPolicy          : False
NetFlow                 : False
TrafficFilteringMarking : False

## Remediate; returns the updated vDPortgroup objects after reconfig
Assert-HardeningGuideVNetworkPortOverride -Remediate -Verbose
VERBOSE: Performing the operation "Reconfigure OverrideAllowed policies to
'False'" on target "vDS-Primary-DVUplinks-160".
VERBOSE: Performing the operation "Reconfigure OverrideAllowed policies to
'False'" on target "vDS-jcpwp0".

Name                           NumPorts PortBinding
----                           -------- -----------
vDS-Primary-DVUplinks-160      4        Static
vDS-jcpwp0                     64       Static

## next assessment shows all is well; great!
Assert-HardeningGuideVNetworkPortOverride

VDPortgroup             : vDS-Primary-DVUplinks-160
VDSwitch                : vDSwitch0
HasSuggestedValues      : True
BlockPorts              : False
TrafficShaping          : False
VendorConfiguration     : False
VLAN                    : False
UplinkTeaming           : False
ResourceAllocation      : False
SecurityPolicy          : False
NetFlow                 : False
TrafficFilteringMarking : False

VDPortgroup             : vDS-jcpwp0
VDSwitch                : vDSwitch0
HasSuggestedValues      : True
BlockPorts              : False
TrafficShaping          : False
VendorConfiguration     : False
VLAN                    : False
UplinkTeaming           : False
ResourceAllocation      : False
SecurityPolicy          : False
NetFlow                 : False
TrafficFilteringMarking : False

As you can see, the two vDPortgroups involved each had some settings that allowed various overrides. The remediation task updated the settings and returned the updated vDPortgroup objects. Rerunning the assessment returned information objects that show that each vDPortgroup now has the suggested values. The Assert-HardeningGuideVNetworkPortOverride function in Listing 13-9 assesses and remediates all vDPortgroups in the connected vCenter by default. You can focus this scope by using the -VDPortgroup parameter.

vCenter Server

Again, as VMware has gone the route of more secure default settings in vSphere products, the number of items of security concern has dropped. There is but one remaining vCenter.* programmatic guideline in the 6.0 version of the Hardening Guide, and the guide includes the PowerCLI commands for assessment and remediation of that recommended setting.

As for other vCenter considerations, you should follow relevant common security best practices for your vCenter Server if it is running in a Windows-based OS, such as antivirus, antimalware, and security-related OS configurations. These practices are outside the scope of this book. For vCenter running as the vCenter Server Appliance (VCSA), VMware already applies hardening recommendations to the appliance—hurray for VMware!

Bring It All Together

In this chapter, we looked at the security hardening guidelines from the Hardening Guide, focusing on the ones for which the Guide does not provide assessment and/or remediation PowerCLI automation. We provided a command, code block, or function for you to use to close the security hole. Now your hosts, your VMs, and your vNetworks will be that much better prepared for the security threats that they face.

Next improvement: Instead of running these detection and remediation scripts separately for each of the guidelines, we’d like to see a module or tool that leverages the assessment and remediation code to run as a whole—say, something schedulable that reports each time period on the security “hardness” of your environment, like Alan Renouf’s vCheck-vSphere (https://github.com/alanrenouf/vCheck-vSphere) but with a security focus (we could call it vSecCheck).

While more desirable, creating such a tool is beyond the scope of this chapter. Let us know on the book’s web page (see www.wiley.com/go/vmwarevspherepowercli2e) if there is interest in such a framework, and we will try to oblige. Or, start such a project, make it open (on GitHub perhaps), and let everyone know so that we all can contribute to your project!

Enjoy making your vSphere environment more secure with the help of PowerCLI.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset