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. [Update] Check out this official KB article that has since been brought to my attention – KB 2008226. 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:
You 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.
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.
Cormac,
You used a double negative: “Please note that this method of changing the services.xml IS NOT unsupported”
So it’s supported, right? 🙂
You got me! I’ll change it now – thanks Gavin. But I think you know the answer already – right? 😉
Sure I’ll just tell GSS that ‘Cormac said it was grand’ and we’re all good 😉