ESXi-Arm on Raspi – Pull CPU Temperature using Curl

Yesterday, I posted a screenshot on Twitter where I pulled the CPU temperature from a Raspberry Pi running ESXi-Arm using curl. If that is possible, it would be a great option to pull the data for monitoring or graphing purposes:
I got a few messages on whether this really works, or is a fake. So, here is how I did it…

Disclaimer: This is not supported by VMware, use at your own risk.

We all know the webserver running on the ESXi hosts that serves the Web Client. The root directory from that webserver is located in /usr/lib/vmware/hostd/docroot/ and it is quite easy to add custom files. But this webserver can only serve static content like images or HTML pages.

A second webserver has the ability to run python-based CGI scripts to allow administrators the download of esxcfg-info output and vm-support bundles:

  • https://[esx]/cgi-bin/esxcfg-info.cgi
  • https://[esx]/cgi-bin/vm-support.cgi

The scripts that are delivered by the hostdCgiServer are located in /usr/lib/vmware/hostd/cgi-bin/ and my idea was to add custom scripts here. Unfortunately, there are two problems:

First Problem: You can’t just add custom scripts. You can place whatever you want in the cgi-bin directory, but the hostdCgiServer just ignores it. I’ve added my script to the cgi-bin directory and tried to open the site using a browser, which resulted in HTTP ERROR 404 – Page not found. The log file (/var/log/hostdCgiServer.log) did not give a hint on what’s happening. Apparently, the hostdCgiServer only accepts a hardcoded list of files.

2020-11-13T15:57:16.387Z info hostdCgiServer[137140] [Originator@6876 sub=CgiHandler] Received HTTP GET request for URI /cgi-bin/temp.cgi
2020-11-13T15:57:16.387Z info hostdCgiServer[137140] [Originator@6876 sub=CgiHandler] Authorizing SOAP cookie ...
2020-11-13T15:57:16.388Z verbose hostdCgiServer[137140] [Originator@6876 sub=vmomi.soapStub[7]] Connected to host <cs p:000000878adfbf00, TCP:localhost:80> using vim25/6.0 (vim.version.version10)
2020-11-13T15:57:16.395Z verbose hostdCgiServer[137140] [Originator@6876 sub=HttpConnectionPool-000008] HttpConnectionPoolImpl created. maxPoolConnections = 1; idleTimeout = 900000000; maxOpenConnections = 1; maxConnectionAge = 0
2020-11-13T15:57:16.403Z info hostdCgiServer[137140] [Originator@6876 sub=CgiHandler] Authorizing user 'root'
2020-11-13T15:57:16.403Z verbose hostdCgiServer[137140] [Originator@6876 sub=vmomi.soapStub[8]] Connected to host <cs p:000000878adf5cb0, TCP:localhost:80> using vim25/6.0 (vim.version.version10)
2020-11-13T15:57:16.411Z verbose hostdCgiServer[137140] [Originator@6876 sub=HttpConnectionPool-000009] HttpConnectionPoolImpl created. maxPoolConnections = 1; idleTimeout = 900000000; maxOpenConnections = 1; maxConnectionAge = 0
2020-11-13T15:57:16.479Z verbose hostdCgiServer[137140] [Originator@6876 sub=Default] Hostd operation failed: N5Vmomi5Fault15InvalidArgument9ExceptionE(Fault cause: vmodl.fault.InvalidArgument
--> )
--> [context]zKq7AWICAgAAAEhzBAEAaG9zdGRDZ2lTZXJ2ZXIA[/context]
2020-11-13T15:57:16.479Z verbose hostdCgiServer[137140] [Originator@6876 sub=CgiHandler] Hostd error. Authorizing with PAM
2020-11-13T15:57:16.509Z verbose hostdCgiServer[137140] [Originator@6876 sub=CgiHandler] Sent Not Found response

So, why not modify the existing files?

Second Problem:

# ls -l /usr/lib/vmware/hostd/cgi-bin/esxcfg-info.cgi
-r-xr-xr-x 1 root root 5374 Oct 21 20:09 /usr/lib/vmware/hostd/cgi-bin/esxcfg-info.cgi # chmod +w esxcfg-info.cgi
chmod: esxcfg-info.cgi: Operation not permitted

According to KB78689, the root account can no longer change permissions since ESXi 7.0. So you can’t modify the files that are already there. Now what? After inspecting the hostdCgiServer I figured out that it is actually hardcoded to only listen on 3 files:

  • esxcfg-info.cgi
  • vm-support.cgi
  • hostd-operation.cgi

“hostd-operation.cgi” what? That file does not even exist! And here we go!

How to Pull CPU Temperature using Curl

  1. Install the thpimon driver by Tom Hebel
  2. Disable the ESXi Firewall
    # esxcli network firewall set --enabled false
  3. Download and unzip the fgrehl/esxi-raspi repository from GitHub to a datastore
    # cd /vmfs/volumes/[DATASTORE]/
    # wget
    # unzip
  4. Make the python script executable
    # cd esxi-raspi-main/pyUtil/
    # chmod +x hostd-operation.cgi
  5. Create a soft link to hostd-operation.cgi and the pimonLib directory in the cgi-bin directory. Make sure to use the correct path to your datastore.
    # ln -s '/vmfs/volumes/[datastore]/esxi-raspi-main/pyUtil/hostd-operation.cgi' /usr/lib/vmware/hostd/cgi-bin/hostd-operation.cgi # ln -s '/vmfs/volumes/[datastore]/esxi-raspi-main/pyUtil/pimonLib/' /usr/lib/vmware/hostd/cgi-bin/pimonLib
  6. You can now access the script using a browser or curl. Keep in mind that you have to login using the root account, like you know it from the vSphere Client:https://[ESXi-URL]/cgi-bin/hostd-operation.cgi?getTemp

If you want to use curl, use either “-u USER:PASSWORD”, or a netrc auth file.

# curl https://esx8.virten.lab/cgi-bin/hostd-operation.cgi?getTemp -u root:[PASSWORD]
43.0 # curl https://esx8.virten.lab/cgi-bin/hostd-operation.cgi?getTemp --netrc-file .authVirten
43.0 # curl https://esx8.virten.lab/cgi-bin/hostd-operation.cgi?getPiMonJson --netrc-file .authVirten | python -m json.tool
{ "BoardModel": 0, "BoardRev": "0xd03114", "FWRev": "0x5f440c10", "Temp": 42.0, "boardMACStr": "58:be:c8:32:a6:dc", "boardSerial": "0x0000008b5b8b21"
} # cat .authVirten
machine esx8.virten.lab login root password [PASSWORD]

If you do not have a valid certificate, use the –insecure option.

# curl https://esx8.virten.lab/cgi-bin/hostd-operation.cgi?getTemp -u root:[PASSWORD] --insecure

Posted by Editor