
The VMware Cloud Provider Pod Designer produced a bunch of documentation which is really useful (even if you don't use the _Deployer_ to actually, err... deploy). One of the options in the Designer is to forgo having NSX deployed in the management stack. Instead, we leave a load of dangling VLANs and let you connect them together with your own external network/security stack. The "icing on the cake" would be if you could not only find the network topology in the Designer downloads (which you can), but also the firewall policies necessary to make the whole shebang work (which you can't).
Fortunately, all the information we need is inside the configData.cfg
file in the Designer bundle, but not in a very friendly format. What we need is a slick tool to extract the firewall policy data and present it in a neat way. Sadly, we don’t have that, but what we do have is a PowerShell script/cmdlet that I wrote to do the job instead…
If you’re the sort who thinks RTFM is for wimps, you can jump straight to the code here.
Background
This post has been sitting in Drafts for a while now. My VMware colleagues who needed to extract copies of the Pod Designer firewall had access to the PowerShell script and tested it in the real world. However, the world has moved on, and the Cloud Provider Pod is destined for bigger and better things now, so the useful shelf-life of this particular script is already past its sell-by date. However, partly as there are some useful bits of PowerShell which I’m sure will come in handy at some point, and partly in case anyone should actually need it, I decided to quietly release the post. If I can get github to work, I’ll make the code available from there too.
I started to write this in rusty Python and PowerShell at the same time. I wanted to use the challenge to learn a little PowerShell but fully expected to complete the tool in Python which I had much more experience with. However, along the journey I discovered some typically MicroSoft style capabilities which made the PowerShell version far more useful with much less effort. I find that if you want to do what Microsoft intended, their tools can be brilliant. But, if you want to go your own way and Microsoft didn’t think that likely, their tools often put up a great deal of resistance. I liked PowerShell so I guess I fell into line with its developers, or they had a broad enough set of use cases that my tiny one was covered.
The cmdlet
The Cmdlet needs PowerShell Core 6.23 or later to run it. It won’t work on the version of PowerShell which comes with Windows Desktop/Server. I used a couple of features from PS Core as I thought I’d get shouted at if I used the Windows-only version of PS anyway, and they made some of the importing much easier.
The code
You can grab the code from GitHub using the usual methods, but if you want to browse the code first, here it is.
.Notes
==============================================================================
Written by: Steve Dockar
Organization: VMware
Twitter: @SteveDockar
Blog: notthe.blog
Version: 20191119 - Pretty PortList on PS Object, -strict switch
and PortsFile.json to override port desc text
Version: 20191112 - Default output now PowerShell objects
==============================================================================
.Synopsis
Produces firewall policy output from VMware Cloud Provider Pod Designer "configData.cfg" file
.Description
Extracts IP addresses, netmasks and other sundry variables and outputs PSCustomObject for each rule or a text-based firewall policy (using -AsText) for use when deploying non-SDN based Pods.
.Parameter ConfigFile
Absolute or relative path to configData.cfg from Designer Zip file.
.Parameter PortsFile
Absolute or relative path to json file containing port description output overrides.
.Parameter PxeRangeRp00
PXE/TFTP Range for ESXi boot/config
.Parameter North
Output North Edge/Firewall policy
.Parameter South
Output South Edge/Firewall policy
.Parameter AsText
Change output from PowerShell objects to simple (slightly) formatted text.
.Parameter Strict
Change output ports from default Deployer "Any" to Application specific ones.
.Example
# Default full text-based output
Get-PodFirewall /path/to/configData.cfg "192.168.1.1-192.168.1.99" -AsText
.Example
# Pass Pxe range as subnet
Get-PodFirewall /path/to/configData.cfg "192.168.1.0/24"
.Example
# Output only North Edge/Firewall policy as text.
Get-PodFirewall /path/to/configData.cfg "192.168.1.1-192.168.1.99" -North -AsText
.Example
# Output entire policy as CSV
Get-PodFirewall /path/to/configData.cfg "192.168.1.1-192.168.1.99" | Export-CSV /path/to/output.csv
.Example
# Output entire policy as JSON ( and redirect to file)
Get-PodFirewall /path/to/configData.cfg "192.168.1.1-192.168.1.99" | ConvertTo-JSON >/path/to/output.json
.Example
# Override port descriptions with external ports.json file
Get-PodFirewall /path/to/configData.cfg [-PortsFile] /path/to/ports.json [-PxeRangerp00] "192.168.1.1-192.168.1.99"
#>
<#
===================================================================================================================
If you want to replace the text in the Port descriptions, copy the JSON/text below, from "{" to "}" inclusive, into a ports.json file. Edit the "<SVC> (nnn/xxx)" on the right hand side of each line to suit your requirements, and then add -PortsFile '/path/to/ports.json' when you call the script. Your descriptions will then override the built in ones. Don't change the left hand side or the script won't match them. You can also edit $AppIDs in this script directly of course, but you'll lose those changes if you update the script to a newer version.
The examples below have the extra ">" so that you can see -PortsFile has worked before you edit it yourself.
-----8<-----
{
"dnsudp": ">DNS (53/UDP)",
"http": ">HTTP (80/TCP)",
"https": ">HTTPS (443/TCP)",
"ntp": ">NTP (123/UDP)",
"icmpecho": ">ICMP (Echo/Reply)",
"smtp": ">SMTP (25/TCP)",
"ssh": ">SSH (22/TCP)",
"ftp": ">FTP (20/TCP, 21/TCP)",
"rmq1": ">RMQ (5671/TCP)",
"rmq2": ">RMQ (5672/TCP, 5672/UDP)",
"psql": ">PSQL (5432/TCP)",
"nfs": ">NFS (111/TCP, 111/UDP)",
"cas": ">CAS (9042/TCP)",
"syslog": ">Syslog (514/UDP, 514/TCP, 1514/TCP, 6514/TCP)",
"esx": ">ESX (623/UDP, 5988/TCP, 5989/TCP, 6500/TCP, 8000/TCP, 8001/TCP)",
"902": ">(902/TCP, 902/UDP",
"902T": ">902/TCP",
"903T": ">903/TCP",
"920": ">(920/TCP, 920/UDP",
"8443": "8443/TCP"
"61611T": ">61611/TCP",
"61616T": ">61616/TCP",
"tftp": ">Any(tftp)"
"any": ">Any"
}
----->8-----
==================================================================================================================
#>
Param (
# Path to Config File
[Parameter(Mandatory=$true)] [string] $ConfigFile,
# Path to Port override file
[Parameter(Mandatory=$false)] [string] $PortsFile,
# PXE Ports (subnet/range)
[Parameter(Mandatory=$false)] [string] $PxeRangeRp00 = "'pxe/tftp range'",
# Optional Switches
[Parameter(Mandatory=$false)] [switch] $North = $false,
[Parameter(Mandatory=$false)] [switch] $South = $false,
[Parameter(Mandatory=$false)] [switch] $AsText = $false,
[Parameter(Mandatory=$false)] [switch] $Strict = $false
)
$Config = Get-Content -Path $ConfigFile | ConvertFrom-Json -AsHashtable
$DhcpRangeRp00 = @( $PxeRangeRp00 ) # Turn param string into array for $Rule(src|dst)
$PSObject = (-not $AsText)
$In = " " # Centralise indent for write-rule
$InSize= $In.Length # Save checking on every Send-Rule
$Firewall = ""
$VcdCellsIp = @( $Config.vcdCellRp0001Ip, $Config.vcdCellRp0002Ip)
# Lookup table to convert AppId to more descriptive text
if ($PortsFile) {
# Write-Host "Importing Port Descriptions"
$AppIds = Get-Content -Path $PortsFile | ConvertFrom-Json -AsHashtable
} else {
$AppIds = @{
"dnsudp" = "DNS (53/UDP)";
"http" = "HTTP (80/TCP)";
"https" = "HTTPS (443/TCP)";
"ntp" = "NTP (123/UDP)";
"icmpecho" = "ICMP (Echo/Reply)";
"smtp" = "SMTP (25/TCP)";
"ssh" = "SSH (22/TCP)";
"ftp" = "FTP (20/TCP, (21/TCP)";
"rmq1" = "RMQ (5671/TCP)";
"rmq2" = "RMQ (5672/TCP, 5672/UDP)";
"psql" = "PSQL (5432/TCP)"; # PostgreSQL
"nfs" = "NFS (111/TCP, 111/UDP)";
"cas" = "CAS (9042/TCP)"; # Cassandra DB
"syslog" = "Syslog (514/UDP, 514/TCP, 1514/TCP, 6514/TCP)";
"esx" = "ESX (623/UDP, 5988/TCP, 5989/TCP, 6500/TCP, 8000/TCP, 8001/TCP)";
"902" = "(902/TCP, 902/UDP)";
"902T" = "902/TCP";
"903T" = "903/TCP";
"920" = "(920/TCP, 920/UDP)";
"8443" = "8443/TCP";
"61611T" = "61611/TCP";
"61616T" = "61616/TCP";
"tftp" = "Any";
"any" = "Any"
}
}
function Get-CidrMask {
# Pass in "Dotted Quad" mask and get back CIDR length
param (
[string]$dotMask
)
$mask = ([ipaddress] $dotMask).Address
for ($ml = 0; $mask -ne 0; $ml++) {
$mask = $mask -band ($mask -1)
}
return $ml
}
function Get-ClusterCount {
param (
$rpNo = 0
)
return $Config.$("rp"+ ([string]$rpNo).PadLeft(2, "0") + "ClusterCount")
}
function Get-HostCount {
param (
[string]$clNo = 1
)
return $Config.$("rp00Rc"+ ([string]$clNo).PadLeft(2, "0") + "HostCount")
}
function Get-HostInfo {
param (
[Int32]$rp = 0,
[Int32]$rc = 0,
[Int32]$hostNo = 1,
# Valid infoType(s) are: Ip, VsanIp, Mac, VmotionIp, Name, Password, VxlanIp, IpStorageIp
[String]$infoType = "Ip"
)
return $Config.("esxiRp" + ([string]$rp).PadLeft(2,"0") + "Rc" + ([string]$rc).PadLeft(2,"0") + ([string]$hostNo).PadLeft(2,"0") + $infoType)
}
function Get-ResourceEsxiRanges {
$hostRanges = @()
for ( $rc=0; $rc -lt (Get-ClusterCount); $rc++) {
$hostRanges += ( $(Get-HostInfo 0 $rc 1 "Ip") + "-" + $(Get-HostInfo 0 $rc (Get-HostCount "1") "Ip") )
}
return $hostRanges
}
$ResourceEsxiHosts = Get-ResourceEsxiRanges
# Output related functions
function Get-PrettyPorts {
param (
[array]$ports
)
# Build "pretty" ports list
$portList = @()
foreach ($id in $ports) {
if ( $AppIds.ContainsKey($id) ) {
$portList += $AppIds.$id
} else {
$portList += $id
}
}
return $portList
}
function Write-Rule {
param (
[string]$description,
[array]$srcIps,
[array]$dstIps,
[array]$ports
)
$portList = Get-PrettyPorts $ports
Write-Host -Object ($description)
Write-Host -Object ($In + "Source [" + ( $srcIps -join ", ") + "]" )
Write-Host -Object ($In + "Destination [" + ( $dstIps -join ", ") + "]" )
Write-Host -Object ($In + "Ports [" + ( $portList -join ", ") + "]" )
}
function New-RuleObject {
param (
# For now each RuleObject holds which fw N/S and the rule number as well as the rule data.
[string] $fwNS,
[int32] $ruleNo,
[string] $description,
[array] $srcIps,
[array] $dstIps,
[array] $ports
)
$portList = Get-PrettyPorts $ports
# Create a custom object
$ruleObject = [PSCustomObject]@{
RuleId = ($fwNS + "-" + [string]$ruleNo);
Firewall = $fwNS;
RuleNo = $ruleNo;
Description = $description;
Source = ( $srcIps -join ", " );
Destination = ($dstIps -join ", " );
Ports = ($portList -join ", " )
}
return $ruleObject
}
function Send-Rule {
if ($PSObject) {
# Create a FWRule custom object and add to RuleArray
New-RuleObject $Firewall $RuleCount $RuleDesc $RuleSrc $RuleDst $RulePorts
} else {
# Convenience wrapper as we're using global variables. 'Send' rule vars to 'Write-Rule'
$ruleNo = ([string]$script:RuleCount + ".").PadRight($InSize)
Write-Rule ($ruleNo + $RuleDesc) $RuleSrc $RuleDst $RulePorts
}
$Script:RuleCount += 1
}
# --------------------------------------------- Rules -------------------------------------------
# For each rule populate Desc, Src, Dst and Ports the call Send-Rule
function Get-NorthFirewall {
# Rule 1
$RuleDesc = "Outgoing traffic common for all machines in the network"
$RuleSrc = @( ($Config.mgmtVcdDmzNetwork + "/" + $(Get-CidrMask $Config.mgmtVcdDmzSubnet)),
($Config.mgmtVcdNetwork +"/" + $(Get-CidrMask $Config.mgmtVcdSubnet)),
($Config.mgmtInternalNetwork +"/" + $(Get-CidrMask $Config.mgmtInternalSubnet)),
($Config.rp00Rc00MgiNetwork +"/" + $(Get-CidrMask $Config.rp00Rc00MgiSubnet)) )
$RuleDst = @( "any" )
$RulePorts = @( "dnsudp", "http", "https", "ntp", "icmpecho", "smtp")
Send-Rule
# Rule 2
$RuleDesc = "vCD cell server to cassandra database nodes"
$RuleSrc = @( $Config.vcdCellRp0001Ip , $Config.vcdCellRp0002Ip )
$RuleDst = @( ($Config.vcdPfdbRp0001Ip + "-" + $Config.vcdPfdbRp0004Ip) )
$RulePorts = @( "any" ) # Deployer
if ($Strict) { $RulePorts = @( "cas" ) } # Actual Ports
Send-Rule
# Rule 3
$RuleDesc = "vCD cell server to postgreSQL database"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.vcdDbRp0001Ip)
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "psql" ) }
Send-Rule
# Rule 4
$RuleDesc = "vCD cell server to Rabbit MQ loadbalancer"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.vcdRabbLbsRp00Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "61611T", "61616T", "rmq2" ) }
Send-Rule
# Rule 5
$RuleDesc = "vCD cell server to VCSA Resource Pod"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.vcsaRp0001Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https", "902T", "903T" ) }
Send-Rule
# Rule 6 - Need to calculate ESXi cluster numbers and sizes for this - See Get-ClusterCound & Get-HostCount!
$RuleDesc = "vCD cell server to ESXi hosts Resource Pod"
$RuleSrc = $VcdCellsIp
$RuleDst = $ResourceEsxiHosts
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https", "902T", "903T" ) }
Send-Rule
# Rule 7
$RuleDesc = "vCD cell server to NSX Manager Resource Pod"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.nsxMgrRp0001Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# Rule 8
$RuleDesc = "vRealize Operations Tenant App to vRealize Operations Manager"
$RuleSrc = @( $Config.vropsMg0101TenantIp )
$RuleDst = @( $Config.vropsMg0101Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# Rule 9
$RuleDesc = "Rabbit MQ nodes to vRealize Orchestrator"
$RuleSrc = @( ($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip) )
$RuleDst = @( $Config.vroMg0101Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "rmq2" ) }
Send-Rule
# Rule 10
$RuleDesc = "Rabbit MQ nodes to vCloud Director"
$RuleSrc = @( ($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip) )
$RuleDst = $VcdCellsIp
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "rmq2" ) }
Send-Rule
# Rule 11
$RuleDesc = "vRealize Orchestrator to virtual machines and appliances"
$RuleSrc = @( $Config.vroMg0101Ip )
$RuleDst = $VcdCellsIp
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# Rule 12
$RuleDesc = "CPOD install server to vCD cell server and NFS transfer"
$RuleSrc = @( $Config.vcppInstallIp )
$RuleDst = $VcdCellsIp + $Config.vcdNfsRp0001Ip
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https", "nfs", "920" ) }
Send-Rule
# Rule 13
$RuleDesc = "CPOD vRealize Orchestrator to vCD cell server and NFS transfer"
$RuleSrc = @( $Config.vroMg0101Ip )
$RuleDst = $VcdCellsIp + $Config.vcdNfsRp0001Ip
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https", "nfs", "920" ) }
Send-Rule
# Rule 14
$RuleDesc = "vCD cell server to cpod install"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.vcppInstallIp )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# Rule 15
$RuleDesc = "Incoming to vCD LBS UI"
$RuleSrc = @( "any" )
$RuleDst = @( $Config.mgmtDmzVcdUiIp )
$RulePorts = @( "https" )
Send-Rule
# Rule 16
$RuleDesc = "Incoming to vCD LBS Console"
$RuleSrc = @( "any" )
$RuleDst = @( $Config.mgmtDmzVcdConsoleIp )
$RulePorts = @( "8443" )
Send-Rule
# Rule 17
$RuleDesc = "Incoming to vCD tenant App"
$RuleSrc = @( "any" )
$RuleDst = @( $Config.mgmtDmzVropsTenantIp )
$RulePorts = @( "https" )
if ($Strict) { $RulePorts = @( "http", "https" ) }
Send-Rule
# Rule 18
$RuleDesc = "vCD cell server to cpod install"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.vrliMg0101Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# [Rule 19]
if ($Config.vropsMg0101Deploy -eq "true") {
$RuleDesc = "vROPS tenant app to RabbitMQ"
$RuleSrc = @( $Config.vropsMg0101TenantIp )
$RuleDst = @( $Config.vcdRabbLbsRp00Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "rmq2" ) }
Send-Rule
}
}
function Get-SouthFirewall {
# Rule 1
$RuleDesc = "Outgoing traffic common for all machines in the network"
$RuleSrc = @( ($Config.mgmtVcdDmzNetwork + "/" + $(Get-CidrMask $Config.mgmtVcdDmzSubnet)) ,
($Config.mgmtVcdNetwork +"/" + $(Get-CidrMask $Config.mgmtVcdSubnet)) ,
($Config.mgmtInternalNetwork +"/" + $(Get-CidrMask $Config.mgmtInternalSubnet)) ,
($Config.rp00Rc00MgiNetwork +"/" + $(Get-CidrMask $Config.rp00Rc00MgiSubnet)) )
$RuleDst = @( "any" )
$RulePorts = @( "dnsudp", "http", "https", "ntp", "icmpecho", "smtp")
Send-Rule
# Rule 2
$RuleDesc = "FTP traffic for Centos machines to CPOD deployer"
$RuleSrc = @( ($Config.vcdPfdbRp0001Ip + "-" + $Config.vcdPfdbRp0004Ip),
($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip),
($Config.vcdCellRp0001Ip + "-" + $Config.vcdCellRp0002Ip),
$Config.vcdNfsRp0001Ip,
$Config.vcdDbRp0001Ip )
$RuleDst = @( $Config.vcppInstallIp )
$RulePorts = @( "ftp" )
Send-Rule
# Rule 3
$RuleDesc = "vCD cell server to cassandra database nodes"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.vcdPfdbRp0001Ip + "-" + $Config.vcdPfdbRp0004Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "cas" ) }
Send-Rule
# Rule 4
$RuleDesc = "vCD cell server to postgreSQL database"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.vcdDbRp0001Ip)
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "psql" ) }
Send-Rule
# Rule 5
$RuleDesc = "vCD cell server to Rabbit MQ loadbalancer"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.vcdRabbLbsRp00Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "61611T", "61616T", "rmq2" ) }
Send-Rule
# Rule 6
$RuleDesc = "vCD cell server to VCSA Resource Pod"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.vcsaRp0001Ip)
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https", "902T", "903T" ) }
Send-Rule
# Rule 7
$RuleDesc = "vCD cell server to ESXi hosts Resource Pod"
$RuleSrc = $VcdCellsIp
$RuleDst = $ResourceEsxiHosts
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https", "902T", "903T" ) }
Send-Rule
# Rule 8
$RuleDesc = "vCD cell server to NSX Manager Resource Pod"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.nsxMgrRp0001Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# Rule 9
$RuleDesc = "vRealize Operations Tenant App to vRealize Operations Manager"
$RuleSrc = @( $Config.vropsMg0101TenantIp )
$RuleDst = @( $Config.vropsMg0101Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# Rule 10
$RuleDesc = "Rabbit MQ nodes to vRealize Orchestrator"
$RuleSrc = @( ($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip) )
$RuleDst = @( $Config.vroMg0101Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "rmq2" ) }
Send-Rule
# Rule 11
$RuleDesc = "Rabbit MQ nodes to vCloud Director"
$RuleSrc = @( ($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip) )
$RuleDst = $VcdCellsIp
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "rmq2" ) }
Send-Rule
# Rule 12
$RuleDesc = "vRealize Orchestrator to virtual machines and appliances"
$RuleSrc = @( $Config.vroMg0101Ip )
$RuleDst = $VcdCellsIp
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# Rule 13
$RuleDesc = "CPOD install server to vCD cell server and NFS transfer"
$RuleSrc = @( $Config.vcppInstallIp )
$RuleDst = $VcdCellsIp + $Config.vcdNfsRp0001Ip
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https", "nfs", "920" ) }
Send-Rule
# Rule 14
$RuleDesc = "CPOD vRealize Orchestrator to vCD cell server and NFS transfer"
$RuleSrc = @( $Config.vroMg0101Ip )
$RuleDst = $VcdCellsIp + $Config.vcdNfsRp0001Ip
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https", "nfs", "920" ) }
Send-Rule
# Rule 15
$RuleDesc = "vCenter resource pod to ESXi hosts Resource Pod"
$RuleSrc = @( $Config.vcsaRp0001Ip)
$RuleDst = $ResourceEsxiHosts
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "http", "https", "902", "esx" ) }
Send-Rule
# Rule 16
$RuleDesc = "NSX Manager resource pod to ESXi hosts Resource Pod"
$RuleSrc = @( $Config.nsxMgrRp0001Ip)
$RuleDst = $ResourceEsxiHosts
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https", "902T" ) }
Send-Rule
# Rule 17
$RuleDesc = "Cpod vRO to ESXi hosts Resource Pod"
$RuleSrc = @( $Config.vroMg0101Ip)
$RuleDst = $ResourceEsxiHosts
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "ssh", "https" ) }
Send-Rule
# Rule 18
$RuleDesc = "CPOD install server to linux VMs mgmtVcdNetwork and new CPOD install server"
$RuleSrc = @( $Config.vcppInstallIp)
$RuleDst = @( ($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip),
($Config.vcdPfdbRp0001Ip + "-" + $Config.vcdPfdbRp0004Ip),
$Config.vcppInstallRp00Rc00Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "ssh" ) }
Send-Rule
# Rule 19
$RuleDesc = "CPOD vRO to virtual machines and appliances and new CPOD install server"
$RuleSrc = @( $Config.vroMg0101Ip)
$RuleDst = @( ($Config.vcdRabbRp0001Ip + "-" + $Config.vcdRabbRp0002Ip),
($Config.vcdPfdbRp0001Ip + "-" + $Config.vcdPfdbRp0004Ip),
$Config.vcppInstallRp00Rc00Ip,
$Config.vcdDbRp0001Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# Rule 20
$RuleDesc = "NSX controller cluster rp00 to NSX manager rp00"
$RuleSrc = @( ($Config.nsxCtrlRp0001Ip + "-" + $Config.nsxCtrlRp0003Ip) )
$RuleDst = @( $Config.nsxMgrRp0001Ip)
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# Rule 21
$RuleDesc = "ESXi hosts resource pod to vRNI proxy"
$RuleSrc = $ResourceEsxiHosts
$RuleDst = @( $Config.vrniMg0101ProxyIp)
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# Rule 22
$RuleDesc = "RP00 Hosts to cpod-install for TFTP"
$RuleSrc = $ResourceEsxiHosts
$RuleDst = @( $Config.vcppInstallIp )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "tftp" ) }
Send-Rule
# Rule 23
$RuleDesc = "RP00 ip range to cpod-install for TFTP"
$RuleSrc = $DhcpRangeRp00 # dhcp range used for TFTP/PXE boot
$RuleDst = @( $Config.vcppInstallIp )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "tftp" ) }
Send-Rule
# Rule 24
$RuleDesc = "vCD cell server to cpod install"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.vcppInstallIp )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# Rule 25
$RuleDesc = "RP00 Hosts to RP00 NSX Manager"
$RuleSrc = $ResourceEsxiHosts
$RuleDst = @( $Config.nsxMgrRp0001Ip)
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "rmq1" ) }
Send-Rule
# Rule 26
$RuleDesc = "RP00 Hosts to rp00 VCSA"
$RuleSrc = $ResourceEsxiHosts
$RuleDst = @( $Config.vcsaRp0001Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "http", "https", "902", "esx" ) }
Send-Rule
# Rule 27
$RuleDesc = "RP00 Hosts to vRealize Log Insight"
$RuleSrc = $ResourceEsxiHosts
$RuleDst = @( $Config.vrliMg0101Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "syslog" ) }
Send-Rule
# Rule 28
$RuleDesc = "vRNI Proxy to RP00 NSX Controller"
$RuleSrc = @( $Config.vrniMg0101ProxyIp )
$RuleDst = @( ($Config.nsxCtrlRp0001Ip + "-" + $Config.nsxCtrlRp0003Ip) )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "https" ) }
Send-Rule
# Rule 29
$RuleDesc = "vCD cell server to vRealize Log Insight"
$RuleSrc = $VcdCellsIp
$RuleDst = @( $Config.vrliMg0101Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "syslog" ) }
Send-Rule
# Rule 30
if ($Config.vropsMg0101Deploy -eq "true") {
$RuleDesc = "vROPS tenant app to RabbitMQ"
$RuleSrc = @( $Config.vropsMg0101TenantIp )
$RuleDst = @( $Config.vcdRabbLbsRp00Ip )
$RulePorts = @( "any" )
if ($Strict) { $RulePorts = @( "rmq2" ) }
Send-Rule
}
}
# Switch Logic
# When N/S both still false (no switch) print both.
# If N -xor S print the true one
# If both are true print both.
# If xor returns false print both (-xor has precedence over -not)
if ( -not $North -xor $South ) {
$North = $true
$South = $true
}
if ($North) {
$RuleCount = 1
$Firewall = "North"
if (-not $PSObject) { Write-Host -Object ("`nNorth Firewall Rulebase`n") }
Get-NorthFirewall
}
if ($South) {
$RuleCount = 1
$Firewall = "South"
if (-not $PSObject) { Write-Host -Object ("`nSouth Firewall Rulebase`n") }
Get-SouthFirewall
}
The cmdlet holds a sanitized version of the production code which configures the NSX environment, in particular the two Edge firewall policies. I converted the original into a more readable format and hacked together some code to extract the variables from the configData file and output it either to screen, or as a PowerShell object. That latter is quite handy if you want to pipe the result into another cmdlet to do something even more useful with the data.
There are two firewalls in the ProviderPod topology, and we have cmdlet switches (and some embedded logic) to decide which of them you want to output. There’s also an option to swap the terms used in the descriptions of the flows. You can copy the example out of the code, save and edit it, and then have the cmdlet read it in and replace the descriptions with your own.
Caveat Emptor
This is in no way a PowerShell tutorial. There may be better, more PowerShelly was of doing things, and even I could have made the code more compact and less verbose. But, I thought I might have to come and revisit it every time we changed the policy in ProviderPod. So, following PEP20 I went with the ‘readability counts’ philosophy otherwise I’d have no chance of remembering how it all worked!