Adding bespoke firewall rules to ESXi

In my new role, I get to work with a lot of new products and features that are not yet in a state to be used for beta, never mind being close to GA. This means, from time to time, that we needs to work around a few specific problems to get the product/feature to work. On this particular occasion, we were trying to add a custom firewall rule to an ESXi host. The rule took fine, but did not persist through reboots of the ESXi host, which is what was required. This is the solution we came up with.

Please note that this method of changing the services.xml IS NOT supported (Jeez, I feel a bit like William Lam now :-). However, I didn’t figure out any other way of doing this during my research. If someone knows of a supported way, I’d love to hear.Anyways, let’s get on with adding the role.

The first step is to change the /etc/vmware/firewall/service.xml so that it could be edited.

chmod 644 /etc/vmware/firewall/service.xml
chmod +t /etc/vmware/firewall/service.xml

The next step is to add your bespoke firewall rule to the service.xml file. Make sure that the rule does not conflict with the existing rules. We picked rule id 50 which did not clash with the existing rules:

<service id="0050">
 <id>VNASTCPIn</id>
 <rule id='0000'>
  <direction>inbound</direction>
  <protocol>tcp</protocol>
  <porttype>dst</porttype>
  <port>12345</port>
 </rule>
 <enabled>true</enabled>
 <required>false</required>
</service>

Set the permissions back the way they were before the changes.

chmod 444 /etc/vmware/firewall/service.xml
chmod -t /etc/vmware/firewall/service.xml

Make sure that the rule appears before the last </ConfigRoot> entry in the service.xml file. To check that the rule is working, simply refresh the firewall using the following command. The new service should be visible in the vSphere web client after the refresh:

esxcli network firewall refresh

However if you now reboot the ESXi host, the changes will be overwritten once again with the default service.xml file which is stored in the bootbank of the ESXi host. So once the modified/customized service.xml file has been changed, you will need to get it saved in the bootbank so that it is used on subsequent reboots. There are two steps involved here. The first is to save the service.xml file in a zipped tar ball, and then add that zipped tar ball to the bootbank. These are the necessary commands:

~ # tar -cvzf vnasfw.tgz /etc/vmware/firewall/service.xml
tar: removing leading '/' from member names
etc/vmware/firewall/service.xml
~ # BootModuleConfig.sh --add=vnasfw.tgz

Now that the service.xml file has been saved to the bootbank, check the bootbank:

~ # ls -la /bootbank/vnasfw.tgz
-rwx------   1 root    root    1887 Mar 28 08:54 /bootbank/vnasfw.tgz

The bootbank configuration can also be checked to make sure the tar/zip is included:

~ # ls -l /bootbank/boot.cfg
-rwx------   1 root    root   1409 Mar 28 08:54 /bootbank/boot.cfg
~ # more /bootbank/boot.cfg
bootstate=0
kernel=tboot.b00
title=Loading VMware ESXi
kernelopt=no-auto-partition
modules=b.b00 --- jumpstrt.gz --- useropts.gz --- k.b00 --- chardevs.b00 
--- a.b00 --- user.b00 --- sb.v00 --- s.v00 --- ata_pata.v00 --- 
ata_pata.v01 --- ata_pata.v02 --- ata_pata.v03 --- ata_pata.v04 --- 
ata_pata.v05 --- ata_pata.v06 --- ata_pata.v07 --- block_cc.v00 --- 
ehci_ehc.v00 --- elxnet.v00 --- weaselin.t00 --- esx_dvfi.v00 --- 
xlibs.v00 --- ima_qla4.v00 --- ipmi_ipm.v00 --- ipmi_ipm.v01 --- 
ipmi_ipm.v02 --- lpfc.v00 --- lsi_mr3.v00 --- lsi_msgp.v00 --- 
misc_cni.v00 --- misc_dri.v00 --- mtip32xx.v00 --- net_be2n.v00 --- 
net_bnx2.v00 --- net_bnx2.v01 --- net_cnic.v00 --- net_e100.v00 --- 
net_e100.v01 --- net_enic.v00 --- net_forc.v00 --- net_igb.v00 --- 
net_ixgb.v00 --- net_mlx4.v00 --- net_mlx4.v01 --- net_nx_n.v00 --- 
net_tg3.v00 --- net_vmxn.v00 --- ohci_usb.v00 --- qlnative.v00 --- 
rste.v00 --- sata_ahc.v00 --- sata_ata.v00 --- sata_sat.v00 --- 
sata_sat.v01 --- sata_sat.v02 --- sata_sat.v03 --- sata_sat.v04 --- 
scsi_aac.v00 --- scsi_adp.v00 --- scsi_aic.v00 --- scsi_bnx.v00 --- 
scsi_bnx.v01 --- scsi_fni.v00 --- scsi_hps.v00 --- scsi_ips.v00 --- 
scsi_lpf.v00 --- scsi_meg.v00 --- scsi_meg.v01 --- scsi_meg.v02 --- 
scsi_mpt.v00 --- scsi_mpt.v01 --- scsi_mpt.v02 --- scsi_qla.v00 --- 
scsi_qla.v01 --- uhci_usb.v00 --- xorg.v00 --- imgdb.tgz --- state.tgz 
--- vnasfw.tgz
build=5.5.0-1623387
updated=1

Now on subsequent reboots of the ESXi host, this tar/zip will be extracted, the service.xml contained inside will be put in place, and the rules in the service.xml (including any additional bespoke firewall rules) will be implemented:

Security ProfileYou can also check if the module was loaded after a reboot by using the command bootOption -m.

If you wish to remove the module that you added to the bootbank, use:

~ # BootModuleConfig.sh --remove=vnasfw.tg

Kudos once again to Paudie for his help with this.

5 comments
  1. Hi Cormac,

    great post – I have not yet known the BootModuleConfig.sh script!

    However, if you add the file this way then it will probably get lost once you patch the ESXi host, because it is not part of the installed image profile.

    A safer way to permanently add a firewall rule is to create a VIB package of it and install that package. I have explained that process in this post: http://www.v-front.de/2012/01/howto-use-esxi-5-as-ntp-server-or-howto.html.

    Andreas

    • Thanks Andreas – agree completely, and also the reason I called this out as “unsupported”. But it was a quick way to get me going at the time.

Comments are closed.