8 minute read

You can use a Bash script to audit Distributed Firewall (DFW) rule counts across virtual machines and hosts in your NSX environment, helping identify rule bloat and optimize firewall performance.

In NSX, as you create and modify firewall policies over time, DFW rules can accumulate on individual vNICs. Excessive rules per vNIC can impact throughput and latency. The NSX documentation provides guidance on rule limits, but there’s no built-in automated way to enumerate and aggregate rule counts across all VMs on a host.

Use Case

  • NSX environment running on ESXi hosts with DFW enabled
  • Security administrators need to identify VMs approaching rule count limits
  • Operations teams require per-host and per-VM rule distribution for capacity planning
  • Troubleshooting scenarios where DFW performance is degraded
  • Audit and compliance reporting on firewall rule sprawl

Solution

The solution is a Bash script that runs directly on an ESXi host, leveraging native NSX CLI tools (vsipioctl, summarize-dvfilter, vim-cmd) to enumerate filters, count rules per vNIC, correlate with VM names, and produce a comprehensive report.

Script Features

  • Runs natively on ESXi - no external dependencies, uses built-in NSX CLI tools
  • Single-pass data collection - collects summarize-dvfilter and vsipioctl getfilters once, reuses in memory
  • VM name resolution - correlates vNIC filter UUIDs to human-readable VM names via vim-cmd cache and dvfilter mapping
  • Per-VM rule count table - formatted output showing VM name, filter UUID, and rule count
  • High rule count alerting - identifies VMs exceeding 4000 rules (NSX recommended limit)
  • Summary statistics - totals, averages, and distribution buckets
  • Top 5 VMs by rule count - quick identification of heaviest consumers
  • Verbose mode - optional detailed rule listing per vNIC for deep inspection
  • Zero temp files - all processing in memory using Bash associative arrays

Prerequisites

  • ESXi host with NSX DFW configured and running
  • Access to ESXi shell (SSH or console)
  • NSX VIBs installed (vsipioctl, summarize-dvfilter available)
  • Appropriate privileges to run vim-cmd vmsvc/get.config

Script Parameters

Parameter Description
-v Verbose output - shows individual rule details per vNIC
-h Show help message

Usage Examples

./count_dfw_rules-v2.1.sh

2. Verbose output with individual rule details

./count_dfw_rules-v2.1.sh -v

3. Show help

./count_dfw_rules-v2.1.sh -h

How It Works

1. Environment Validation

The script validates it’s running on an ESXi host with NSX by checking for required commands:

  • vsipioctl - NSX vShield endpoint CLI
  • summarize-dvfilter - DVFilter summary tool
  • vim-cmd - VM management CLI

If any are missing, the script exits with an error.

2. Data Collection (Single Pass)

The script collects all raw data once to minimize overhead:

  • summarize-dvfilter - Maps world IDs to VM names via vmm device names
  • vsipioctl getfilters - Lists all NSX filters (one per vNIC) with their UUIDs
  • vim-cmd vmsvc/get.config - Resolves world IDs to VM display names (cached per world ID)

3. Lookup Table Construction

Two in-memory associative arrays are built:

  • WORLD_VM_MAP - world_id → VM name from dvfilter output (fallback)
  • VIM_CACHE - world_id → VM name from vim-cmd (primary, more reliable)

The vim-cmd cache is pre-populated with a single call per unique world ID for efficiency.

4. Per-Filter Rule Counting

For each NSX filter (vNIC):

  1. Count rules - vsipioctl getrules -f <filter> piped to grep -c "rule"
  2. Find world_id - Search dvfilter output for the filter UUID, extract preceding world line
  3. Resolve VM name - Priority: VIM_CACHEWORLD_VM_MAP → filter UUID as fallback
  4. Store results - Accumulate in arrays for later statistics

5. Reporting and Analysis

After processing all filters:

  • Per-VM table - Formatted columns: VM Name, Filter UUID, Rule Count
  • High rule count alert - Lists VMs with >4000 rules (configurable threshold)
  • Summary statistics - Total VMs, total rules, average rules/VM
  • Distribution buckets - 0-100, 101-500, 501-1000, 1001-2000, 2001-4000, >4000
  • Top 5 VMs - Sorted descending by rule count

6. Verbose Mode (Optional)

When -v is specified, the script additionally outputs:

  • Debug lookup source (VIM_CACHE vs WORLD_VM_MAP) per vNIC
  • Full rule listing for each vNIC (first 30 lines via head)

Safety Features

The script is read-only and non-destructive:

  1. No modifications - Only queries NSX and ESXi state
  2. No temp files - All processing in memory
  3. Graceful degradation - Falls back to filter UUID if VM name resolution fails
  4. Error suppression - Failed commands don’t halt execution; results marked as 0
  5. Single execution - Data collected once, reused throughout

Sample Output

When run in basic mode:

==============================================
ESXi DFW Rules Count - Per VM and Per Host
==============================================

Host: esxi-01.lab.local
ESXi Version: VMware ESXi 7.0.3 build-18905247
Date: 2026-08-01 14:58:02

----------------------------------------------
Collecting Data
----------------------------------------------

----------------------------------------------
Building VM Name Lookup Tables
----------------------------------------------
VM lookup tables built: 42 names from vim-cmd, 45 from dvfilter

==============================================
DFW Rules Count - Per VM
==============================================
Virtual Machine                          VM UUID (Filter)     DFW Rules Count
--------------------------------------------------------------------------------------------------------
web-01                                   550e8400-e29b-41d4-a716-446655440000  1247
app-02                                   550e8400-e29b-41d4-a716-446655440001  3892
db-01                                    550e8400-e29b-41d4-a716-446655440002  567
...

----------------------------------------------
VMs with >4000 DFW Rules
----------------------------------------------
app-02                                   550e8400-e29b-41d4-a716-446655440001  3892

Total VMs with >4000 rules: 1

==============================================
Summary Statistics
==============================================
Total VMs with DFW: 42
Total DFW Rules on Host: 89234
Average Rules per VM: 2124

----------------------------------------------
Distribution of VMs by Rule Count
----------------------------------------------
  0-100            :  12 VMs ( 28.6%)
  101-500          :  15 VMs ( 35.7%)
  501-1000         :   5 VMs ( 11.9%)
  1001-2000        :   4 VMs (  9.5%)
  2001-4000        :   5 VMs ( 11.9%)
  >4000            :   1 VMs (  2.4%)

----------------------------------------------
Top 5 VMs by Rule Count
----------------------------------------------
  app-02                                          : 3892 rules
  web-01                                          : 1247 rules
  lb-01                                           : 987 rules
  app-03                                          : 876 rules
  db-01                                           : 567 rules

==============================================
Completed: 2026-08-01 14:58:15

When run with -v:

DEBUG: 550e8400-e29b-41d4-a716-446655440001 -> VIM_LOOKUP=app-02
  --- Rules for 550e8400-e29b-41d4-a716-446655440001 ---
rule 1001: action=allow, src=any, dst=any, service=HTTP, ...
rule 1002: action=deny, src=10.0.0.0/8, dst=any, service=any, ...
...

Customization Options

The script can be easily customized for different environments:

  • Adjust the high rule count threshold (default 4000) by modifying the comparison on line 174
  • Modify distribution buckets in the awk block (lines 199-220) for different granularity
  • Change Top N VMs count (default 5) in the head -5 on line 229
  • Extend verbose output by adjusting head -30 on line 162
  • Add JSON/CSV export by appending formatted output to the results arrays

Troubleshooting

Common issues and solutions:

No NSX DFW Configured

  • Script outputs: WARNING: No NSX DFW configured and exits with 0
  • Verify NSX is installed and DFW is enabled on the host

Commands Not Found

  • Error: vsipioctl not found. Run on ESXi with NSX installed.
  • Ensure NSX VIBs are installed: esxcli software vib list | grep -i nsx
  • Run directly on ESXi host, not vCenter or remote machine

VM Name Resolution Failures

  • VM names show as filter UUIDs instead of friendly names
  • Verify vim-cmd vmsvc/get.config <world_id> works manually
  • Check summarize-dvfilter output includes vmm device names

Permission Denied

  • Ensure running as root or with appropriate ESXi shell privileges
  • vim-cmd requires hostd access

Empty Results

  • If total_rules=0 but DFW is enabled, check vsipioctl getfilters output manually
  • Verify filters are attached to running VMs (powered off VMs have no active filters)

Conclusion

This Bash script provides a lightweight, dependency-free way to audit DFW rule distribution across your NSX-on-ESXi environment. By running directly on the host and leveraging native CLI tools, it delivers immediate visibility into rule counts without requiring external APIs, collectors, or management plane connectivity.

The read-only design makes it safe for production use during maintenance windows or routine audits. The summary statistics and distribution buckets help identify outliers quickly, while the verbose mode supports deep-dive troubleshooting when specific VMs show abnormal rule counts.

Regular execution of this script as part of operational hygiene can prevent rule bloat from silently degrading DFW performance and help maintain compliance with NSX best practices for rule limits per vNIC.