Die Firewall eines ESXi Host lässt sich über mehrere Wege setzen. Soll dies automatisiert werden, stößt man beim Setzen der Hostfirewall über die ESXCLI auf Probleme, da über diesen Weg lediglich pro Aufruf ein Netz bzw. eine IP gesetzt werden kann. In größeren Umgebungen skaliert diese Methode nur bedingt gut.
Um diesen Prozess dennoch zu automatisieren, lässt sich dies per Powershell bzw. PowerCLI umsetzen.
Dabei setzt die Funktion mehrere Netze und IPs auf einmal für einen Service eines ESXi Hosts. Dafür benötigt die Funktion folgende Parameter:
VMHost: Hier wird der ESXi Host angegeben, auf welchem die Hostfirewall gesetzt wird, dieser kann auch über eine Pipeline der Funktion übergeben werden
Service: Der Service, auf welchem die IPs und Netze gesetzt werden sollen
IPSet: Ein Array mit IPs und Netzen, welche in der Hostfirewall gesetzt werden
param (
[ValidateNotNullOrEmpty()]
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl] $VMHost,
[Parameter(Mandatory = $true, ValueFromPipeline = $false)]
[String] $Service,
[Parameter(Mandatory = $true, ValueFromPipeline = $false)]
[Array] $IPSet
)
Die Funktion besteht aus zwei Schritten.
Zuerst werden die Netze und IPs jeweils in zwei unterschiedliche Arrays aufgeteilt.
#Split $IPSet
$IPs = @()
$Networks = @()
foreach ($item in $IPSet) {
if ($item -like "*/*") {
$Networks += $item
}else {
$IPs += $item
}
}
Anschließend wird das Objekt erstellt und mit den Netzen und IPs befüllt, welche in der Firewall gesetzt werden sollen.
Dieses Objekt wird nun auf das Regelwerk der ESXI FW angewandt.
$_this = Get-View -Id $VMHost.Id
$spec = New-Object VMware.Vim.HostFirewallRulesetRulesetSpec
$spec.AllowedHosts = New-Object VMware.Vim.HostFirewallRulesetIpList
$spec.AllowedHosts.AllIp = $false
#build ips
$spec.AllowedHosts.IpAddress = New-Object string[] ($IPs.Length)
for ($i = 0; $i -lt $IPs.Length; $i++) {
$spec.AllowedHosts.IpAddress[$i] = $IPs[$i]
}
#build networks
$spec.AllowedHosts.IpNetwork = New-Object VMware.Vim.HostFirewallRulesetIpNetwork[] ($Networks.Length)
for ($i = 0; $i -lt $Networks.Length; $i++) {
$spec.AllowedHosts.IpNetwork[$i] = New-Object VMware.Vim.HostFirewallRulesetIpNetwork
$spec.AllowedHosts.IpNetwork[$i].PrefixLength = $Networks[$i].Split("/")[1]
$spec.AllowedHosts.IpNetwork[$i].Network = $Networks[$i].Split("/")[0]
}
$id = $($VMHost.Id.Split("-")[2])
$_this = Get-View -Id "HostFirewallSystem-firewallSystem-$($id)"
#Update Ruleset
$_this.UpdateRuleset($Service, $spec)
Die Powershell Funktion kann wie folgt verwendet werden. Hierbei wird der ESXi Host direkt über eine Pipeline der Funktion übergeben.
Get-VMHost -Name 192.168.1.10 | Set-VMHost-Firewall -Service "sshServer" -IPSet @("10.0.0.0/8", "192.168.0.0/16")
Um IP-Adressen und Netze für alle Services zu setzen, kann folgender Code verwendet werden. Dieser Code setzt für die unter $services angegebenen Services die ESXi Firewall Regeln bzw. Netze.
$services = @("webAccess", "vSphereClient", "sshServer", "ntpClient")
foreach ($service in $services) {
Get-VMHost -Name 192.168.1.10 | Set-VMHost-Firewall -Service $service -IPSet @("10.0.0.0/8", "192.168.0.0/16", "1.2.3.4", "1.2.3.5")
}