Enforce IP filtering on ESXi

       475 words, 3 minutes

My ESXi is provided by Online.net and accessible from Internet. Reading the VMware documentation, one can see:

ESXi includes a firewall that is enabled by default.

At installation time, the ESXi firewall is configured to block incoming and outgoing traffic, except traffic for services that are enabled in the host’s security profile.

But the default security profile is way too loose! So here’s how to harden it a bit.

The default firewall configuration

The default online.net host’s security profile allows:

# nmap my_esxi
Not shown: 990 filtered ports
PORT     STATE  SERVICE
22/tcp   open   ssh
80/tcp   open   http
427/tcp  open   svrloc
443/tcp  open   https
902/tcp  open   iss-realsecure
5988/tcp closed wbem-http
5989/tcp closed wbem-https
8000/tcp open   http-alt
8300/tcp open   tmi
9080/tcp open   glrpc
Nmap done: 1 IP address (1 host up) scanned in 4.37 seconds

Isn’t this nice !?

Configure the firewall using esxcli

With SSH enabled on the host, the firewall can be configured using esxcli. This will allow easy mass modification. I will simply copy esxcli commands in a shell script and run it from the SSH session.

# cat > firewall.sh
_lan="192.168.0.0/24 10.0.0.0/8"
_whitelist="a.a.a.a/32 b.b.b.b/32 c.c.c.c/32"

# Default block
esxcli network firewall set -d false
for _service in $(esxcli network firewall ruleset allowedip list | awk 'NR>=3 { print $1 }'); do
  esxcli network firewall ruleset set --allowed-all false --ruleset-id=$_service
done

# Allow outgoing to ANY
esxcli network firewall ruleset set --allowed-all true --ruleset-id=dns
esxcli network firewall ruleset set --allowed-all true --ruleset-id=esxupdate
esxcli network firewall ruleset set --allowed-all true --ruleset-id=httpClient
esxcli network firewall ruleset set --allowed-all true --ruleset-id=ntpClient


# Allow outgoing to LAN
for _ip in $lan; do
  esxcli network firewall ruleset allowedip add -i=$_ip -r=syslog
done

# Allow incoming from LAN
for _ip in $_lan; do
  esxcli network firewall ruleset allowedip add -i=$_ip -r=snmp
  esxcli network firewall ruleset allowedip add -i=$_ip -r=sshServer
  esxcli network firewall ruleset allowedip add -i=$_ip -r=webAccess
  esxcli network firewall ruleset allowedip add -i=$_ip -r=vSphereClient
done

# Allow incoming from WHITELIST
for _ip in $_whitelist; do
  esxcli network firewall ruleset allowedip add -i=$_ip -r=sshServer
  esxcli network firewall ruleset allowedip add -i=$_ip -r=webAccess
  esxcli network firewall ruleset allowedip add -i=$_ip -r=vSphereClient
done
^D

# nohup ash firewall.sh

When applied, check the rules set:

# esxcli network firewall ruleset allowedip list
Ruleset                 Allowed IP Addresses
----------------------  -------------------------------------------------------------------------
sshServer               a.a.a.a, b.b.b.b, c.c.c.c, 192.168.0.0/24, 10.0.0.0/8
sshClient
nfsClient
nfs41Client
dhcp
dns                     All
snmp                    192.168.0.0/24, 10.0.0.0/8
ntpClient               All
(...)

From an authorized machine, I now get:

# nmap my_esxi
Not shown: 997 filtered ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp open https

Nmap done: 1 IP address (1 host up) scanned in 4.76 seconds

From an unauthorized machine, I get:

# nmap my_esxi
All 1000 scanned ports on my_esxi (x.x.x.x) are filtered

Nmap done: 1 IP address (1 host up) scanned in 21.63 seconds

The ESXi Firewall Command Reference are available online.