This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

vSphere

Performing compliance automation tasks for vSphere.

1 - Audit vSphere 8

Auditing vSphere 8 for STIG Compliance

Overview

Auditing vSphere for STIG compliance involves scanning ESXi, Virtual Machines, vCenter, and the vCenter appliance.

When auditing vSphere we will split up tasks between product and appliance based controls which are defined as follows:

  • Product Control: Configurations that interact with the Product via the User Interface or API that are exposed to administrators. Whether these are Default or Non-Default, the risk of mis-configuration effecting availability of the product is low but could impact how the environment is operated if not assessed.
  • Appliance Control: Appliance controls deal with the underlying components (databases, web servers, Photon OS, etc) that make up the product. Altering these add risk to product availability if precautionary steps and care in implementation are not taken. Identifying and relying on Default settings in this category makes this category less risky (Default Appliance Controls should be seen as a positive).

To audit vSphere using InSpec we utilize the VMware transport(train-vmware) which connects to vCenter via PowerCLI and performs queries. For the vCenter appliance the auditing is performed via SSH. It is recommended to disable SSH on vCenter after the auditing is complete.

Prerequisites

Versions listed below were used for this documentation. Other versions of these tools may work as well but if issues are found it is recommended to try the versions listed here.

  • Powershell 7.3.4/PowerCLI 13.1 or newer
  • VMware.Vsphere.SsoAdmin PowerCLI Module 1.3.9 or newer
  • InSpec/Cinc Auditor 6.6.0
  • train-vmware 0.2.0
  • SAF CLI 1.4.0
  • STIG Viewer 2.17
  • A vSphere 8.x U1 or newer environment.
  • An account with sufficient privileges to view SSO configuration in vCenter.
  • Example distributed switches, VMs, and a content library were created in the testbed to produce audit results for those objects.

Assumptions

  • Commands are being ran from a Linux machine. Windows will also work but paths and commands may need to be adjusted from the examples.
  • The DOD Compliance and Automation repository downloaded and extracted to /usr/share/stigs.
  • CINC Auditor is used in lieu of InSpec. If InSpec is used replace cinc-auditor with inspec when running commands.

Install the custom VMware transport for InSpec

To extend the functionality of the VMware transport that ships with InSpec we have created a custom one that also incorporates the VMware.Vsphere.SsoAdmin module to extend automation coverage to the vCenter SSO STIG controls.

To install the plugin that is included with the vmware-vsphere-8.0-stig-baseline profile, do the following:

# Install the custom train-vmware plugin. Update the path to the gem as needed. The command will be the same on Windows and Linux.
> cinc-auditor plugin install /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/inspec/vmware-vsphere-8.0-stig-baseline/train-vmware-0.2.0.gem

# To verify the installation
> cinc-auditor plugin list

┌────────────────────────────────────────┬─────────┬──────────────┬─────────┬────────────────────────────────────────────────────────────────────────┐
              Plugin Name                Version      Via       ApiVer                                Description                               
├────────────────────────────────────────┼─────────┼──────────────┼─────────┼────────────────────────────────────────────────────────────────────────┤
 inspec-compliance                       6.6.0    core          2        Plugin to perform operations with Chef Automate                        
 inspec-habitat                          6.6.0    core          2        Plugin to create/upload habitat package                                
 inspec-init                             6.6.0    core          2        Plugin for scaffolding profile, plugin or a resource                   
 inspec-license                          6.6.0    core          2        Plugin to list user licenses.                                          
 inspec-parallel                         6.6.0    core          2        Plugin to handle parallel InSpec scan operations over multiple targets 
 inspec-plugin-manager-cli               6.6.0    core          2        CLI plugin for InSpec                                                  
 inspec-reporter-html2                   6.6.0    core          2        Improved HTML reporter plugin                                          
 inspec-reporter-json-min                6.6.0    core          2        Json-min json reporter plugin                                          
 inspec-reporter-junit                   6.6.0    core          2        JUnit XML reporter plugin                                              
 inspec-sign                             6.6.0    core          2                                                                               
 inspec-streaming-reporter-progress-bar  6.6.0    core          2        Displays a real-time progress bar and control title as output          
 inspec-supermarket                      6.6.0    core          0                                                                               
 train-aws                               0.2.36   gem (system)  train-1  AWS API Transport for Train                                            
 train-habitat                           0.2.22   gem (system)  train-1  Habitat API Transport for Train                                        
 train-kubernetes                        0.1.12   gem (system)  train-1  Train Kubernetes                                                       
 train-vmware                            0.2.0    gem (user)    train-1  Train Plugin for VMware PowerCLI                                       
 train-winrm                             0.2.13   gem (system)  train-1  Windows WinRM API Transport for Train                                  
└────────────────────────────────────────┴─────────┴──────────────┴─────────┴────────────────────────────────────────────────────────────────────────┘
 17 plugin(s) total

Auditing vSphere (Product Controls)

Setup environment variables for vCenter connection

Connectivity to vCenter is established via environment variables. Take care to clear your history and close the Powershell session to avoid any credentials left in memory/history.

#Enter Powershell
pwsh

# Note: VISERVER is referencing vCenter and not an ESXi host.
$env:VISERVER='10.186.30.81'
$env:VISERVER_USERNAME='Administrator@vsphere.local'
$env:VISERVER_PASSWORD='password'

Note: If your password has a single ’ in it you must substitute it with ’’’’ for it to be properly escaped all the way through the process.

Auditing ESXi

Update profile inputs

Included in the vmware-vsphere-8.0-stig-baseline is an example inputs-example.yml file with variables relevant to ESXi. This is used to provide InSpec with values specific to the environment being audited.

Open the inputs file for editing.

# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Edit the inputs file
vi inputs-example.yml
# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Edit the inputs file
vi inputs-example.yml

Update the inputs as shown below with values relevant to your environment.

# Choose whether to scan a single host, all hosts in a cluster, or all hosts in vCenter.
vmhostName: '10.186.25.26'
cluster: ''
allesxi: false
# Set to true if hosts are joined to active directory for authentication
adJoined: false
# If ESXi is joined to AD, enter the AD group that has administrative access to ESXi.
adAdminGroup: 'MyAdAdminGroup'
# Enter the environment specific syslog server ESXi should be forwarding logs to
syslogServer: 'tcp://log.test.local:514'
# Enter the environment specific time servers.
esxiNtpServers:
  - 'time-a-g.nist.gov'
  - 'time-b-g.nist.gov'
# Enter the environment specific vMotion VLAN Id.
vMotionVlanId: '100'
# Enter the environment specific Management VLAN Id.
mgtVlanId: '101'
# Enter an array of users that should be in the lockdown mode exceptions list.
exceptionUsers:
  - root
  - dcui
# If snmp is used in the environment change to true.
snmpEnabled: 'false'
# Enter the latest build number for ESXi.
esxiBuildNumber: '22380479'
# Choose whether to scan a single host, all hosts in a cluster, or all hosts in vCenter.
vmhostName: '10.186.25.26'
cluster: ''
allesxi: false
# Set to true if hosts are joined to active directory for authentication
adJoined: false
# If ESXi is joined to AD, enter the AD group that has administrative access to ESXi.
adAdminGroup: 'MyAdAdminGroup'
# Enter the environment specific syslog server ESXi should be forwarding logs to
syslogServer: 'tcp://log.test.local:514'
# Enter the environment specific time servers.
esxiNtpServers:
  - 'time-a-g.nist.gov'
  - 'time-b-g.nist.gov'
# Enter the environment specific vMotion VLAN Id.
vMotionVlanId: '100'
# Enter the environment specific Management VLAN Id.
mgtVlanId: '101'
# Enter an array of users that should be in the lockdown mode exceptions list.
exceptionUsers:
  - root
  - dcui
# If snmp is used in the environment change to true.
snmpEnabled: 'false'
# Enter the latest build number for ESXi.
esxiBuildNumber: '21813344'

Run the audit

In this example we will be scanning a single ESXi host attached to the target vCenter, specifying an inputs file, enabling enhanced outcomes in InSpec, and outputting a report to the CLI and to a JSON file.

# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Run the audit
> cinc-auditor exec ./esxi/ -t vmware:// --show-progress --enhanced-outcomes --input-file ./inputs-example.yml --reporter cli json:/tmp/reports/MyESXi8Report.json

# Shown below is the last part of the output at the CLI.
  [N/A]  ESXI-80-000241: The ESXi host must not use the default Active Directory ESX Admin group.
     [SKIP]  The ESXi host 10.186.25.26 is not joined to AD, so this control is not applicable.
  [PASS]  ESXI-80-000243: The ESXi host must configure a persistent log location for all locally stored logs.
     [PASS]  PowerCLI Command: $vmhost = Get-VMHost -Name 10.186.25.26; $esxcli = Get-EsxCli -VMHost $vmhost -V2; $esxcli.system.syslog.config.get.Invoke() | Select-Object -ExpandProperty LocalLogOutputIsPersistent stdout.strip is expected to cmp == "true"
  [FAIL]  ESXI-80-000244: The ESXi host must enforce the exclusive running of executables from approved VIBs.
     [FAIL]  PowerCLI Command: Get-VMHost -Name 10.186.25.26 | Get-AdvancedSetting -Name VMkernel.Boot.execInstalledOnly | Select-Object -ExpandProperty Value stdout.strip is expected to cmp == "true"

     expected: true
          got: False

     (compared using `cmp` matcher)

  [PASS]  ESXI-80-000245: The ESXi host must use sufficient entropy for cryptographic operations.
     [PASS]  PowerCLI Command: $vmhost = Get-VMHost -Name 10.186.25.26; $esxcli = Get-EsxCli -VMHost $vmhost -V2; $esxcli.system.settings.kernel.list.invoke()| Where {$_.Name -eq "disableHwrng"} | Select-Object -ExpandProperty Configured stdout.strip is expected to cmp == "FALSE"
     [PASS]  PowerCLI Command: $vmhost = Get-VMHost -Name 10.186.25.26; $esxcli = Get-EsxCli -VMHost $vmhost -V2; $esxcli.system.settings.kernel.list.invoke()| Where {$_.Name -eq "entropySources"} | Select-Object -ExpandProperty Configured stdout.strip is expected to cmp == "0"
  [PASS]  ESXI-80-000246: The ESXi host must not enable log filtering.
     [PASS]  PowerCLI Command: $vmhost = Get-VMHost -Name 10.186.25.26; $esxcli = Get-EsxCli -VMHost $vmhost -V2; $esxcli.system.syslog.config.logfilter.get.invoke() | Select-Object -ExpandProperty LogFilteringEnabled stdout.strip is expected to cmp == "false"

Profile Summary: 29 successful controls, 26 control failures, 18 controls not reviewed, 4 controls not applicable, 0 controls have error
Test Summary: 41 successful, 51 failures, 23 skipped
# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Run the audit
> cinc-auditor exec ./esxi/ -t vmware:// --show-progress --enhanced-outcomes --input-file ./inputs-example.yml --reporter cli json:/tmp/reports/MyESXi8Report.json

# Shown below is the last part of the output at the CLI.
  [N/A]  ESXI-80-000241: The ESXi host must not use the default Active Directory ESX Admin group.
     [SKIP]  The ESXi host 10.186.25.26 is not joined to AD, so this control is not applicable.
  [PASS]  ESXI-80-000243: The ESXi host must configure a persistent log location for all locally stored logs.
     [PASS]  PowerCLI Command: $vmhost = Get-VMHost -Name 10.186.25.26; $esxcli = Get-EsxCli -VMHost $vmhost -V2; $esxcli.system.syslog.config.get.Invoke() | Select-Object -ExpandProperty LocalLogOutputIsPersistent stdout.strip is expected to cmp == "true"
  [FAIL]  ESXI-80-000244: The ESXi host must enforce the exclusive running of executables from approved VIBs.
     [FAIL]  PowerCLI Command: Get-VMHost -Name 10.186.25.26 | Get-AdvancedSetting -Name VMkernel.Boot.execInstalledOnly | Select-Object -ExpandProperty Value stdout.strip is expected to cmp == "true"

     expected: true
          got: False

     (compared using `cmp` matcher)

  [PASS]  ESXI-80-000245: The ESXi host must use sufficient entropy for cryptographic operations.
     [PASS]  PowerCLI Command: $vmhost = Get-VMHost -Name 10.186.25.26; $esxcli = Get-EsxCli -VMHost $vmhost -V2; $esxcli.system.settings.kernel.list.invoke()| Where {$_.Name -eq "disableHwrng"} | Select-Object -ExpandProperty Configured stdout.strip is expected to cmp == "FALSE"
     [PASS]  PowerCLI Command: $vmhost = Get-VMHost -Name 10.186.25.26; $esxcli = Get-EsxCli -VMHost $vmhost -V2; $esxcli.system.settings.kernel.list.invoke()| Where {$_.Name -eq "entropySources"} | Select-Object -ExpandProperty Configured stdout.strip is expected to cmp == "0"
  [PASS]  ESXI-80-000246: The ESXi host must not enable log filtering.
     [PASS]  PowerCLI Command: $vmhost = Get-VMHost -Name 10.186.25.26; $esxcli = Get-EsxCli -VMHost $vmhost -V2; $esxcli.system.syslog.config.logfilter.get.invoke() | Select-Object -ExpandProperty LogFilteringEnabled stdout.strip is expected to cmp == "false"

Profile Summary: 29 successful controls, 26 control failures, 18 controls not reviewed, 4 controls not applicable, 0 controls have error
Test Summary: 41 successful, 51 failures, 23 skipped

Auditing Virtual Machines

Update profile inputs

Included in the vmware-vsphere-8.0-stig-baseline is an example inputs-example.yml file with variables relevant to VMs. This is used to provide InSpec with values specific to the environment being audited.

Open the inputs file for editing.

# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Edit the inputs file
vi inputs-example.yml
# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Edit the inputs file
vi inputs-example.yml

Update the inputs as shown below with values relevant to your environment.

# Choose whether to scan a single VM or all VMs in vCenter.
vmName: ""
allvms: true
# Choose whether to scan a single VM or all VMs in vCenter.
vmName: ""
allvms: true

Run the audit

In this example we will be scanning all VMs in the target vCenter, specifying an inputs file, enabling enhanced outcomes in InSpec, and outputting a report to the CLI and to a JSON file.

# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Run the audit
cinc-auditor exec ./vm/ -t vmware:// --show-progress --enhanced-outcomes --input-file ./inputs-example.yml --reporter cli json:/tmp/reports/MyVMs8Report.json

# Shown below is the last part of the output at the CLI.
  [PASS]  VMCH-80-000207: Virtual machines (VMs) must enable logging.
     [PASS]  VM: stig vm2 is expected to cmp == "true"
     [PASS]  VM: stigvm1 is expected to cmp == "true"
     [PASS]  VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c is expected to cmp == "true"
     [PASS]  VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d is expected to cmp == "true"
     [PASS]  VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 is expected to cmp == "true"
  [PASS]  VMCH-80-000208: Virtual machines (VMs) must not use independent, non-persistent disks.
     [PASS]  Checking the VM: stig vm2 for Non-Persistent Hard Disks is expected not to cmp == "IndependentNonPersistent"
     [PASS]  Checking the VM: stigvm1 for Non-Persistent Hard Disks is expected not to cmp == "IndependentNonPersistent"
     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for Non-Persistent Hard Disks is expected not to cmp == "IndependentNonPersistent"
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for Non-Persistent Hard Disks is expected not to cmp == "IndependentNonPersistent"
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for Non-Persistent Hard Disks is expected not to cmp == "IndependentNonPersistent"
  [PASS]  VMCH-80-000209: Virtual machines (VMs) must remove unneeded floppy devices.
     [PASS]  Checking the VM: stig vm2 for Floppy drives is expected to be empty
     [PASS]  Checking the VM: stigvm1 for Floppy drives is expected to be empty
     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for Floppy drives is expected to be empty
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for Floppy drives is expected to be empty
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for Floppy drives is expected to be empty
  [PASS]  VMCH-80-000210: Virtual machines (VMs) must remove unneeded CD/DVD devices.
     [PASS]  Checking the VM: stig vm2 for CD/DVD drives is expected to cmp == "false"
     [PASS]  Checking the VM: stigvm1 for CD/DVD drives is expected to cmp == "false"
     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for CD/DVD drives is expected to be empty
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for CD/DVD drives is expected to be empty
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for CD/DVD drives is expected to be empty
  [PASS]  VMCH-80-000211: Virtual machines (VMs) must remove unneeded parallel devices.
     [PASS]  Checking the VM: stig vm2 for parallel devices is expected not to match "Parallel"
     [PASS]  Checking the VM: stigvm1 for parallel devices is expected not to match "Parallel"
     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for parallel devices is expected not to match "Parallel"
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for parallel devices is expected not to match "Parallel"
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for parallel devices is expected not to match "Parallel"
  [PASS]  VMCH-80-000212: Virtual machines (VMs) must remove unneeded serial devices.
     [PASS]  Checking the VM: stig vm2 for serial devices is expected not to match "Serial"
     [PASS]  Checking the VM: stigvm1 for serial devices is expected not to match "Serial"
     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for serial devices is expected not to match "Serial"
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for serial devices is expected not to match "Serial"
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for serial devices is expected not to match "Serial"
  [FAIL]  VMCH-80-000213: Virtual machines (VMs) must remove unneeded USB devices. (2 failed)
     [FAIL]  Checking the VM: stig vm2 for USB devices is expected not to match "USB"
     expected "IDE 0\r\nIDE 1\r\nPS2 controller 0\r\nPCI controller 0\r\nSIO controller 0\r\nKeyboard \r\nPointing ...er \r\nSCSI controller 0\r\nSATA controller 0\r\nCD/DVD drive 1\r\nHard disk 1\r\nNetwork adapter 1" not to match "USB"

     [FAIL]  Checking the VM: stigvm1 for USB devices is expected not to match "USB"
     expected "IDE 0\r\nIDE 1\r\nPS2 controller 0\r\nPCI controller 0\r\nSIO controller 0\r\nKeyboard \r\nPointing ...er \r\nSCSI controller 0\r\nSATA controller 0\r\nCD/DVD drive 1\r\nHard disk 1\r\nNetwork adapter 1" not to match "USB"

     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for USB devices is expected not to match "USB"
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for USB devices is expected not to match "USB"
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for USB devices is expected not to match "USB"
  [PASS]  VMCH-80-000214: Virtual machines (VMs) must disable DirectPath I/O devices when not required.
     [PASS]  Checking the VM: stig vm2 for PCI passthrough devices is expected to be empty
     [PASS]  Checking the VM: stigvm1 for PCI passthrough devices is expected to be empty
     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for PCI passthrough devices is expected to be empty
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for PCI passthrough devices is expected to be empty
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for PCI passthrough devices is expected to be empty

Profile Summary: 23 successful controls, 2 control failures, 0 controls not reviewed, 0 controls not applicable, 0 controls have error
Test Summary: 121 successful, 4 failures, 0 skipped
# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Run the audit
cinc-auditor exec ./vm/ -t vmware:// --show-progress --enhanced-outcomes --input-file ./inputs-example.yml --reporter cli json:/tmp/reports/MyVMs8Report.json

# Shown below is the last part of the output at the CLI.
  [PASS]  VMCH-80-000207: Virtual machines (VMs) must enable logging.
     [PASS]  VM: stig vm2 is expected to cmp == "true"
     [PASS]  VM: stigvm1 is expected to cmp == "true"
     [PASS]  VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c is expected to cmp == "true"
     [PASS]  VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d is expected to cmp == "true"
     [PASS]  VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 is expected to cmp == "true"
  [PASS]  VMCH-80-000208: Virtual machines (VMs) must not use independent, non-persistent disks.
     [PASS]  Checking the VM: stig vm2 for Non-Persistent Hard Disks is expected not to cmp == "IndependentNonPersistent"
     [PASS]  Checking the VM: stigvm1 for Non-Persistent Hard Disks is expected not to cmp == "IndependentNonPersistent"
     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for Non-Persistent Hard Disks is expected not to cmp == "IndependentNonPersistent"
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for Non-Persistent Hard Disks is expected not to cmp == "IndependentNonPersistent"
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for Non-Persistent Hard Disks is expected not to cmp == "IndependentNonPersistent"
  [PASS]  VMCH-80-000209: Virtual machines (VMs) must remove unneeded floppy devices.
     [PASS]  Checking the VM: stig vm2 for Floppy drives is expected to be empty
     [PASS]  Checking the VM: stigvm1 for Floppy drives is expected to be empty
     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for Floppy drives is expected to be empty
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for Floppy drives is expected to be empty
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for Floppy drives is expected to be empty
  [PASS]  VMCH-80-000210: Virtual machines (VMs) must remove unneeded CD/DVD devices.
     [PASS]  Checking the VM: stig vm2 for CD/DVD drives is expected to cmp == "false"
     [PASS]  Checking the VM: stigvm1 for CD/DVD drives is expected to cmp == "false"
     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for CD/DVD drives is expected to be empty
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for CD/DVD drives is expected to be empty
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for CD/DVD drives is expected to be empty
  [PASS]  VMCH-80-000211: Virtual machines (VMs) must remove unneeded parallel devices.
     [PASS]  Checking the VM: stig vm2 for parallel devices is expected not to match "Parallel"
     [PASS]  Checking the VM: stigvm1 for parallel devices is expected not to match "Parallel"
     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for parallel devices is expected not to match "Parallel"
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for parallel devices is expected not to match "Parallel"
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for parallel devices is expected not to match "Parallel"
  [PASS]  VMCH-80-000212: Virtual machines (VMs) must remove unneeded serial devices.
     [PASS]  Checking the VM: stig vm2 for serial devices is expected not to match "Serial"
     [PASS]  Checking the VM: stigvm1 for serial devices is expected not to match "Serial"
     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for serial devices is expected not to match "Serial"
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for serial devices is expected not to match "Serial"
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for serial devices is expected not to match "Serial"
  [FAIL]  VMCH-80-000213: Virtual machines (VMs) must remove unneeded USB devices. (2 failed)
     [FAIL]  Checking the VM: stig vm2 for USB devices is expected not to match "USB"
     expected "IDE 0\r\nIDE 1\r\nPS2 controller 0\r\nPCI controller 0\r\nSIO controller 0\r\nKeyboard \r\nPointing ...er \r\nSCSI controller 0\r\nSATA controller 0\r\nCD/DVD drive 1\r\nHard disk 1\r\nNetwork adapter 1" not to match "USB"

     [FAIL]  Checking the VM: stigvm1 for USB devices is expected not to match "USB"
     expected "IDE 0\r\nIDE 1\r\nPS2 controller 0\r\nPCI controller 0\r\nSIO controller 0\r\nKeyboard \r\nPointing ...er \r\nSCSI controller 0\r\nSATA controller 0\r\nCD/DVD drive 1\r\nHard disk 1\r\nNetwork adapter 1" not to match "USB"

     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for USB devices is expected not to match "USB"
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for USB devices is expected not to match "USB"
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for USB devices is expected not to match "USB"
  [PASS]  VMCH-80-000214: Virtual machines (VMs) must disable DirectPath I/O devices when not required.
     [PASS]  Checking the VM: stig vm2 for PCI passthrough devices is expected to be empty
     [PASS]  Checking the VM: stigvm1 for PCI passthrough devices is expected to be empty
     [PASS]  Checking the VM: vCLS-1446f2cc-b6b7-4778-84b7-f73f758dd46c for PCI passthrough devices is expected to be empty
     [PASS]  Checking the VM: vCLS-28a51340-7070-4437-b4b1-a87b7480ac7d for PCI passthrough devices is expected to be empty
     [PASS]  Checking the VM: vCLS-b680b5a0-5434-48a0-8420-82c95e5ab481 for PCI passthrough devices is expected to be empty

Profile Summary: 23 successful controls, 2 control failures, 0 controls not reviewed, 0 controls not applicable, 0 controls have error
Test Summary: 121 successful, 4 failures, 0 skipped

Auditing vCenter

Update profile inputs

Included in the vmware-vsphere-8.0-stig-baseline is an example inputs-example.yml file with variables relevant to vCenter. This is used to provide InSpec with values specific to the environment being audited.

Open the inputs file for editing.

# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Edit the inputs file
vi inputs-example.yml
# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Edit the inputs file
vi inputs-example.yml

Update the inputs as shown below with values relevant to your environment.

# Enter the environment specific syslog server vCenter should be forwarding logs to.
syslogServers:
  - 'loginsight.vmware.com'
  - 'syslog.server2.com'
# Enter the environment specific time servers.
ntpServers:
  - 'time-a-g.nist.gov'
  - 'time-b-g.nist.gov'
# If an IPfix collector is used enter the IP.
ipfixCollectorAddress: ''
# List any users/groups that should be in the default roles that have crypto permissions. The default users/groups are provided below.
vcCryptoAdmins:
  - 'VSPHERE.LOCAL\Administrator'
  - 'VSPHERE.LOCAL\Administrators'
  - 'VSPHERE.LOCAL\vCLSAdmin'
# List any roles that are approved to have crypto permissions. The default roles are provided below.
vcCryptoRoles:
  - 'Admin'
  - 'NoTrustedAdmin'
  - 'vCLSAdmin'
  - 'vSphereKubernetesManager'
# Enter any approved users in the bash shell administrators users group
bashShellAdminUsers:
  - 'Administrator'
# Enter any approved group in the bash shell administrators group
bashShellAdminGroups: []
# Enter any approved users in the trusted admin users group
trustedAdminUsers: []
# Enter any approved users in the trusted admin group
trustedAdminGroups: []
# Set to false if file based backups are used via the VAMI
backup3rdParty: false
# Enter the environment specific syslog server vCenter should be forwarding logs to.
syslogServers:
  - 'loginsight.vmware.com'
  - 'syslog.server2.com'
# Enter the environment specific time servers.
ntpServers:
  - 'time-a-g.nist.gov'
  - 'time-b-g.nist.gov'
# If an IPfix collector is used enter the IP.
ipfixCollectorAddress: ''
# List any users/groups that should be in the default roles that have crypto permissions. The default users/groups are provided below.
vcCryptoAdmins:
  - 'VSPHERE.LOCAL\Administrator'
  - 'VSPHERE.LOCAL\Administrators'
  - 'VSPHERE.LOCAL\vCLSAdmin'
# List any roles that are approved to have crypto permissions. The default roles are provided below.
vcCryptoRoles:
  - 'Admin'
  - 'NoTrustedAdmin'
  - 'vCLSAdmin'
  - 'vSphereKubernetesManager'
# Enter any approved users in the bash shell administrators users group
bashShellAdminUsers:
  - 'Administrator'
# Enter any approved group in the bash shell administrators group
bashShellAdminGroups: []
# Enter any approved users in the trusted admin users group
trustedAdminUsers: []
# Enter any approved users in the trusted admin group
trustedAdminGroups: []
# Set to false if file based backups are used via the VAMI
backup3rdParty: false

Run the audit

In this example we will be scanning vCenter controls in the target vCenter, specifying an inputs file, enabling enhanced outcomes in InSpec, and outputting a report to the CLI and to a JSON file.

# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Run the audit
cinc-auditor exec ./vcenter/ -t vmware:// --show-progress --enhanced-outcomes --input-file ./inputs-example.yml --reporter cli json:/tmp/reports/MyvCenter8Report.json

# Shown below is the last part of the output at the CLI.
  [PASS]  VCSA-80-000302: The vCenter Server must reset port configuration when virtual machines are disconnected.
     [PASS]  PowerCLI Command: (Get-VDPortgroup -Name "VDSwitch STIG 1-DVUplinks-40").ExtensionData.Config.Policy.PortConfigResetAtDisconnect stdout.strip is expected to cmp == "True"
     [PASS]  PowerCLI Command: (Get-VDPortgroup -Name "VD PG 1").ExtensionData.Config.Policy.PortConfigResetAtDisconnect stdout.strip is expected to cmp == "True"
     [PASS]  PowerCLI Command: (Get-VDPortgroup -Name "VD PG 2").ExtensionData.Config.Policy.PortConfigResetAtDisconnect stdout.strip is expected to cmp == "True"
     [PASS]  PowerCLI Command: (Get-VDPortgroup -Name "VDSwitch STIG 2-DVUplinks-44").ExtensionData.Config.Policy.PortConfigResetAtDisconnect stdout.strip is expected to cmp == "True"
     [PASS]  PowerCLI Command: (Get-VDPortgroup -Name "VD PG 3").ExtensionData.Config.Policy.PortConfigResetAtDisconnect stdout.strip is expected to cmp == "True"
     [PASS]  PowerCLI Command: (Get-VDPortgroup -Name "VD PG 4").ExtensionData.Config.Policy.PortConfigResetAtDisconnect stdout.strip is expected to cmp == "True"
  [FAIL]  VCSA-80-000303: The vCenter Server must disable Secure Shell (SSH) access.
     [FAIL]  True is expected not to cmp == "true"

     expected: true
          got: True

     (compared using `cmp` matcher)

  [FAIL]  VCSA-80-000304: The vCenter Server must enable data in transit encryption for vSAN.
     [FAIL]  PowerCLI Command: $vsanclusterconf = Get-VsanView -Id VsanVcClusterConfigSystem-vsan-cluster-config-system; $vsanclusterconf.VsanClusterGetConfig((Get-Cluster -Name cluster0).ExtensionData.MoRef).DataInTransitEncryptionConfig.Enabled stdout.strip is expected to cmp == "true"

     expected: true
          got:

     (compared using `cmp` matcher)

Profile Summary: 25 successful controls, 22 control failures, 16 controls not reviewed, 3 controls not applicable, 0 controls have error
Test Summary: 136 successful, 26 failures, 20 skipped
# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Run the audit
cinc-auditor exec ./vcenter/ -t vmware:// --show-progress --enhanced-outcomes --input-file ./inputs-example.yml --reporter cli json:/tmp/reports/MyvCenter8Report.json

# Shown below is the last part of the output at the CLI.
  [PASS]  VCSA-80-000302: The vCenter Server must reset port configuration when virtual machines are disconnected.
     [PASS]  PowerCLI Command: (Get-VDPortgroup -Name "VDSwitch STIG 1-DVUplinks-40").ExtensionData.Config.Policy.PortConfigResetAtDisconnect stdout.strip is expected to cmp == "True"
     [PASS]  PowerCLI Command: (Get-VDPortgroup -Name "VD PG 1").ExtensionData.Config.Policy.PortConfigResetAtDisconnect stdout.strip is expected to cmp == "True"
     [PASS]  PowerCLI Command: (Get-VDPortgroup -Name "VD PG 2").ExtensionData.Config.Policy.PortConfigResetAtDisconnect stdout.strip is expected to cmp == "True"
     [PASS]  PowerCLI Command: (Get-VDPortgroup -Name "VDSwitch STIG 2-DVUplinks-44").ExtensionData.Config.Policy.PortConfigResetAtDisconnect stdout.strip is expected to cmp == "True"
     [PASS]  PowerCLI Command: (Get-VDPortgroup -Name "VD PG 3").ExtensionData.Config.Policy.PortConfigResetAtDisconnect stdout.strip is expected to cmp == "True"
     [PASS]  PowerCLI Command: (Get-VDPortgroup -Name "VD PG 4").ExtensionData.Config.Policy.PortConfigResetAtDisconnect stdout.strip is expected to cmp == "True"
  [FAIL]  VCSA-80-000303: The vCenter Server must disable Secure Shell (SSH) access.
     [FAIL]  True is expected not to cmp == "true"

     expected: true
          got: True

     (compared using `cmp` matcher)

  [FAIL]  VCSA-80-000304: The vCenter Server must enable data in transit encryption for vSAN.
     [FAIL]  PowerCLI Command: $vsanclusterconf = Get-VsanView -Id VsanVcClusterConfigSystem-vsan-cluster-config-system; $vsanclusterconf.VsanClusterGetConfig((Get-Cluster -Name cluster0).ExtensionData.MoRef).DataInTransitEncryptionConfig.Enabled stdout.strip is expected to cmp == "true"

     expected: true
          got:

     (compared using `cmp` matcher)

Profile Summary: 25 successful controls, 22 control failures, 16 controls not reviewed, 3 controls not applicable, 0 controls have error
Test Summary: 136 successful, 26 failures, 20 skipped

Run a combined scan for all vSphere product controls

Instead of running each STIG for product controls separately you can also run all of the vCenter, ESXi, and VM controls for a combined report.

# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Run the script
cinc-auditor exec . -t vmware:// --show-progress --enhanced-outcomes --input-file ./inputs-example.yml --reporter cli json:/tmp/reports/MyvSphere8Report.json
# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/inspec/vmware-vsphere-8.0-stig-baseline

# Run the audit
cinc-auditor exec . -t vmware:// --show-progress --enhanced-outcomes --input-file ./inputs-example.yml --reporter cli json:/tmp/reports/MyvSphere8Report.json

InSpec runner scripts

For accreditation purposes there may be a requirement to produce a CKL file for each ESXi host and/or VM. We have also created a PowerCLI script that acts as a runner for InSpec to loop through a list of hosts or VMs, then produce a json report for each, and if the SAF CLI is installed also create a CKL file.

With this script you can also provide an attestation file that will be applied to the results and incorporated into the CKL file.

Using the ESXi runner script

To use the runner script, do the following:

# Enter Powershell
pwsh

# If not already previously done setup the credential for the vCenter connection.
# Note: VISERVER is referencing vCenter and not an ESXi host.
$env:VISERVER='10.186.30.81'
$env:VISERVER_USERNAME='Administrator@vsphere.local'
$env:VISERVER_PASSWORD='password'

# Navigate to the powercli folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/powercli

# Run the script
./VMware_vSphere_8.0_STIG_ESXi_InSpec_Runner.ps1 -vcenter 10.186.30.81 -reportPath /tmp/reports -inspecPath /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/inspec/vmware-vsphere-8.0-stig-baseline -inputsfile ./vmware-vsphere-8.0-stig-esxi-inspec-runner-inputs-example.yml

# You will be prompted for credentials to vCenter. This is to connect via PowerCLI before running InSpec to collect all of the host names to use as an input to InSpec for each individual host audit.
10:08:10 AM ...Enter credentials to connect to vCenter

PowerShell credential request
Enter credentials for vCenter
User: administrator@vsphere.local
Password for user administrator@vsphere.local: ****************

10:08:23 AM ...Connecting to vCenter Server 10.186.30.81
10:08:26 AM ...Getting PowerCLI objects for all ESXi hosts in vCenter: 10.186.30.81
10:08:27 AM ...Validated path for report at C:\Inspec\Reports\Runner
10:08:27 AM ...Report path is C:\Inspec\Reports\Runner and report file is C:\Inspec\Reports\Runner\VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.13-6-7-2023_10-8-4.json
10:08:27 AM ...Running InSpec exec against 10.186.16.13 with inspec exec $inspecPath -t vmware:// --input vmhostName=$name --input-file $inputsFile --show-progress --reporter=json:$reportFile
FFFF...F...*.FF*..FFFFF.**.*.FF*.FFF.F..F*F.**********............F..*F.FF.F*..FFFF**FFFFFFFFFFFFFFFFF.FFFFF**.F...
10:10:06 AM ...Detected saf cli...generating STIG Viewer Checklist for 10.186.16.13
10:10:11 AM ...Report path is C:\Inspec\Reports\Runner and report file is C:\Inspec\Reports\Runner\VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.134-6-7-2023_10-8-4.json
10:10:11 AM ...Running InSpec exec against 10.186.16.134 with inspec exec $inspecPath -t vmware:// --input vmhostName=$name --input-file $inputsFile --show-progress --reporter=json:$reportFile
FFFF...F...*.FF*..FFFFF.**.*.FF*.FFF.F..F*F.**********............F..*F.FF.F*..FFFF**FFFFFFFFFFFFFFFFF.FFFFF**.F...
10:11:51 AM ...Detected saf cli...generating STIG Viewer Checklist for 10.186.16.134
10:11:56 AM ...Report path is C:\Inspec\Reports\Runner and report file is C:\Inspec\Reports\Runner\VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.25.26-6-7-2023_10-8-4.json
10:11:56 AM ...Running InSpec exec against 10.186.25.26 with inspec exec $inspecPath -t vmware:// --input vmhostName=$name --input-file $inputsFile --show-progress --reporter=json:$reportFile
FFFF...F...*.FF*..FFFFF.**.*.FF*.FFF.F..F*F.**********............F..*F.FF.F*..FFFF**FFFFFFFFFFFFFFFFF.FFFFF**.F...
10:13:26 AM ...Detected saf cli...generating STIG Viewer Checklist for 10.186.25.26
10:13:30 AM ...Disconnecting from vCenter

# Resulting output
ls /tmp/reports

    Directory: /tmp/reports

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/7/2023 10:10 AM         473286 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.13-6-7-2023_10-8-4.ckl
-a---            6/7/2023 10:10 AM         521076 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.13-6-7-2023_10-8-4.json
-a---            6/7/2023 10:11 AM         473364 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.134-6-7-2023_10-8-4.ckl
-a---            6/7/2023 10:11 AM         521228 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.134-6-7-2023_10-8-4.json
-a---            6/7/2023 10:13 AM         473286 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.25.26-6-7-2023_10-8-4.ckl
-a---            6/7/2023 10:13 AM         521082 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.25.26-6-7-2023_10-8-4.json

# If you want to specify a attestation file to incorporate into the CKL results you can add the attestation argument to the command as follows:
./VMware_vSphere_8.0_STIG_ESXi_InSpec_Runner.ps1 -vcenter 10.186.30.81 -reportPath /tmp/reports -inspecPath /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/inspec/vmware-vsphere-8.0-stig-baseline -inputsfile ./vmware-vsphere-8.0-stig-esxi-inspec-runner-inputs-example.yml -attestationFile ./vmware-vsphere-8.0-stig-esxi-inspec-runner-attestation-example.yml

# Resulting output
ls /tmp/reports

    Directory: /tmp/reports

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/7/2023 10:39 AM         473326 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.13-6-7-2023_10-37-15_with_Attestations.ckl
-a---            6/7/2023 10:39 AM         592992 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.13-6-7-2023_10-37-15_with_Attestations.json
-a---            6/7/2023 10:39 AM         521084 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.13-6-7-2023_10-37-15.json
-a---            6/7/2023 10:41 AM         473404 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.134-6-7-2023_10-37-15_with_Attestations.ckl
-a---            6/7/2023 10:41 AM         593137 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.134-6-7-2023_10-37-15_with_Attestations.json
-a---            6/7/2023 10:40 AM         521230 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.134-6-7-2023_10-37-15.json
-a---            6/7/2023 10:42 AM         473326 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.25.26-6-7-2023_10-37-15_with_Attestations.ckl
-a---            6/7/2023 10:42 AM         592988 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.25.26-6-7-2023_10-37-15_with_Attestations.json
-a---            6/7/2023 10:42 AM         521082 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.25.26-6-7-2023_10-37-15.json
# Enter Powershell
pwsh

# If not already previously done setup the credential for the vCenter connection.
# Note: VISERVER is referencing vCenter and not an ESXi host.
$env:VISERVER='10.186.30.81'
$env:VISERVER_USERNAME='Administrator@vsphere.local'
$env:VISERVER_PASSWORD='password'

# Navigate to the powercli folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/powercli

# Run the script
./VMware_vSphere_8.0_STIG_ESXi_InSpec_Runner.ps1 -vcenter 10.186.30.81 -reportPath /tmp/reports -inspecPath /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/inspec/vmware-vsphere-8.0-stig-baseline -inputsfile ./vmware-vsphere-8.0-stig-esxi-inspec-runner-inputs-example.yml

# You will be prompted for credentials to vCenter. This is to connect via PowerCLI before running InSpec to collect all of the host names to use as an input to InSpec for each individual host audit.
10:08:10 AM ...Enter credentials to connect to vCenter

PowerShell credential request
Enter credentials for vCenter
User: administrator@vsphere.local
Password for user administrator@vsphere.local: ****************

10:08:23 AM ...Connecting to vCenter Server 10.186.30.81
10:08:26 AM ...Getting PowerCLI objects for all ESXi hosts in vCenter: 10.186.30.81
10:08:27 AM ...Validated path for report at C:\Inspec\Reports\Runner
10:08:27 AM ...Report path is C:\Inspec\Reports\Runner and report file is C:\Inspec\Reports\Runner\VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.13-6-7-2023_10-8-4.json
10:08:27 AM ...Running InSpec exec against 10.186.16.13 with inspec exec $inspecPath -t vmware:// --input vmhostName=$name --input-file $inputsFile --show-progress --reporter=json:$reportFile
FFFF...F...*.FF*..FFFFF.**.*.FF*.FFF.F..F*F.**********............F..*F.FF.F*..FFFF**FFFFFFFFFFFFFFFFF.FFFFF**.F...
10:10:06 AM ...Detected saf cli...generating STIG Viewer Checklist for 10.186.16.13
10:10:11 AM ...Report path is C:\Inspec\Reports\Runner and report file is C:\Inspec\Reports\Runner\VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.134-6-7-2023_10-8-4.json
10:10:11 AM ...Running InSpec exec against 10.186.16.134 with inspec exec $inspecPath -t vmware:// --input vmhostName=$name --input-file $inputsFile --show-progress --reporter=json:$reportFile
FFFF...F...*.FF*..FFFFF.**.*.FF*.FFF.F..F*F.**********............F..*F.FF.F*..FFFF**FFFFFFFFFFFFFFFFF.FFFFF**.F...
10:11:51 AM ...Detected saf cli...generating STIG Viewer Checklist for 10.186.16.134
10:11:56 AM ...Report path is C:\Inspec\Reports\Runner and report file is C:\Inspec\Reports\Runner\VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.25.26-6-7-2023_10-8-4.json
10:11:56 AM ...Running InSpec exec against 10.186.25.26 with inspec exec $inspecPath -t vmware:// --input vmhostName=$name --input-file $inputsFile --show-progress --reporter=json:$reportFile
FFFF...F...*.FF*..FFFFF.**.*.FF*.FFF.F..F*F.**********............F..*F.FF.F*..FFFF**FFFFFFFFFFFFFFFFF.FFFFF**.F...
10:13:26 AM ...Detected saf cli...generating STIG Viewer Checklist for 10.186.25.26
10:13:30 AM ...Disconnecting from vCenter

# Resulting output
ls /tmp/reports

    Directory: /tmp/reports

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/7/2023 10:10 AM         473286 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.13-6-7-2023_10-8-4.ckl
-a---            6/7/2023 10:10 AM         521076 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.13-6-7-2023_10-8-4.json
-a---            6/7/2023 10:11 AM         473364 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.134-6-7-2023_10-8-4.ckl
-a---            6/7/2023 10:11 AM         521228 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.134-6-7-2023_10-8-4.json
-a---            6/7/2023 10:13 AM         473286 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.25.26-6-7-2023_10-8-4.ckl
-a---            6/7/2023 10:13 AM         521082 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.25.26-6-7-2023_10-8-4.json

# If you want to specify a attestation file to incorporate into the CKL results you can add the attestation argument to the command as follows:
./VMware_vSphere_8.0_STIG_ESXi_InSpec_Runner.ps1 -vcenter 10.186.30.81 -reportPath /tmp/reports -inspecPath /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/inspec/vmware-vsphere-8.0-stig-baseline -inputsfile ./vmware-vsphere-8.0-stig-esxi-inspec-runner-inputs-example.yml -attestationFile ./vmware-vsphere-8.0-stig-esxi-inspec-runner-attestation-example.yml

# Resulting output
ls /tmp/reports

    Directory: /tmp/reports

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/7/2023 10:39 AM         473326 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.13-6-7-2023_10-37-15_with_Attestations.ckl
-a---            6/7/2023 10:39 AM         592992 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.13-6-7-2023_10-37-15_with_Attestations.json
-a---            6/7/2023 10:39 AM         521084 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.13-6-7-2023_10-37-15.json
-a---            6/7/2023 10:41 AM         473404 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.134-6-7-2023_10-37-15_with_Attestations.ckl
-a---            6/7/2023 10:41 AM         593137 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.134-6-7-2023_10-37-15_with_Attestations.json
-a---            6/7/2023 10:40 AM         521230 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.16.134-6-7-2023_10-37-15.json
-a---            6/7/2023 10:42 AM         473326 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.25.26-6-7-2023_10-37-15_with_Attestations.ckl
-a---            6/7/2023 10:42 AM         592988 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.25.26-6-7-2023_10-37-15_with_Attestations.json
-a---            6/7/2023 10:42 AM         521082 VMware_vSphere_8.0_STIG_ESXi_Inspec_Report_10.186.25.26-6-7-2023_10-37-15.json

Auditing vCenter (Appliance Controls)

Auditing the vCenter appliance is done over SSH which must be enabled for the scan.

Update the default shell for root

The default shell for root must be changed to /bin/bash before running. The appliance shell causes issues with some controls running.

# SSH to vCenter
Connected to service

    * List APIs: "help api list"
    * List Plugins: "help pi list"
    * Launch BASH: "shell"

Command> shell.set --enabled true
Command> shell
Shell access is granted to root
root@sc1-10-182-131-166 [ ~ ]# chsh -s /bin/bash root

Run the audit

In this example we will be scanning the vCenter appliance, specifying an inputs file, and outputting a report to the CLI and to a JSON file.

Updating the inputs file is not required for this profile but the inputs-vcsa-8.0.yml should be specified because it contains inputs for the Photon profile.

# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vcsa/inspec/vmware-vcsa-8.0-stig-baseline

# Run the audit
cinc-auditor exec . -t ssh://root@10.186.30.81 --password 'password' --show-progress --enhanced-outcomes --input-file ./inputs-vcsa-8.0.yml --reporter cli json:/tmp/reports/MyVCSA8Report.json

# Shown below is the last part of the output at the CLI.
  [PASS]  VCUI-80-000141: The vCenter UI service example applications must be removed.
     [PASS]  false is expected to cmp == "false"
  [PASS]  VCUI-80-000142: The vCenter UI service default ROOT web application must be removed.
     [PASS]  Command: `ls /usr/lib/vmware-vsphere-ui/server/webapps/ROOT` stdout.strip is expected to cmp == ""
  [PASS]  VCUI-80-000143: The vCenter UI service default documentation must be removed.
     [PASS]  false is expected to cmp == "false"
  [PASS]  VCUI-80-000151: The vCenter UI service must disable "ALLOW_BACKSLASH".
     [PASS]  is expected to be in nil and "false"
  [PASS]  VCUI-80-000152: The vCenter UI service must enable "ENFORCE_ENCODING_IN_GET_WRITER".
     [PASS]  is expected to be in nil and "true"
  [PASS]  VCUI-80-000154: The vCenter UI service manager webapp must be removed.
     [PASS]  false is expected to cmp == "false"
  [PASS]  VCUI-80-000155: The vCenter UI service host-manager webapp must be removed.
     [PASS]  false is expected to cmp == "false"

Profile Summary: 304 successful controls, 25 control failures, 0 controls skipped
Test Summary: 1240 successful, 80 failures, 0 skipped
# Navigate to the InSpec profile folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vcsa/inspec/vmware-vcsa-8.0-stig-baseline

# Run the audit
cinc-auditor exec . -t ssh://root@10.186.30.81 --password 'password' --show-progress --enhanced-outcomes --input-file ./inputs-vcsa-8.0.yml --reporter cli json:/tmp/reports/MyVCSA8Report.json

# Shown below is the last part of the output at the CLI.
  [PASS]  VCUI-80-000141: The vCenter UI service example applications must be removed.
     [PASS]  false is expected to cmp == "false"
  [PASS]  VCUI-80-000142: The vCenter UI service default ROOT web application must be removed.
     [PASS]  Command: `ls /usr/lib/vmware-vsphere-ui/server/webapps/ROOT` stdout.strip is expected to cmp == ""
  [PASS]  VCUI-80-000143: The vCenter UI service default documentation must be removed.
     [PASS]  false is expected to cmp == "false"
  [PASS]  VCUI-80-000151: The vCenter UI service must disable "ALLOW_BACKSLASH".
     [PASS]  is expected to be in nil and "false"
  [PASS]  VCUI-80-000152: The vCenter UI service must enable "ENFORCE_ENCODING_IN_GET_WRITER".
     [PASS]  is expected to be in nil and "true"
  [PASS]  VCUI-80-000154: The vCenter UI service manager webapp must be removed.
     [PASS]  false is expected to cmp == "false"
  [PASS]  VCUI-80-000155: The vCenter UI service host-manager webapp must be removed.
     [PASS]  false is expected to cmp == "false"

Profile Summary: 304 successful controls, 25 control failures, 0 controls skipped
Test Summary: 1240 successful, 80 failures, 0 skipped

Convert the results to CKL

If a STIG Viewer CKL file is needed then the results from the scans can be converted to CKL with the SAF CLI.

# Converting the VCSA scan results from the prior section to CKL
saf convert hdf2ckl -i /tmp/reports/MyVCSA8Report.json -o /tmp/reports/MyVCSA8Report.ckl --hostname 10.186.30.81 --fqdn myvcenter.local --ip 10.186.30.81 --mac 00:00:00:00:00:00

Opening the CKL file in STIG Viewer will look like the screenshot below. Note the InSpec results are included in the Finding Details pane.

alt text

2 - Remediate vSphere 8

Remediating vSphere 8 for STIG Compliance

Overview

Remediating vSphere for STIG compliance involves configuring ESXi, Virtual Machines, vCenter, and the vCenter appliance.

When remediating vSphere we will split up tasks between product and appliance based controls which are defined as follows:

  • Product Control: Configurations that interact with the Product via the User Interface or API that are exposed to administrators. Whether these are Default or Non-Default, the risk of mis-configuration effecting availability of the product is low but could impact how the environment is operated if not assessed.
  • Appliance Control: Appliance controls deal with the underlying components (databases, web servers, Photon OS, etc) that make up the product. Altering these add risk to product availability without precautionary steps and care in implementation. Identifying and relying on Default settings in this category makes this category less risky (Default Appliance Controls should be seen as a positive).

To remediate vSphere, PowerCLI is the automation tool used, while for the VCSA we will use Ansible. For the vCenter appliance the remediation is performed via SSH. It is recommended to disable SSH on vCenter after configuration is complete.

Prerequisites

Versions listed below were used for this documentation. Other versions of these tools may work as well but if issues are found it is recommended to try the versions listed here.

Assumptions

  • Commands are being ran from a Linux machine. Windows will also work (for the PowerCLI portions only) but paths and commands may need to be adjusted from the examples.
  • The DOD Compliance and Automation repository downloaded and extracted to /usr/share/stigs.
  • Ansible installed and all playbook dependencies resolved as provided in the requirements.yml file in each playbook. Install with ansible-galaxy roles install -r requirements.yml.
  • The dependent Photon OS Ansible roles(Photon 3.0 for U1 and Photon 4 for U2) installed and available. Verify role installation with ansible-galaxy role list.

Remediate vSphere (Product Controls)

Create Powershell credential for vCenter connection

The PowerCLI scripts provided use a Powershell Credential stored in a variable to authenticate to vCenter and should be established before attempting to run the scripts.

# Run the following command to generate a credential. Substitute the username as needed in your environment.
pwsh

$vccred = Get-Credential

PowerShell credential request
Enter your credentials.
User: administrator@vsphere.local
Password for user administrator@vsphere.local: ****************

Remediating ESXi product controls

To remediate ESXi hosts we have provided a PowerCLI script that will target a single host or a vSphere cluster based on parameters provided to the script.

Note: There are some controls that cannot be remediated with PowerCLI and are not addressed by this script. The output will indicate that these are manual controls.

Gather environment information

In order to run the script effectively it must be provided with the organizations environment specific information.

Review the below parameters and gather the information needed to run the script:

[CmdletBinding()]
param (
  [Parameter(Mandatory=$true)]
  [string]$vcenter,
  [Parameter(Mandatory=$true)]
  [pscredential]$vccred,
  [Parameter(Mandatory=$true,ParameterSetName="hostname")]
  [string]$hostname,
  [Parameter(Mandatory=$true,ParameterSetName="cluster")]
  [string]$cluster,
  [Parameter(Mandatory=$false,
  HelpMessage="Enter the path for the output report. Example /tmp")]
  [string]$reportpath,  
  [Parameter(Mandatory=$true,
  HelpMessage="Enter the Active Directory Admins group to use for administrative access to ESXi")]
  [string]$esxAdminGroup,
  [Parameter(Mandatory=$true,
  HelpMessage="Enter allowed IP ranges for the ESXi firewall in comma separated format.  For Example "192.168.0.0/16","10.0.0.0/8" ")]
  [string[]]$allowedIPs,
  [Parameter(Mandatory=$false,
  HelpMessage="Enter the syslog server for the ESXi server(s). Example tcp://log.domain.local:514")]
  [string]$syslogServer,
  [Parameter(Mandatory=$false,
  HelpMessage="Enable this option if VMware vRealize Log Insight is used to manage syslog on the ESXi host(s).")]
  [switch]$logInsight,
  [Parameter(Mandatory=$true,
  HelpMessage="Enter NTP servers.  For Example "10.1.1.1","10.1.1.2" ")]
  [string[]]$ntpServers,
  [Parameter(Mandatory=$false,
  HelpMessage="Specify the native VLAN Id configured on the ports going to the ESXi Hosts.  If none is specified the default of 1 will be used.")]
  [string]$nativeVLAN = "1"
)
[CmdletBinding()]
param (
  [Parameter(Mandatory=$true)]
  [string]$vcenter,
  [Parameter(Mandatory=$true)]
  [pscredential]$vccred,
  [Parameter(Mandatory=$true,ParameterSetName="hostname")]
  [string]$hostname,
  [Parameter(Mandatory=$true,ParameterSetName="cluster")]
  [string]$cluster,
  [Parameter(Mandatory=$false,
  HelpMessage="Enter the path for the output report. Example /tmp")]
  [string]$reportpath,  
  [Parameter(Mandatory=$true,
  HelpMessage="Enter the Active Directory Admins group to use for administrative access to ESXi")]
  [string]$esxAdminGroup,
  [Parameter(Mandatory=$true,
  HelpMessage="Enter allowed IP ranges for the ESXi firewall in comma separated format.  For Example "192.168.0.0/16","10.0.0.0/8" ")]
  [string[]]$allowedIPs,
  [Parameter(Mandatory=$false,
  HelpMessage="Enter the syslog server for the ESXi server(s). Example tcp://log.domain.local:514")]
  [string]$syslogServer,
  [Parameter(Mandatory=$false,
  HelpMessage="Enable this option if VMware vRealize Log Insight is used to manage syslog on the ESXi host(s).")]
  [switch]$logInsight,
  [Parameter(Mandatory=$true,
  HelpMessage="Enter NTP servers.  For Example "10.1.1.1","10.1.1.2" ")]
  [string[]]$ntpServers,
  [Parameter(Mandatory=$false,
  HelpMessage="Specify the native VLAN Id configured on the ports going to the ESXi Hosts.  If none is specified the default of 1 will be used.")]
  [string]$nativeVLAN = "1"
)

Disabling Controls

The script includes variables to enable or disable controls by STIG ID. All controls are all enabled by default and can be turned off by changing these variables to $false for a specific control.

A snippet of these variables is shown below.

##### Enable or Disable specific STIG Remediations #####
$controlsenabled = [ordered]@{
  ESXI80000005 = $true  #Account Lock Failures
  ESXI80000006 = $true  #Consent Banner Welcome
  ESXI80000008 = $true  #Lockdown Mode
  ESXI80000010 = $true  #Host Client Timeout

Run remediation script on target ESXi hosts

This example will remediate all hosts in the vSphere cluster named cluster0. If running on a single host is desired, specify the hostname parameter instead of cluster and provide the hostname as displayed in vCenter.

# Navigate to the powercli folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/powercli

# Running the script.
./VMware_vSphere_8.0_STIG_ESXi_Remediation.ps1 -vcenter 10.182.177.21 -vccred $vccred -cluster "cluster0" -esxAdminGroup "MyESXiGroup" -allowedIPs "10.10.10.0/24","10.10.11.0/24" -ntpServers "time-a-g.nist.gov","time-b-g.nist.gov" -syslogServer "tcp://loginsight.vmware.com:514" -reportpath /tmp/reports

# Snippet from the output of running the script.
2:11:17 PM ...Remediating STIG ID:ESXI-80-000244 with Title: The ESXi host must enforce the exclusive running of executables from approved VIBs.
2:11:17 PM ...Setting VMkernel.Boot.execInstalledOnly was incorrectly set to False on 10.182.180.5...setting to true
VMkernel.Boot.execI True                 VMHost
2:11:18 PM ...Setting VMkernel.Boot.execInstalledOnly was incorrectly set to False on 10.182.182.193...setting to true
VMkernel.Boot.execI True                 VMHost
2:11:20 PM ...Setting VMkernel.Boot.execInstalledOnly was incorrectly set to False on 10.182.183.107...setting to true
VMkernel.Boot.execI True                 VMHost
2:11:21 PM ...Remediating STIG ID:ESXI-80-000245 with Title: The ESXi host must use sufficient entropy for cryptographic operations.
2:11:22 PM ...disableHwrng set correctly to FALSE on 10.182.180.5
2:11:22 PM ...entropySources set correctly to 0 on 10.182.180.5
2:11:23 PM ...disableHwrng set correctly to FALSE on 10.182.182.193
2:11:24 PM ...entropySources set correctly to 0 on 10.182.182.193
2:11:25 PM ...disableHwrng set correctly to FALSE on 10.182.183.107
2:11:25 PM ...entropySources set correctly to 0 on 10.182.183.107
2:11:25 PM ...Remediating STIG ID:ESXI-80-000246 with Title: The ESXi host must not enable log filtering.
2:11:25 PM ...log filtering set correctly to false on 10.182.180.5
2:11:25 PM ...log filtering set correctly to false on 10.182.182.193
2:11:26 PM ...log filtering set correctly to false on 10.182.183.107
2:11:26 PM ...Remediating STIG ID:ESXI-80-000008 with Title: The ESXi host must enable lockdown mode.
2:11:26 PM ...Enabling Lockdown mode with level lockdownNormal on 10.182.180.5
2:11:26 PM ...Enabling Lockdown mode with level lockdownNormal on 10.182.182.193
2:11:27 PM ...Enabling Lockdown mode with level lockdownNormal on 10.182.183.107
2:11:27 PM ...Configuration Summary:
2:11:27 PM {
  "vcenter": "10.182.177.21",
  "hostname": "",
  "cluster": "cluster0",
  "vmhosts": [
    "10.182.180.5",
    "10.182.182.193",
    "10.182.183.107"
  ],
  "reportpath": "/tmp/reports",
  "ok": 99,
  "changed": 123,
  "skipped": 25,
  "failed": 5,

# A results file and Powershell transcript is provided in the report path specified.
Directory: /tmp/reports

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/8/2023  2:11 PM           6578 VMware_vSphere_8.0_STIG_ESXi_Remediation_Results_6-8-2023_14-6-38.json
-a---            6/8/2023  2:11 PM          84552 VMware_vSphere_8.0_STIG_ESXi_Remediation_Transcript_6-8-2023_14-6-38.txt
# Navigate to the powercli folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/powercli

# Running the script.
./VMware_vSphere_8.0_STIG_ESXi_Remediation.ps1 -vcenter 10.182.177.21 -vccred $vccred -cluster "cluster0" -esxAdminGroup "MyESXiGroup" -allowedIPs "10.10.10.0/24","10.10.11.0/24" -ntpServers "time-a-g.nist.gov","time-b-g.nist.gov" -syslogServer "tcp://loginsight.vmware.com:514" -reportpath /tmp/reports

# Snippet from the output of running the script.
2:11:17 PM ...Remediating STIG ID:ESXI-80-000244 with Title: The ESXi host must enforce the exclusive running of executables from approved VIBs.
2:11:17 PM ...Setting VMkernel.Boot.execInstalledOnly was incorrectly set to False on 10.182.180.5...setting to true
VMkernel.Boot.execI True                 VMHost
2:11:18 PM ...Setting VMkernel.Boot.execInstalledOnly was incorrectly set to False on 10.182.182.193...setting to true
VMkernel.Boot.execI True                 VMHost
2:11:20 PM ...Setting VMkernel.Boot.execInstalledOnly was incorrectly set to False on 10.182.183.107...setting to true
VMkernel.Boot.execI True                 VMHost
2:11:21 PM ...Remediating STIG ID:ESXI-80-000245 with Title: The ESXi host must use sufficient entropy for cryptographic operations.
2:11:22 PM ...disableHwrng set correctly to FALSE on 10.182.180.5
2:11:22 PM ...entropySources set correctly to 0 on 10.182.180.5
2:11:23 PM ...disableHwrng set correctly to FALSE on 10.182.182.193
2:11:24 PM ...entropySources set correctly to 0 on 10.182.182.193
2:11:25 PM ...disableHwrng set correctly to FALSE on 10.182.183.107
2:11:25 PM ...entropySources set correctly to 0 on 10.182.183.107
2:11:25 PM ...Remediating STIG ID:ESXI-80-000246 with Title: The ESXi host must not enable log filtering.
2:11:25 PM ...log filtering set correctly to false on 10.182.180.5
2:11:25 PM ...log filtering set correctly to false on 10.182.182.193
2:11:26 PM ...log filtering set correctly to false on 10.182.183.107
2:11:26 PM ...Remediating STIG ID:ESXI-80-000008 with Title: The ESXi host must enable lockdown mode.
2:11:26 PM ...Enabling Lockdown mode with level lockdownNormal on 10.182.180.5
2:11:26 PM ...Enabling Lockdown mode with level lockdownNormal on 10.182.182.193
2:11:27 PM ...Enabling Lockdown mode with level lockdownNormal on 10.182.183.107
2:11:27 PM ...Configuration Summary:
2:11:27 PM {
  "vcenter": "10.182.177.21",
  "hostname": "",
  "cluster": "cluster0",
  "vmhosts": [
    "10.182.180.5",
    "10.182.182.193",
    "10.182.183.107"
  ],
  "reportpath": "/tmp/reports",
  "ok": 99,
  "changed": 123,
  "skipped": 25,
  "failed": 5,

# A results file and Powershell transcript is provided in the report path specified.
Directory: /tmp/reports

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/8/2023  2:11 PM           6578 VMware_vSphere_8.0_STIG_ESXi_Remediation_Results_6-8-2023_14-6-38.json
-a---            6/8/2023  2:11 PM          84552 VMware_vSphere_8.0_STIG_ESXi_Remediation_Transcript_6-8-2023_14-6-38.txt

Remediating virtual machines

To remediate virtual machines we have provided a PowerCLI script that will target a single VM, all VMs in a cluster, or all VMs in vCenter based on parameters provided to the script.

Note: There are some controls that cannot be remediated with PowerCLI and are not addressed by this script. See the scripts description text for more details.

Disabling Controls

For processing efficiency it is not constructed to run each control individually so the STIG ID variables are not included to enabled/disable controls such as in the ESXi/vCenter scripts. If it is desired to skip some controls they could be commented out in the $vmconfig variable in the script.

Run remediation script on target virtual machines

This example will remediate all hosts in the vSphere cluster named cluster0. If running on a single host is desired, specify the hostname parameter instead of cluster and provide the hostname as displayed in vCenter.

# Navigate to the powercli folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/powercli

# Running the script.
./VMware_vSphere_8.0_STIG_VM_Remediation.ps1 -vcenter 10.182.177.21 -vccred $vccred -cluster "cluster0" -reportpath /tmp/reports

# Snippet from the output of running the script.
2:13:50 PM ...Connecting to vCenter Server 10.182.177.21
2:13:52 PM ...Getting PowerCLI objects for all virtual machines in cluster: cluster0
2:13:53 PM ...Remediating advanced settings on vCLS-1ef92498-69e3-4c68-b4fa-ef5a25b671b7 on 10.182.177.21
2:13:53 PM ...Setting isolation.device.connectable.disable does not exist on vCLS-1ef92498-69e3-4c68-b4fa-ef5a25b671b7 and is compliant by default...
2:13:53 PM ...Setting isolation.tools.copy.disable does not exist on vCLS-1ef92498-69e3-4c68-b4fa-ef5a25b671b7 and is compliant by default...
2:13:53 PM ...Setting isolation.tools.diskShrink.disable does not exist on vCLS-1ef92498-69e3-4c68-b4fa-ef5a25b671b7 and is compliant by default...
2:13:53 PM ...Setting isolation.tools.diskWiper.disable does not exist on vCLS-1ef92498-69e3-4c68-b4fa-ef5a25b671b7 and is compliant by default...

# A results file and Powershell transcript is provided in the report path specified.
Directory: /tmp/reports

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/8/2023  2:14 PM          10743 VMware_vSphere_8.0_STIG_VM_Remediation_Transcript_6-8-2023_14-13-50.txt
-a---            6/8/2023  2:14 PM           1105 VMware_vSphere_8.0_STIG_VM_Remediation_Transcript_6-8-2023_14-14-7.txt
# Navigate to the powercli folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/powercli

# Running the script.
./VMware_vSphere_8.0_STIG_VM_Remediation.ps1 -vcenter 10.182.177.21 -vccred $vccred -cluster "cluster0" -reportpath /tmp/reports

# Snippet from the output of running the script.
2:13:50 PM ...Connecting to vCenter Server 10.182.177.21
2:13:52 PM ...Getting PowerCLI objects for all virtual machines in cluster: cluster0
2:13:53 PM ...Remediating advanced settings on vCLS-1ef92498-69e3-4c68-b4fa-ef5a25b671b7 on 10.182.177.21
2:13:53 PM ...Setting isolation.device.connectable.disable does not exist on vCLS-1ef92498-69e3-4c68-b4fa-ef5a25b671b7 and is compliant by default...
2:13:53 PM ...Setting isolation.tools.copy.disable does not exist on vCLS-1ef92498-69e3-4c68-b4fa-ef5a25b671b7 and is compliant by default...
2:13:53 PM ...Setting isolation.tools.diskShrink.disable does not exist on vCLS-1ef92498-69e3-4c68-b4fa-ef5a25b671b7 and is compliant by default...
2:13:53 PM ...Setting isolation.tools.diskWiper.disable does not exist on vCLS-1ef92498-69e3-4c68-b4fa-ef5a25b671b7 and is compliant by default...

# A results file and Powershell transcript is provided in the report path specified.
Directory: /tmp/reports

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/8/2023  2:14 PM          10743 VMware_vSphere_8.0_STIG_VM_Remediation_Transcript_6-8-2023_14-13-50.txt
-a---            6/8/2023  2:14 PM           1105 VMware_vSphere_8.0_STIG_VM_Remediation_Transcript_6-8-2023_14-14-7.txt

Remediating vCenter

To remediate vCenter we have provided a PowerCLI script that will target a single vCenter server.

Note: There are some controls that cannot be remediated with PowerCLI and are not addressed by this script. The output will indicate that these are manual controls.

Gather environment information

In order to run the script effectively it must be provided with the organizations environment specific information.

This script also uses the VMware.Vsphere.SsoAdmin PowerCLI Module to configure vCenter SSO controls. This module connects to vCenter separately using the Connect-SsoAdminServer command that requires using an account that has sufficient privileges in vCenter to modify SSO settings.

Review the below parameters and gather the information needed to run the script:

[CmdletBinding()]
param (
  [Parameter(Mandatory=$true)]
  [string]$vcenter,
  [Parameter(Mandatory=$true)]
  [pscredential]$vccred,
  [Parameter(Mandatory=$false,
  HelpMessage="Enter the path for the output report. Example /tmp")]
  [string]$reportpath,
  [Parameter(Mandatory=$false,
  HelpMessage="If Netflow is used enter the collector IP address")]
  [string]$vcNetflowCollectorIp = "",
  [Parameter(Mandatory=$false,
  HelpMessage="To disable Netflow on all port groups if enabled set to true")]
  [boolean]$vcNetflowDisableonallPortGroups = $false
)
[CmdletBinding()]
param (
  [Parameter(Mandatory=$true)]
  [string]$vcenter,
  [Parameter(Mandatory=$true)]
  [pscredential]$vccred,
  [Parameter(Mandatory=$false,
  HelpMessage="Enter the path for the output report. Example /tmp")]
  [string]$reportpath,
  [Parameter(Mandatory=$false,
  HelpMessage="If Netflow is used enter the collector IP address")]
  [string]$vcNetflowCollectorIp = "",
  [Parameter(Mandatory=$false,
  HelpMessage="To disable Netflow on all port groups if enabled set to true")]
  [boolean]$vcNetflowDisableonallPortGroups = $false
)

Disabling Controls

The script includes variables to enable or disable controls by STIG ID. All controls are all enabled by default and can be turned off by changing these variables to $false for a specific control.

A snippet of these variables is shown below.

##### Enable or Disable specific STIG Remediations #####
$controlsenabled = [ordered]@{
  VCSA8000009 = $true  #TLS 1.2
  VCSA8000023 = $true  #SSO Login Attempts
  VCSA8000024 = $true  #SSO Banner - Manual
  VCSA8000034 = $true  #config.log.level

Run remediation script on target vCenter server

This example will remediate all controls on a target vCenter server.

# Navigate to the powercli folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vsphere/powercli

# Running the script.
./VMware_vSphere_8.0_STIG_vCenter_Remediation.ps1 -vcenter 10.182.177.21 -vccred $vccred -vcNetflowDisableonallPortGroups $true -reportpath /tmp/reports

# Snippet from the output of running the script.
2:27:42 PM ...Connecting to vCenter Server 10.182.177.21
2:27:44 PM ...Connecting to vCenter SSO Server 10.182.177.21
2:27:45 PM ...Verifying vCenter 10.182.177.21 is version 8.0.x
2:27:45 PM ...vCenter 10.182.177.21 is version 8.0.1 continuing...
2:27:45 PM ...Getting PowerCLI objects for all virtual distributed switches in vCenter: 10.182.177.21
2:27:45 PM ...Getting PowerCLI objects for all virtual distributed port groups in vCenter: 10.182.177.21
2:27:46 PM ...Remediating STIG ID: VCSA-80-000009 with Title: The vCenter Server must use TLS 1.2, at a minimum, to protect the confidentiality of sensitive data during electronic dissemination using remote access.
2:27:46 PM ...!!This control must be remediated manually!!
2:27:46 PM ...Remediating STIG ID: VCSA-80-000023 with Title: The vCenter Server must enforce the limit of three consecutive invalid logon attempts by a user.
2:27:47 PM ...SSO login attempts set incorrectly on 10.182.177.21
2:27:47 PM ...Remediating STIG ID: VCSA-80-000024 with Title: The vCenter Server must display the Standard Mandatory DoD Notice and Consent Banner before logon.
2:27:47 PM ...!!This control must be remediated manually!!
2:27:47 PM ...Remediating STIG ID: VCSA-80-000034 with Title: The vCenter Server must produce audit records containing information to establish what type of events occurred.
2:27:47 PM ...Setting config.log.level is already configured correctly to info on 10.182.177.21

# A results file and Powershell transcript is provided in the report path specified.
Directory: /tmp/reports

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/8/2023  2:28 PM           2873 VMware_vSphere_8.0_STIG_vCenter_Remediation_Results_6-8-2023_14-27-42.json
-a---            6/8/2023  2:28 PM          25530 VMware_vSphere_8.0_STIG_vCenter_Remediation_Transcript_6-8-2023_14-27-42.txt
# Navigate to the powercli folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vsphere/powercli

# Running the script.
./VMware_vSphere_8.0_STIG_vCenter_Remediation.ps1 -vcenter 10.182.177.21 -vccred $vccred -vcNetflowDisableonallPortGroups $true -reportpath /tmp/reports

# Snippet from the output of running the script.
2:27:42 PM ...Connecting to vCenter Server 10.182.177.21
2:27:44 PM ...Connecting to vCenter SSO Server 10.182.177.21
2:27:45 PM ...Verifying vCenter 10.182.177.21 is version 8.0.x
2:27:45 PM ...vCenter 10.182.177.21 is version 8.0.1 continuing...
2:27:45 PM ...Getting PowerCLI objects for all virtual distributed switches in vCenter: 10.182.177.21
2:27:45 PM ...Getting PowerCLI objects for all virtual distributed port groups in vCenter: 10.182.177.21
2:27:46 PM ...Remediating STIG ID: VCSA-80-000009 with Title: The vCenter Server must use TLS 1.2, at a minimum, to protect the confidentiality of sensitive data during electronic dissemination using remote access.
2:27:46 PM ...!!This control must be remediated manually!!
2:27:46 PM ...Remediating STIG ID: VCSA-80-000023 with Title: The vCenter Server must enforce the limit of three consecutive invalid logon attempts by a user.
2:27:47 PM ...SSO login attempts set incorrectly on 10.182.177.21
2:27:47 PM ...Remediating STIG ID: VCSA-80-000024 with Title: The vCenter Server must display the Standard Mandatory DoD Notice and Consent Banner before logon.
2:27:47 PM ...!!This control must be remediated manually!!
2:27:47 PM ...Remediating STIG ID: VCSA-80-000034 with Title: The vCenter Server must produce audit records containing information to establish what type of events occurred.
2:27:47 PM ...Setting config.log.level is already configured correctly to info on 10.182.177.21

# A results file and Powershell transcript is provided in the report path specified.
Directory: /tmp/reports

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/8/2023  2:28 PM           2873 VMware_vSphere_8.0_STIG_vCenter_Remediation_Results_6-8-2023_14-27-42.json
-a---            6/8/2023  2:28 PM          25530 VMware_vSphere_8.0_STIG_vCenter_Remediation_Transcript_6-8-2023_14-27-42.txt

Remediating vCenter (Appliance Controls)

To remediate vCenter we have provided an Ansible playbook that will target a single vCenter server appliance over SSH and configure any non-compliant controls.

Update the default shell for root

The default shell for root must be changed to /bin/bash before running. The appliance shell causes issues with some controls running.

# SSH to vCenter
Connected to service

    * List APIs: "help api list"
    * List Plugins: "help pi list"
    * Launch BASH: "shell"

Command> shell.set --enabled true
Command> shell
Shell access is granted to root
root@sc1-10-182-131-166 [ ~ ]# chsh -s /bin/bash root

Running the playbook

To run all of the VCSA controls, follow the example below:

# Navigate to the Ansible playbook folder
cd /usr/share/stigs/vsphere/8.0/v1r1-stig/vcsa/ansible/vmware-vcsa-8.0-stig-ansible-hardening

# The -k parameter will prompt for password and we are using extra-vars to specify a variable file for the playbook to use.
ansible-playbook -i 10.182.177.21, -u root playbook.yml -k -v --extra-vars @vars-vcenter-example.yml

# Output example
SSH password:

PLAY [all] ********************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [10.182.177.21]

TASK [vmware-photon-3.0-stig-ansible-hardening : Include Photon] **************************************************************************************************************************************************************
included: /home/rlakey/.ansible/roles/vmware-photon-3.0-stig-ansible-hardening/tasks/photon.yml for 10.182.177.21

TASK [vmware-photon-3.0-stig-ansible-hardening : Create time stamp] ***********************************************************************************************************************************************************
ok: [10.182.177.21] => {"ansible_facts": {"backup_timestamp": "2023-05-25-12-25-58"}, "changed": false}

TASK [vmware-photon-3.0-stig-ansible-hardening : Backup files...if restoring be sure to restore permissions that original file had!!] *****************************************************************************************
ok: [10.182.177.21] => (item=/etc/rsyslog.conf) => {"ansible_loop_var": "item", "changed": false, "checksum": "7aa11dc58f144160e7e3dc2d40cb2f03a39a989c", "dest": "/tmp/ansible-backups-2023-05-25-12-25-58/rsyslog.conf", "gid": 0, "group": "root", "item": "/etc/rsyslog.conf", "md5sum": "d31d58ff2bbc5cff6b7f343c2580300c", "mode": "0644", "owner": "root", "size": 4000, "src": "/etc/rsyslog.conf", "state": "file", "uid": 0}
ok: [10.182.177.21] => (item=/etc/issue) => {"ansible_loop_var": "item", "changed": false, "checksum": "930cb25fc842aca6047cb9fc1bfbd6ea191e686f", "dest": "/tmp/ansible-backups-2023-05-25-12-25-58/issue", "gid": 0, "group": "root", "item": "/etc/issue", "md5sum": "f498b74a84aaa39e292d9b815899144d", "mode": "0644", "owner": "root", "size": 104, "src": "/etc/issue", "state": "file", "uid": 0}
ok: [10.182.177.21] => (item=/etc/audit/rules.d/audit.STIG.rules) => {"ansible_loop_var": "item", "changed": false, "checksum": "38f324fe67c6943e07ef1910b41dedeb0b256ca4", "dest": "/tmp/ansible-backups-2023-05-25-12-25-58/audit.STIG.rules", "gid": 0, "group": "root", "item": "/etc/audit/rules.d/audit.STIG.rules", "md5sum": "396d715044fc7a8d92a0332d3edb4112", "mode": "0640", "owner": "root", "size": 5080, "src": "/etc/audit/rules.d/audit.STIG.rules", "state": "file", "uid": 0}

TASK [vmware-photon-3.0-stig-ansible-hardening : PHTN-30-000001 - Update/Create audit.STIG.rules file] ************************************************************************************************************************
changed: [10.182.177.21] => {"changed": true, "checksum": "aaafa4e8c28743ce3cc22c818f28f4cb9a3f53b2", "dest": "/etc/audit/rules.d/audit.STIG.rules", "gid": 0, "group": "root", "md5sum": "91a31e7bbf9e3f0d7f390feb4360581b", "mode": "0640", "owner": "root", "size": 5180, "src": "/root/.ansible/tmp/ansible-tmp-1685039234.3606877-890-106251101523760/source", "state": "file", "uid": 0}
# Navigate to the Ansible playbook folder
cd /usr/share/stigs/vsphere/8.0/v1r1-srg/vcsa/ansible/vmware-vcsa-8.0-stig-ansible-hardening

# The -k parameter will prompt for password and we are using extra-vars to specify a variable file for the playbook to use.
ansible-playbook -i 10.182.177.21, -u root playbook.yml -k -v --extra-vars @vars-vcenter-example.yml

# Output example
SSH password:

PLAY [all] ********************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [10.182.177.21]

TASK [vmware-photon-3.0-stig-ansible-hardening : Include Photon] **************************************************************************************************************************************************************
included: /home/rlakey/.ansible/roles/vmware-photon-3.0-stig-ansible-hardening/tasks/photon.yml for 10.182.177.21

TASK [vmware-photon-3.0-stig-ansible-hardening : Create time stamp] ***********************************************************************************************************************************************************
ok: [10.182.177.21] => {"ansible_facts": {"backup_timestamp": "2023-05-25-12-25-58"}, "changed": false}

TASK [vmware-photon-3.0-stig-ansible-hardening : Backup files...if restoring be sure to restore permissions that original file had!!] *****************************************************************************************
ok: [10.182.177.21] => (item=/etc/rsyslog.conf) => {"ansible_loop_var": "item", "changed": false, "checksum": "7aa11dc58f144160e7e3dc2d40cb2f03a39a989c", "dest": "/tmp/ansible-backups-2023-05-25-12-25-58/rsyslog.conf", "gid": 0, "group": "root", "item": "/etc/rsyslog.conf", "md5sum": "d31d58ff2bbc5cff6b7f343c2580300c", "mode": "0644", "owner": "root", "size": 4000, "src": "/etc/rsyslog.conf", "state": "file", "uid": 0}
ok: [10.182.177.21] => (item=/etc/issue) => {"ansible_loop_var": "item", "changed": false, "checksum": "930cb25fc842aca6047cb9fc1bfbd6ea191e686f", "dest": "/tmp/ansible-backups-2023-05-25-12-25-58/issue", "gid": 0, "group": "root", "item": "/etc/issue", "md5sum": "f498b74a84aaa39e292d9b815899144d", "mode": "0644", "owner": "root", "size": 104, "src": "/etc/issue", "state": "file", "uid": 0}
ok: [10.182.177.21] => (item=/etc/audit/rules.d/audit.STIG.rules) => {"ansible_loop_var": "item", "changed": false, "checksum": "38f324fe67c6943e07ef1910b41dedeb0b256ca4", "dest": "/tmp/ansible-backups-2023-05-25-12-25-58/audit.STIG.rules", "gid": 0, "group": "root", "item": "/etc/audit/rules.d/audit.STIG.rules", "md5sum": "396d715044fc7a8d92a0332d3edb4112", "mode": "0640", "owner": "root", "size": 5080, "src": "/etc/audit/rules.d/audit.STIG.rules", "state": "file", "uid": 0}

TASK [vmware-photon-3.0-stig-ansible-hardening : PHTN-30-000001 - Update/Create audit.STIG.rules file] ************************************************************************************************************************
changed: [10.182.177.21] => {"changed": true, "checksum": "aaafa4e8c28743ce3cc22c818f28f4cb9a3f53b2", "dest": "/etc/audit/rules.d/audit.STIG.rules", "gid": 0, "group": "root", "md5sum": "91a31e7bbf9e3f0d7f390feb4360581b", "mode": "0640", "owner": "root", "size": 5180, "src": "/root/.ansible/tmp/ansible-tmp-1685039234.3606877-890-106251101523760/source", "state": "file", "uid": 0}

A more conservative and preferred approach is to target any non-compliant controls or run each component separately allowed you to perform any functional testing in between.

# Providing the tag "eam" will instruct the playbook to only run the eam role. This tag can be seen in each roles task/main.yml file.
ansible-playbook -i 10.182.177.21, -u root playbook.yml -k -v --extra-vars @vars-vcenter-example.yml --tags eam

# Providing the tag "VCEM-70-000001" will instruct the playbook to only run task tagged with the STIG ID of VCEM-80-000001.
ansible-playbook -i 10.182.177.21, -u root playbook.yml -k -v --extra-vars @vars-vcenter-example.yml --tags VCEM-80-000001
# Providing the tag "eam" will instruct the playbook to only run the eam role. This tag can be seen in each roles task/main.yml file.
ansible-playbook -i 10.182.177.21, -u root playbook.yml -k -v --extra-vars @vars-vcenter-example.yml --tags eam

# Providing the tag "VCEM-70-000001" will instruct the playbook to only run task tagged with the STIG ID of VCEM-80-000001.
ansible-playbook -i 10.182.177.21, -u root playbook.yml -k -v --extra-vars @vars-vcenter-example.yml --tags VCEM-80-000001

3 - Audit vSphere 7

Auditing vSphere 7 for STIG Compliance

Overview

Auditing vSphere for STIG compliance involves scanning ESXi, Virtual Machines, vCenter, and the vCenter appliance.

When auditing vSphere we will split up tasks between product and appliance based controls which are defined as follows:

  • Product Control: Configurations that interact with the Product via the User Interface or API that are exposed to administrators. Whether these are Default or Non-Default, the risk of mis-configuration effecting availability of the product is low but could impact how the environment is operated if not assessed.
  • Appliance Control: Appliance controls deal with the underlying components (databases, web servers, Photon OS, etc) that make up the product. Altering these add risk to product availability if precautionary steps and care in implementation are not taken. Identifying and relying on Default settings in this category makes this category less risky (Default Appliance Controls should be seen as a positive).

To audit vSphere using InSpec we utilize the VMware transport(train-vmware) which connects to vCenter via PowerCLI and performs queries. For the vCenter appliance the auditing is performed via SSH. It is recommended to disable SSH on vCenter after the auditing is complete.

Prerequisites

Versions listed below were used for this documentation. Other versions of these tools may work as well but if issues are found it is recommended to try the versions listed here.

Install the custom VMware transport for InSpec

To extend the functionality of the VMware transport that ships with InSpec we have created a custom one that also incorporates the VMware.Vsphere.SsoAdmin module to extend automation coverage to the vCenter SSO STIG controls.

To install the plugin that is included with the vmware-vsphere-7.0-stig-baseline profile, do the following:

# Install the custom train-vmware plugin. Update the path to the gem as needed. The command will be the same on Windows and Linux.
> inspec plugin install C:\vmware-vsphere-7.0-stig-baseline\train-vmware-0.2.0.gem

# To verify the installation
> inspec plugin list

┌────────────────────────────────────────┬─────────┬──────────────┬─────────┬───────────────────────────────────────────────────────────────┐
              Plugin Name                Version      Via       ApiVer                            Description                          
├────────────────────────────────────────┼─────────┼──────────────┼─────────┼───────────────────────────────────────────────────────────────┤
 inspec-compliance                       5.22.3   core          2        Plugin to perform operations with Chef Automate               
 inspec-habitat                          5.22.3   core          2        Plugin to create/upload habitat package                       
 inspec-init                             5.22.3   core          2        Plugin for scaffolding profile, plugin or a resource          
 inspec-plugin-manager-cli               5.22.3   core          2        CLI plugin for InSpec                                         
 inspec-reporter-html2                   5.22.3   core          2        Improved HTML reporter plugin                                 
 inspec-reporter-json-min                5.22.3   core          2        Json-min json reporter plugin                                 
 inspec-reporter-junit                   5.22.3   core          2        JUnit XML reporter plugin                                     
 inspec-sign                             5.22.3   core          2                                                                      
 inspec-streaming-reporter-progress-bar  5.22.3   core          2        Displays a real-time progress bar and control title as output 
 inspec-supermarket                      5.22.3   core          0                                                                      
 train-aws                               0.2.24   gem (system)  train-1  AWS API Transport for Train                                   
 train-habitat                           0.2.22   gem (system)  train-1  Habitat API Transport for Train                               
 train-kubernetes                        0.1.12   gem (system)  train-1  Train Kubernetes                                              
 train-vmware                            0.2.0    gem (user)    train-1  Train Plugin for VMware PowerCLI                              
 train-winrm                             0.2.13   gem (system)  train-1  Windows WinRM API Transport for Train                         
└────────────────────────────────────────┴─────────┴──────────────┴─────────┴───────────────────────────────────────────────────────────────┘
 15 plugin(s) total

Auditing ESXi Hosts

Update profile inputs

Included in the vmware-vsphere-7.0-stig-baseline is an example inputs-example.yml file with the following inputs relevant to ESXi.

Update the inputs as shown below with values relevant to your environment.

# Choose whether to scan a single host, all hosts in a cluster, or all hosts in vCenter.
vmhostName: ""
cluster: ""
allesxi: true
# Enter an array of users that should be in the lockdown mode exceptions list.
exceptionUsers: []
# Enter the environment specific syslog server ESXi should be forwarding logs to.
syslogServer: "tcp://log.test.local:514"
# If ESXi is joined to AD, enter the AD group that has administrative access to ESXi.
adAdminGroup: "MyAdAdminGroup"
# Enter the environment specific time servers.
esxiNtpServers:
  - 'time-a-g.nist.gov'
  - 'time-b-g.nist.gov'
# Enter the environment specific vMotion VLAN Id.
vMotionVlanId: "100"
# Enter the environment specific Management VLAN Id.
mgtVlanId: "101"
# If snmp is used in the environment change to true.
snmpEnabled: "false"
# Enter the latest build number for ESXi.
esxiBuildNumber: "21424296"

Setup environment variables for vCenter connection

Connectivity to vCenter is established via environment variables. Take care to clear your history and close the Powershell session to avoid any credentials left in memory/history.

# Note: VISERVER is referencing vCenter and not an ESXi host.
> $env:VISERVER='10.186.30.81'
> $env:VISERVER_USERNAME='Administrator@vsphere.local'
> $env:VISERVER_PASSWORD='password'

Note: If your password has a single ’ in it you must substitute it with ’’’’ for it to be properly escaped all the way through the process.

Run the audit

In this example we will be scanning all ESXi hosts attached to the target vCenter, specifying an inputs file, enabling enhanced outcomes in InSpec, and outputting a report to the CLI and to a JSON file.

# Note this command is being ran from the root of the profile folder. Update paths as needed if running from a different location.
> inspec exec .\esxi\ -t vmware:// --show-progress --input-file .\inputs-example.yml --enhanced-outcomes --reporter=cli json:C:\InSpec\Reports\MyESXiReport.json

# Shown below is the last part of the output at the CLI.
  [FAIL]  ESXI-70-000097: The ESXi Common Information Model (CIM) service must be disabled. (2 failed)
     [FAIL]  PowerCLI Command: Get-VMHost -Name 10.182.131.186 | Get-VMHostService | Where {$_.Label -eq 'CIM Server'} | Select-Object -ExpandProperty Policy stdout.strip is expected to cmp == "off"

     expected: off
          got: on

     (compared using `cmp` matcher)

     [PASS]  PowerCLI Command: Get-VMHost -Name 10.182.131.186 | Get-VMHostService | Where {$_.Label -eq 'CIM Server'} | Select-Object -ExpandProperty Running stdout.strip is expected to cmp == "false"
     [FAIL]  PowerCLI Command: Get-VMHost -Name 10.182.132.6 | Get-VMHostService | Where {$_.Label -eq 'CIM Server'} | Select-Object -ExpandProperty Policy stdout.strip is expected to cmp == "off"

     expected: off
          got: on

     (compared using `cmp` matcher)

     [PASS]  PowerCLI Command: Get-VMHost -Name 10.182.132.6 | Get-VMHostService | Where {$_.Label -eq 'CIM Server'} | Select-Object -ExpandProperty Running stdout.strip is expected to cmp == "false"
     [PASS]  PowerCLI Command: Get-VMHost -Name 10.182.138.1 | Get-VMHostService | Where {$_.Label -eq 'CIM Server'} | Select-Object -ExpandProperty Policy stdout.strip is expected to cmp == "off"
     [PASS]  PowerCLI Command: Get-VMHost -Name 10.182.138.1 | Get-VMHostService | Where {$_.Label -eq 'CIM Server'} | Select-Object -ExpandProperty Running stdout.strip is expected to cmp == "false"
  [N/R]  ESXI-70-000274: The ESXi host SSH daemon must be configured to only use FIPS 140-2 validated ciphers.
     [SKIP]  This must be reviewed manually

Profile Summary: 25 successful controls, 27 control failures, 20 controls not reviewed, 3 controls not applicable, 0 controls have error
Test Summary: 143 successful, 120 failures, 34 skipped

Auditing Virtual Machines

Update profile inputs

Included in the vmware-vsphere-7.0-stig-baseline is an example inputs-example.yml file with the following inputs relevant to VMs.

Update the inputs as shown below with values relevant to your environment.

# Choose whether to scan a single VM or all VMs in vCenter.
vmName: ""
allvms: true

Setup environment variables for vCenter connection

Connectivity to vCenter is established via environment variables. Take care to clear your history and close the Powershell session to avoid any credentials left in memory/history.

If was done in the previous step it is not necessary to do again.

# Note: VISERVER is referencing vCenter and not an ESXi host.
> $env:VISERVER='10.186.30.81'
> $env:VISERVER_USERNAME='Administrator@vsphere.local'
> $env:VISERVER_PASSWORD='password'

Note: If your password has a single ’ in it you must substitute it with ’’’’ for it to be properly escaped all the way through the process.

Run the audit

In this example we will be scanning all VMs in the target vCenter, specifying an inputs file, enabling enhanced outcomes in InSpec, and outputting a report to the CLI and to a JSON file.

# Note this command is being ran from the root of the profile folder. Update paths as needed if running from a different location.
> inspec exec .\vm\ -t vmware:// --show-progress --input-file .\inputs-example.yml --enhanced-outcomes --reporter=cli json:C:\InSpec\Reports\MyVMsReport.json

# Shown below is the last part of the output at the CLI.
  [FAIL]  VMCH-70-000027: Log retention must be configured properly on the virtual machine (VM). (2 failed)
     [FAIL]  PowerCLI Command: Get-VM -Name 'stig space test' | Get-AdvancedSetting -Name log.keepOld | Select-Object -ExpandProperty Value stdout.strip is expected to cmp == "10"

     expected: 10
          got:

     (compared using `cmp` matcher)

     [FAIL]  PowerCLI Command: Get-VM -Name 'stigvmtest1' | Get-AdvancedSetting -Name log.keepOld | Select-Object -ExpandProperty Value stdout.strip is expected to cmp == "10"

     expected: 10
          got:

     (compared using `cmp` matcher)

     [PASS]  PowerCLI Command: Get-VM -Name 'vCLS-189ef61c-56dc-4d5f-a255-ac43798a77b3' | Get-AdvancedSetting -Name log.keepOld | Select-Object -ExpandProperty Value stdout.strip is expected to cmp == "10"
     [PASS]  PowerCLI Command: Get-VM -Name 'vCLS-6e74013e-53a1-4589-a2f7-47f11674d089' | Get-AdvancedSetting -Name log.keepOld | Select-Object -ExpandProperty Value stdout.strip is expected to cmp == "10"
     [PASS]  PowerCLI Command: Get-VM -Name 'vCLS-d7018f26-8dab-48c7-8161-56311f5eb077' | Get-AdvancedSetting -Name log.keepOld | Select-Object -ExpandProperty Value stdout.strip is expected to cmp == "10"
  [PASS]  VMCH-70-000028: DirectPath I/O must be disabled on the virtual machine (VM) when not required.
     [PASS]  PowerCLI Command: Get-VM -Name 'stig space test' | Get-AdvancedSetting -Name pciPassthru*.present | Select-Object -ExpandProperty Value stdout.strip is expected to be empty
     [PASS]  PowerCLI Command: Get-VM -Name 'stigvmtest1' | Get-AdvancedSetting -Name pciPassthru*.present | Select-Object -ExpandProperty Value stdout.strip is expected to be empty
     [PASS]  PowerCLI Command: Get-VM -Name 'vCLS-189ef61c-56dc-4d5f-a255-ac43798a77b3' | Get-AdvancedSetting -Name pciPassthru*.present | Select-Object -ExpandProperty Value stdout.strip is expected to be empty
     [PASS]  PowerCLI Command: Get-VM -Name 'vCLS-6e74013e-53a1-4589-a2f7-47f11674d089' | Get-AdvancedSetting -Name pciPassthru*.present | Select-Object -ExpandProperty Value stdout.strip is expected to be empty
     [PASS]  PowerCLI Command: Get-VM -Name 'vCLS-d7018f26-8dab-48c7-8161-56311f5eb077' | Get-AdvancedSetting -Name pciPassthru*.present | Select-Object -ExpandProperty Value stdout.strip is expected to be empty
  [PASS]  VMCH-70-000029: Encryption must be enabled for Fault Tolerance on the virtual machine (VM).
     [PASS]  PowerCLI Command: (Get-VM -Name 'stig space test').ExtensionData.Config.FtEncryptionMode stdout.strip is expected to be in "ftEncryptionOpportunistic" and "ftEncryptionRequired"
     [PASS]  PowerCLI Command: (Get-VM -Name 'stigvmtest1').ExtensionData.Config.FtEncryptionMode stdout.strip is expected to be in "ftEncryptionOpportunistic" and "ftEncryptionRequired"
     [PASS]  PowerCLI Command: (Get-VM -Name 'vCLS-189ef61c-56dc-4d5f-a255-ac43798a77b3').ExtensionData.Config.FtEncryptionMode stdout.strip is expected to be in "ftEncryptionOpportunistic" and "ftEncryptionRequired"
     [PASS]  PowerCLI Command: (Get-VM -Name 'vCLS-6e74013e-53a1-4589-a2f7-47f11674d089').ExtensionData.Config.FtEncryptionMode stdout.strip is expected to be in "ftEncryptionOpportunistic" and "ftEncryptionRequired"
     [PASS]  PowerCLI Command: (Get-VM -Name 'vCLS-d7018f26-8dab-48c7-8161-56311f5eb077').ExtensionData.Config.FtEncryptionMode stdout.strip is expected to be in "ftEncryptionOpportunistic" and "ftEncryptionRequired"

Profile Summary: 11 successful controls, 15 control failures, 2 controls not reviewed, 0 controls not applicable, 0 controls have error
Test Summary: 75 successful, 55 failures, 2 skipped

Auditing vCenter (Product Controls)

Update profile inputs

Included in the vmware-vsphere-7.0-stig-baseline is an example inputs-example.yml file with the following inputs relevant to vCenter.

Update the inputs as shown below with values relevant to your environment.

# Enter the environment specific syslog server vCenter should be forwarding logs to.
syslogServers:
  - "loginsight.test.com"
  - "syslog.server2.com"
# Enter the environment specific time servers.
ntpServers:
  - 'time-a-g.nist.gov'
  - 'time-b-g.nist.gov'
# If an IPfix collector is used enter the IP.
ipfixCollectorAddress: ""
# Enter any approved users in the bash shell administrators users group
bashShellAdminUsers:
  - 'Administrator'
# Enter any approved group in the bash shell administrators group
bashShellAdminGroups: []
# Enter any approved users in the trusted admin users group
trustedAdminUsers: []
# Enter any approved users in the trusted admin group
trustedAdminGroups: []
# Set to false if file based backups are used via the VAMI
backup3rdParty: false

Setup environment variables for vCenter connection

Connectivity to vCenter is established via environment variables. Take care to clear your history and close the Powershell session to avoid any credentials left in memory/history.

If was done in the previous step it is not necessary to do again.

# Note: VISERVER is referencing vCenter and not an ESXi host.
> $env:VISERVER='10.186.30.81'
> $env:VISERVER_USERNAME='Administrator@vsphere.local'
> $env:VISERVER_PASSWORD='password'

Note: If your password has a single ’ in it you must substitute it with ’’’’ for it to be properly escaped all the way through the process.

Run the audit

In this example we will be scanning vCenter controls in the target vCenter, specifying an inputs file, enabling enhanced outcomes in InSpec, and outputting a report to the CLI and to a JSON file.

# Note this command is being ran from the root of the profile folder. Update paths as needed if running from a different location.
> inspec exec .\vcenter\ -t vmware:// --show-progress --input-file .\inputs-example.yml --enhanced-outcomes --reporter=cli json:C:\InSpec\Reports\MyvCenterReport.json

# Shown below is the last part of the output at the CLI.
  [PASS]  VCSA-70-000291: The vCenter Server must limit membership to the "TrustedAdmins" Single Sign-On (SSO) group.
     [PASS]  Stderr should be empty if no users found is expected to be empty
     [PASS]  No users found in TrustedAdmins is expected to be empty
     [PASS]  Stderr should be empty if no groups found is expected to be empty
     [PASS]  No groups found in TrustedAdmins is expected to be empty
  [FAIL]  VCSA-70-000292: The vCenter server configuration must be backed up on a regular basis.
     [FAIL]  File based backups should be enabled. is expected to cmp == "true"

     expected: true
          got:

     (compared using `cmp` matcher)

  [PASS]  VCSA-70-000293: vCenter task and event retention must be set to at least 30 days.
     [PASS]  PowerCLI Command: Get-AdvancedSetting -Entity $global:DefaultViServers.Name -Name event.maxAge | Select-Object -ExpandProperty Value stdout.strip is expected to cmp == "30"
     [PASS]  PowerCLI Command: Get-AdvancedSetting -Entity $global:DefaultViServers.Name -Name task.maxAge | Select-Object -ExpandProperty Value stdout.strip is expected to cmp == "30"
  [N/R]  VCSA-70-000294: vCenter Native Key Providers must be backed up with a strong password.
     [SKIP]  This must be reviewed manually

Profile Summary: 19 successful controls, 16 control failures, 22 controls not reviewed, 0 controls not applicable, 0 controls have error
Test Summary: 52 successful, 19 failures, 22 skipped

Run a combined scan for all vSphere product controls

Instead of running each STIG for product controls separately you can also run all of the vCenter, ESXi, and VM controls for a combined report.

# Note this command is being ran from the root of the profile folder. Update paths as needed if running from a different location.
> inspec exec . -t vmware:// --show-progress --input-file .\inputs-example.yml --reporter=cli json:C:\InSpec\Reports\MyvSphereReport.json

Using the InSpec runner script

For accredidation purposes there may be a requirement to produce a CKL file for each ESXi host and/or VM.

We have also created a PowerCLI script that acts as a runner for InSpec to loop through a list of hosts or VMs and then produce a json report for each and if the SAF CLI is installed also create a CKL file.

Currently we have an example for doing this with ESXi hosts available here.

With this script you can also provide an attestation file that will be applied to the results and incorporated into the CKL file.

To use the runner script, do the following:

# If not done already provide the credentials for InSpec to connect to vCenter.
# Note: VISERVER is referencing vCenter and not an ESXi host.
> $env:VISERVER='10.186.30.81'
> $env:VISERVER_USERNAME='Administrator@vsphere.local'
> $env:VISERVER_PASSWORD='password'
# Note: If your password has a single ' in it you must substitute it with '''' for it to be properly escaped all the way through the process.
# Adjust the paths in the command as needed. The inspec and inputs paths in the example are assuming this is being ran from the root of the InSpec profile folder.
> C:\github\VMware_vSphere_7.0_STIG_ESXi_InSpec_Runner.ps1 -vcenter 10.182.131.166 -reportPath C:\Inspec\Reports\Runner -inspecPath .\esxi\ -inputsfile .\inputs-example.yml

# You will be prompted for credentials to vCenter. This is to connect via PowerCLI before running InSpec to collect all of the host names to use as an input to InSpec for each individual host audit.
8:48:29 AM ...Enter credentials to connect to vCenter

PowerShell credential request
Enter credentials for vCenter
User: administrator@vsphere.local
Password for user administrator@vsphere.local: ****************

8:48:44 AM ...Connecting to vCenter Server 10.182.131.166
8:48:47 AM ...Getting PowerCLI objects for all ESXi hosts in vCenter: 10.182.131.166
8:48:48 AM ...Validated path for report at C:\Inspec\Reports\Runner
8:48:48 AM ...Report path is C:\Inspec\Reports\Runner and report file is C:\Inspec\Reports\Runner\VMware_vSphere_7.0_STIG_ESXi_Inspec_Report_10.182.131.186-5-19-2023_8-48-29.json
8:48:48 AM ...Running InSpec exec against 10.182.131.186 with inspec exec $inspecPath -t vmware:// --input vmhostName=$name --input-file $inputsFile --show-progress --reporter=json:$reportFile
FFF......FFFFF....FFFF.FFFF.*...***********...FF.FF.....F.F..FFFF..FFF***FFFF.FFF.FF.FF....FFFFFF..F...***FF*FF*FF**...***...FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFFFFFF.FFFFF...................FF....FF...............................*......*FFF......*......F..FF..F....FF.***FF....FF....FF.**FFFFFFF.F...*
8:51:49 AM ...Detected saf cli...generating STIG Viewer Checklist for 10.182.131.186
8:51:53 AM ...Report path is C:\Inspec\Reports\Runner and report file is C:\Inspec\Reports\Runner\VMware_vSphere_7.0_STIG_ESXi_Inspec_Report_10.182.132.6-5-19-2023_8-48-29.json
8:51:53 AM ...Running InSpec exec against 10.182.132.6 with inspec exec $inspecPath -t vmware:// --input vmhostName=$name --input-file $inputsFile --show-progress --reporter=json:$reportFile
FFF......FFFFF....FFFF.FFFF.*...***********...FF.FF.....F.F..FFFF..FFF***FFFF.FFF.FF.FF....FFFFFF..F...***FF*FF*FF**...***...FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFFFFFF.FFFFF...................FF....FF...............................*......*FFF......*......F..FF..F....FF.***FF....FF....FF.**FFFFFFF.F...*
8:54:54 AM ...Detected saf cli...generating STIG Viewer Checklist for 10.182.132.6
8:54:59 AM ...Report path is C:\Inspec\Reports\Runner and report file is C:\Inspec\Reports\Runner\VMware_vSphere_7.0_STIG_ESXi_Inspec_Report_10.182.138.1-5-19-2023_8-48-29.json
8:54:59 AM ...Running InSpec exec against 10.182.138.1 with inspec exec $inspecPath -t vmware:// --input vmhostName=$name --input-file $inputsFile --show-progress --reporter=json:$reportFile
FFF......FFFFF....FFFF.FFFF.*...***********...FF.FF.....F.F..FFFF..FFF***FFFF.FFF.FF.FF....FFFFFF..F...***FF*FF*FF**...***...FFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFFFFFF.FFFFF...................FF....FF...............................*......*FFF......*......F..FF..F....FF.***FF....FF....FF.**FFFFFFF.F...*
8:57:50 AM ...Detected saf cli...generating STIG Viewer Checklist for 10.182.138.1
8:57:54 AM ...Disconnecting from vCenter

# Resulting output
> dir C:\inspec\Reports\Runner\

    Directory: C:\Inspec\Reports\Runner

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           5/19/2023  8:51 AM         507413 VMware_vSphere_7.0_STIG_ESXi_Inspec_Report_10.182.131.186-5-19-2023_8-48-29.ckl
-a---           5/19/2023  8:51 AM         580793 VMware_vSphere_7.0_STIG_ESXi_Inspec_Report_10.182.131.186-5-19-2023_8-48-29.json
-a---           5/19/2023  8:54 AM         507403 VMware_vSphere_7.0_STIG_ESXi_Inspec_Report_10.182.132.6-5-19-2023_8-48-29.ckl
-a---           5/19/2023  8:54 AM         580816 VMware_vSphere_7.0_STIG_ESXi_Inspec_Report_10.182.132.6-5-19-2023_8-48-29.json
-a---           5/19/2023  8:57 AM         507403 VMware_vSphere_7.0_STIG_ESXi_Inspec_Report_10.182.138.1-5-19-2023_8-48-29.ckl
-a---           5/19/2023  8:57 AM         580787 VMware_vSphere_7.0_STIG_ESXi_Inspec_Report_10.182.138.1-5-19-2023_8-48-29.json

Auditing vCenter (Appliance Controls)

Auditing the vCenter appliance is done over SSH which must be enabled for the scan.

Update the default shell for root

The default shell for root must be changed to /bin/bash before running. The appliance shell causes issues with some controls running.

# SSH to vCenter
Connected to service

    * List APIs: "help api list"
    * List Plugins: "help pi list"
    * Launch BASH: "shell"

Command> shell.set --enabled true
Command> shell
Shell access is granted to root
root@sc1-10-182-131-166 [ ~ ]# chsh -s /bin/bash root

Run the audit

In this example we will be scanning the vCenter appliance, specifying an inputs file, and outputting a report to the CLI and to a JSON file.

Updating the inputs file is not required for this profile but the inputs-vcsa-7.0.yml should be specified because it contains inputs for the Photon profile.

# Note this command is being ran from the root of the profile folder. Update paths as needed if running from a different location.
> inspec exec . -t ssh://root@10.182.131.166 --password 'password' --show-progress --input-file .\inputs-vcsa-7.0.yml --reporter=cli json:C:\InSpec\Reports\MyVCSAReport.json

# Shown below is the last part of the output at the CLI.
  [PASS]  VCUI-70-000028: vSphere UI must use a logging mechanism that is configured to allocate log record storage capacity large enough to accommodate the logging requirements of the web server.
     [PASS]  Command: `rpm -V vsphere-ui|grep serviceability.xml|grep "^..5......"` stdout.strip is expected to eq ""
  [PASS]  VCUI-70-000029: vSphere UI log files must be moved to a permanent repository in accordance with site policy.
     [PASS]  Command: `rpm -V VMware-visl-integration|grep vmware-services-vsphere-ui.conf|grep "^..5......"` stdout.strip is expected to eq ""
  [PASS]  VCUI-70-000030: vSphere UI must be configured with the appropriate ports.
     [PASS]  5090 is expected to eq "5090"
     [PASS]  443 is expected to eq "443"
  [PASS]  VCUI-70-000031: vSphere UI must disable the shutdown port.
     [PASS]  XML /usr/lib/vmware-vsphere-ui/server/conf/server.xml ["/Server/@port"] is expected to cmp == "${shutdown.port}"
     [PASS]  JSON /etc/vmware/vmware-vmon/svcCfgfiles/vsphere-ui.json StartCommandArgs is expected to include "-Dshutdown.port=-1"
  [PASS]  VCUI-70-000032: vSphere UI must set the secure flag for cookies.
     [PASS]  XML /usr/lib/vmware-vsphere-ui/server/conf/web.xml /web-app/session-config/cookie-config/secure is expected to cmp == "true"
  [PASS]  VCUI-70-000033: The vSphere UI default servlet must be set to "readonly".
     [PASS]  XML /usr/lib/vmware-vsphere-ui/server/conf/web.xml /web-app/servlet[servlet-name="default"]/init-param[param-name="readonly"]/param-value is expected to eq []


Profile Summary: 313 successful controls, 17 control failures, 0 controls skipped
Test Summary: 1516 successful, 106 failures, 0 skipped

Convert the results to CKL

If a STIG Viewer CKL file is needed then the results from the scans can be converted to CKL with the SAF CLI.

# Converting the VCSA scan results from the prior section to CKL
saf convert hdf2ckl -i C:\inspec\Reports\MyVCSAReport.json -o C:\inspec\Reports\MyVCSAReport.ckl --hostname 10.182.131.166 --fqdn myvcenter.local --ip 10.182.131.166 --mac 00:00:00:00:00:00

Opening the CKL file in STIG Viewer will look like the screenshot below. Note the InSpec results are included in the Finding Details pane.

alt text

4 - Remediate vSphere 7

Remediating vSphere 7 for STIG Compliance

Overview

Remediating vSphere for STIG compliance involves configuring ESXi, Virtual Machines, vCenter, and the vCenter appliance.

When remediating vSphere we will split up tasks between product and appliance based controls which are defined as follows:

  • Product Control: Configurations that interact with the Product via the User Interface or API that are exposed to administrators. Whether these are Default or Non-Default, the risk of mis-configuration effecting availability of the product is low but could impact how the environment is operated if not assessed.
  • Appliance Control: Appliance controls deal with the underlying components (databases, web servers, Photon OS, etc) that make up the product. Altering these add risk to product availability without precautionary steps and care in implementation. Identifying and relying on Default settings in this category makes this category less risky (Default Appliance Controls should be seen as a positive).

To remediate vSphere, PowerCLI is the automation tool used, while for the VCSA we will use Ansible. For the vCenter appliance the remediation is performed via SSH. It is recommended to disable SSH on vCenter after configuration is complete.

Prerequisites

Versions listed below were used for this documentation. Other versions of these tools may work as well but if issues are found it is recommended to try the versions listed here.

Create Powershell credential for vCenter connection

The PowerCLI scripts provided use a Powershell Credential stored in a varialbe to authenticate to vCenter and should be established before attempting to run the scripts.

# Run the following command to generate a credential. Substitute the username as needed in your environment. Note if ran in Powershell 5.x on Windows this will popup a window to enter the credentials.
$vccred = Get-Credential

PowerShell credential request
Enter your credentials.
User: administrator@vsphere.local
Password for user administrator@vsphere.local: ****************

Remediating ESXi product controls

To remediate ESXi hosts we have provided a PowerCLI script that will target a single host or a vSphere cluster based on parameters provided to the script.

Note: There are some controls that cannot be remediated with PowerCLI and are not addressed by this script. The output will indicate that these are manual controls.

Gather environment information

In order to run the script effectively it must be provided with the organizations environment specific information.

Review the below parameters and gather the information needed to run the script:

[CmdletBinding()]
param (
  [Parameter(Mandatory = $true)]
  [string]$vcenter,
  [Parameter(Mandatory = $true)]
  [pscredential]$vccred,
  [Parameter(Mandatory = $true, ParameterSetName = "hostname")]
  [string]$hostname,
  [Parameter(Mandatory = $true, ParameterSetName = "cluster")]
  [string]$cluster,
  [Parameter(Mandatory = $false,
    HelpMessage = "Enter the path for the output report. Example /tmp")]
  [string]$reportpath,    
  [Parameter(Mandatory = $true,
    HelpMessage = "Enter the Active Directory Admins group to use for administrative access to ESXi")]
  [string]$esxAdminGroup,
  [Parameter(Mandatory = $true,
    HelpMessage = "Enter allowed IP ranges for the ESXi firewall in comma separated format.  For Example `"192.168.0.0/16`",`"10.0.0.0/8`" ")]
  [string[]]$allowedIPs,
  [Parameter(Mandatory = $false,
    HelpMessage = "Enter the syslog server for the ESXi server(s). Example tcp://log.domain.local:514")]
  [string]$syslogServer,
  [Parameter(Mandatory = $false,
    HelpMessage = "Enable this option if VMware vRealize Log Insight is used to manage syslog on the ESXi host(s).")]
  [switch]$logInsight,
  [Parameter(Mandatory = $true,
    HelpMessage = "Enter NTP servers.  For Example `"10.1.1.1`",`"10.1.1.2`" ")]
  [string[]]$ntpServers,
  [Parameter(Mandatory = $false,
    HelpMessage = "Specify the native VLAN Id configured on the ports going to the ESXi Hosts.  If none is specified the default of 1 will be used.")]
  [string]$nativeVLAN = "1"
)

Disabling Controls

The script includes varialbes to enable or disable controls by STIG ID. All controls are all enabled by default and can be turned off by changing these variables to $false for a specific control.

A snippet of these variables is shown below.

##### Enable or Disable specific STIG Remediations #####
$controlsenabled = [ordered]@{
  ESXI70000001 = $true  #Lockdown Mode
  ESXI70000002 = $true  #DCUI.Access List
  ESXI70000003 = $true  #Lockdown Mode Exceptions
  ESXI70000004 = $true  #Syslog

Run remediation script on target ESXi hosts

This example will remediate all hosts in the vSphere cluster named cluster0. If running on a single host is desired, specify the hostname parameter instead of cluster and provide the hostname as displayed in vCenter.

# Running the script.
> .\VMware_vSphere_7.0_STIG_ESXi_Remediation.ps1 -vcenter 10.182.131.166 -vccred $vccred -cluster "cluster0" -esxAdminGroup "MyESXiGroup" -allowedIPs "10.0.0.0/8" -ntpServers "time-a-g.nist.gov","time-b-g.nist.gov" -syslogServer "tcp://loginsight.vmware.com:514" -reportpath C:\Temp

# Snippet from the output of running the script.
Transcript started, output file is C:\Temp\VMware_vSphere_7.0_STIG_ESXi_Remediation_Transcript_5-25-2023_9-26-8.txt
9:26:09 AM ...Core detected...checking for VMware.PowerCLI
9:26:09 AM ...Trying to import module VMware.PowerCLI
9:27:13 AM ...Connecting to vCenter 10.182.131.166
9:27:16 AM ...Gathering info on target hosts in 10.182.131.166
9:27:19 AM ...Found host 10.182.131.186
9:27:19 AM ...Found host 10.182.132.6
9:27:19 AM ...Found host 10.182.138.1
9:27:19 AM ...Remediating STIG ID:ESXI-70-000002 with Title: The ESXi host must verify the DCUI.Access list.
9:27:20 AM ...Setting DCUI.Access is already configured correctly to root on 10.182.131.186
9:27:20 AM ...Setting DCUI.Access is already configured correctly to root on 10.182.132.6
9:27:20 AM ...Setting DCUI.Access is already configured correctly to root on 10.182.138.1
9:27:20 AM ...Remediating STIG ID:ESXI-70-000003 with Title: The ESXi host must verify the exception users list for lockdown mode.
9:27:20 AM ...No exception users found on 10.182.131.186
9:27:20 AM ...No exception users found on 10.182.132.6
9:27:21 AM ...No exception users found on 10.182.138.1
9:27:21 AM ...Remediating STIG ID:ESXI-70-000004 with Title: Remote logging for ESXi hosts must be configured.
9:27:21 AM ...Setting Syslog.global.logHost was incorrectly set to  on 10.182.131.186...setting to tcp://loginsight.vmware.com:514

Name                 Value                Type                 Description
----                 -----                ----                 -----------
Syslog.global.logHo tcp://loginsight.vm VMHost
9:27:25 AM ...Setting Syslog.global.logHost was incorrectly set to  on 10.182.132.6...setting to tcp://loginsight.vmware.com:514
Syslog.global.logHo tcp://loginsight.vm VMHost
9:27:28 AM ...Setting Syslog.global.logHost was incorrectly set to  on 10.182.138.1...setting to tcp://loginsight.vmware.com:514
Syslog.global.logHo tcp://loginsight.vm VMHost

# A results file and Powershell transcript is provided in the report path specified.
Directory: C:\Temp

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           5/25/2023  9:30 AM           6224 VMware_vSphere_7.0_STIG_ESXi_Remediation_Results_5-25-2023_9-26-8.json
-a---           5/25/2023  9:30 AM          89142 VMware_vSphere_7.0_STIG_ESXi_Remediation_Transcript_5-25-2023_9-26-8.txt

Remediating virtual machines product controls

To remediate virtual machines we have provided a PowerCLI script that will target a single VM, all VMs in a cluster, or all VMs in vCenter based on parameters provided to the script.

Note: There are some controls that cannot be remediated with PowerCLI and are not addressed by this script. See the scripts description text for more details.

Disabling Controls

For processing efficiency it is not constructed to run each control individually so the STIG ID variables are not included to enabled/disable controls such as in the ESXi/vCenter scripts. If it is desired to skip some controls they could be commented out in the $vmconfig variable in the script.

Run remediation script on target virtual machines

This example will remediate all hosts in the vSphere cluster named cluster0. If running on a single host is desired, specify the hostname parameter instead of cluster and provide the hostname as displayed in vCenter.

# Running the script.
> .\VMware_vSphere_7.0_STIG_VM_Remediation.ps1 -vcenter 10.182.131.166 -vccred $vccred -cluster "cluster0" -reportpath C:\Temp

# Snippet from the output of running the script.
Transcript started, output file is C:\Temp\VMware_vSphere_7.0_STIG_VM_Remediation_Transcript_5-25-2023_10-19-28.txt
10:19:28 AM ...Core detected...checking for VMware.PowerCLI
10:19:28 AM ...Connecting to vCenter Server 10.182.131.166
10:19:31 AM ...Getting PowerCLI objects for all virtual machines in cluster: cluster0
10:19:31 AM ...Remediating advanced settings on stig space test on 10.182.131.166
10:19:31 AM ...Setting isolation.device.connectable.disable does not exist on stig space test creating setting...

Name                 Value                Type                 Description
----                 -----                ----                 -----------
isolation.device.co True                 VM
10:19:34 AM ...Setting isolation.tools.copy.disable does not exist on stig space test creating setting...
isolation.tools.cop True                 VM
10:19:36 AM ...Setting isolation.tools.diskShrink.disable does not exist on stig space test creating setting...
isolation.tools.dis True                 VM

# A results file and Powershell transcript is provided in the report path specified.
Directory: C:\Temp

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           5/25/2023 10:20 AM           1055 VMware_vSphere_7.0_STIG_VM_Remediation_Results_5-25-2023_10-19-28.json
-a---           5/25/2023 10:22 AM          13150 VMware_vSphere_7.0_STIG_VM_Remediation_Transcript_5-25-2023_10-19-28.txt

Remediating vCenter product controls

To remediate vCenter we have provided a PowerCLI script that will target a single vCenter server.

Note: There are some controls that cannot be remediated with PowerCLI and are not addressed by this script. The output will indicate that these are manual controls.

Gather environment information

In order to run the script effectively it must be provided with the organizations environment specific information.

This script also uses the VMware.Vsphere.SsoAdmin PowerCLI Module to configure vCenter SSO controls. This module connects to vCenter separately using the Connect-SsoAdminServer command that requires using an account that has sufficient privileges in vCenter to modify SSO settings.

Review the below parameters and gather the information needed to run the script:

[CmdletBinding()]
param (
  [Parameter(Mandatory=$true)]
  [string]$vcenter,
  [Parameter(Mandatory=$true)]
  [pscredential]$vccred,
  [Parameter(Mandatory=$false,
  HelpMessage="Enter the path for the output report. Example /tmp")]
  [string]$reportpath,
  [Parameter(Mandatory=$false,
  HelpMessage="If Netflow is used enter the collector IP address")]
  [string]$vcNetflowCollectorIp = "",
  [Parameter(Mandatory=$false,
  HelpMessage="To disable Netflow on all port groups if enabled set to true")]
  [boolean]$vcNetflowDisableonallPortGroups = $false
)

Disabling Controls

The script includes varialbes to enable or disable controls by STIG ID. All controls are all enabled by default and can be turned off by changing these variables to $false for a specific control.

A snippet of these variables is shown below.

##### Enable or Disable specific STIG Remediations #####
$controlsenabled = [ordered]@{
  VCSA7000009 = $true  #TLS 1.2
  VCSA7000023 = $true  #SSO Login Attempts
  VCSA7000024 = $true  #SSO Banner - Manual
  VCSA7000034 = $true  #config.log.level
  VCSA7000057 = $true  #Plugins - Manual

Run remediation script on target vCenter server

This example will remediate all controls on a target vCenter server.

# Running the script.
> .\VMware_vSphere_7.0_STIG_vCenter_Remediation.ps1 -vcenter 10.182.131.166 -vccred $vccred -reportpath C:\Temp

# Snippet from the output of running the script.
Transcript started, output file is C:\Temp\VMware_vSphere_7.0_STIG_ESXi_Remediation_Transcript_5-25-2023_11-30-58.txt
11:30:58 AM ...Core detected...checking for VMware.PowerCLI
11:30:58 AM ...Module VMware.PowerCLI is already imported.
11:30:58 AM ...Core detected...checking for VMware.Vsphere.SsoAdmin
11:30:58 AM ...Module VMware.Vsphere.SsoAdmin is already imported.
11:30:58 AM ...Connecting to vCenter Server 10.182.131.166
11:30:59 AM ...Connecting to vCenter SSO Server 10.182.131.166
11:31:00 AM ...Verifying vCenter 10.182.131.166 is version 7.0.x
11:31:00 AM ...vCenter 10.182.131.166 is version 7.0.3 continuing...
11:31:00 AM ...Getting PowerCLI objects for all virtual distributed switches in vCenter: 10.182.131.166
11:31:01 AM ...Getting PowerCLI objects for all virtual distributed port groups in vCenter: 10.182.131.166
11:31:02 AM ...Remediating STIG ID: VCSA-70-000009 with Title: The vCenter Server must use TLS 1.2, at a minimum, to protect the confidentiality of sensitive data during electronic dissemination using remote access.
11:31:02 AM ...!!This control must be remediated manually!!
11:31:02 AM ...Remediating STIG ID: VCSA-70-000023 with Title: The vCenter Server must enforce the limit of three consecutive invalid logon attempts by a user.
11:31:02 AM ...SSO login attempts set incorrectly on 10.182.131.166
11:31:03 AM ...Remediating STIG ID: VCSA-70-000024 with Title: The vCenter Server must display the Standard Mandatory DoD Notice and Consent Banner before logon.
11:31:03 AM ...!!This control must be remediated manually!!
11:31:03 AM ...Remediating STIG ID: VCSA-70-000034 with Title: The vCenter Server must produce audit records containing information to establish what type of events occurred.
11:31:03 AM ...Setting config.log.level is already configured correctly to info on 10.182.131.166

# A results file and Powershell transcript is provided in the report path specified.
Directory: C:\Temp

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           5/25/2023 11:33 AM           2543 VMware_vSphere_7.0_STIG_vCenter_Remediation_Results_5-25-2023_11-33-25.json
-a---           5/25/2023 11:33 AM          18763 VMware_vSphere_7.0_STIG_vCenter_Remediation_Transcript_5-25-2023_11-33-25.txt

Remediating vCenter server appliance controls

To remediate vCenter we have provided an Ansible playbook that will target a single vCenter server appliance over SSH and configure any non-compliant controls.

Since Ansible can only be ran from Linux based systems, the examples below are being ran on an Ubuntu 22.04 WSL2 instance on Windows 11 for reference.

Backups

Before running it is highly advised to have a backup of the VCSA and/or snapshot available if a rollback is required. Also the playbook will backup files configured before updates and place them under the /tmp directory in a folder directly on the VCSA.

Update the default shell for root

The default shell for root must be changed to /bin/bash before running. The appliance shell causes issues with some controls running.

# SSH to vCenter
Connected to service

    * List APIs: "help api list"
    * List Plugins: "help pi list"
    * Launch BASH: "shell"

Command> shell.set --enabled true
Command> shell
Shell access is granted to root
root@sc1-10-182-131-166 [ ~ ]# chsh -s /bin/bash root

Ansible dependencies

The playbook is written to use the separate Photon 3.0 playbook we have avaiable and must be installed as a role prior to running.

Also there are two ansible collections that must be installed if on a version of Ansible newer than 2.9.

# Installing playbook requirements from the requirements.yml file provided.
ansible-galaxy roles install -r requirements.yml

Running the playbook

To run all of the VCSA controls, follow the example below.

# The -k parameter will prompt for password and we are using extra-vars to specify a variable file for the playbook to use.
> ansible-playbook -i 10.182.131.166, -u root playbook.yml -k -v --extra-vars @vars-vcenter-7.0U3eplus.yml

# Output example
SSH password:

PLAY [all] ********************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************
ok: [10.182.131.166]

TASK [vmware-photon-3.0-stig-ansible-hardening : Include Photon] **************************************************************************************************************************************************************
included: /home/rlakey/.ansible/roles/vmware-photon-3.0-stig-ansible-hardening/tasks/photon.yml for 10.182.131.166

TASK [vmware-photon-3.0-stig-ansible-hardening : Create time stamp] ***********************************************************************************************************************************************************
ok: [10.182.131.166] => {"ansible_facts": {"backup_timestamp": "2023-05-25-12-25-58"}, "changed": false}

TASK [vmware-photon-3.0-stig-ansible-hardening : Backup files...if restoring be sure to restore permissions that original file had!!] *****************************************************************************************
ok: [10.182.131.166] => (item=/etc/rsyslog.conf) => {"ansible_loop_var": "item", "changed": false, "checksum": "7aa11dc58f144160e7e3dc2d40cb2f03a39a989c", "dest": "/tmp/ansible-backups-2023-05-25-12-25-58/rsyslog.conf", "gid": 0, "group": "root", "item": "/etc/rsyslog.conf", "md5sum": "d31d58ff2bbc5cff6b7f343c2580300c", "mode": "0644", "owner": "root", "size": 4000, "src": "/etc/rsyslog.conf", "state": "file", "uid": 0}
ok: [10.182.131.166] => (item=/etc/issue) => {"ansible_loop_var": "item", "changed": false, "checksum": "930cb25fc842aca6047cb9fc1bfbd6ea191e686f", "dest": "/tmp/ansible-backups-2023-05-25-12-25-58/issue", "gid": 0, "group": "root", "item": "/etc/issue", "md5sum": "f498b74a84aaa39e292d9b815899144d", "mode": "0644", "owner": "root", "size": 104, "src": "/etc/issue", "state": "file", "uid": 0}
ok: [10.182.131.166] => (item=/etc/audit/rules.d/audit.STIG.rules) => {"ansible_loop_var": "item", "changed": false, "checksum": "38f324fe67c6943e07ef1910b41dedeb0b256ca4", "dest": "/tmp/ansible-backups-2023-05-25-12-25-58/audit.STIG.rules", "gid": 0, "group": "root", "item": "/etc/audit/rules.d/audit.STIG.rules", "md5sum": "396d715044fc7a8d92a0332d3edb4112", "mode": "0640", "owner": "root", "size": 5080, "src": "/etc/audit/rules.d/audit.STIG.rules", "state": "file", "uid": 0}

TASK [vmware-photon-3.0-stig-ansible-hardening : PHTN-30-000001 - Update/Create audit.STIG.rules file] ************************************************************************************************************************
changed: [10.182.131.166] => {"changed": true, "checksum": "aaafa4e8c28743ce3cc22c818f28f4cb9a3f53b2", "dest": "/etc/audit/rules.d/audit.STIG.rules", "gid": 0, "group": "root", "md5sum": "91a31e7bbf9e3f0d7f390feb4360581b", "mode": "0640", "owner": "root", "size": 5180, "src": "/root/.ansible/tmp/ansible-tmp-1685039234.3606877-890-106251101523760/source", "state": "file", "uid": 0}

A more conservative and preferred approach is to target any non-compliant controls or run each component separately allowed you to perform any functional testing in between.

# Providing the tag "eam" will instruct the playbook to only run the eam role. This tag can be seen in each roles task/main.yml file.
> ansible-playbook -i 10.182.131.166, -u root playbook.yml -k -v --extra-vars @vars-vcenter-7.0U3eplus.yml --tags eam

# Providing the tag "VCEM-70-000001" will instruct the playbook to only run task tagged with the STIG ID of VCEM-70-000001.
> ansible-playbook -i 10.182.131.166, -u root playbook.yml -k -v --extra-vars @vars-vcenter-7.0U3eplus.yml --tags VCEM-70-000001