VMware Cloud Community
MC1903
Enthusiast
Enthusiast
Jump to solution

Replacing the ESXi Host Certificate/Private Key using HTTPS PUT no longer works with ESXi 8.x

For years I have been using a simple PowerShell script to change standalone / non-vCenter Server connected ESXi host certificates/keys using HTTPS PUT.

Another script, using OpenSSL, generates a CSR & new private key, the CSR is signed by my Enterprise CA and the signed cert is dumped out as a Base64 .cer file.

For the first time I have tried to do this with a ESXi 8.x host and it fails with (401) Unauthorized.

It's NOT a username/password issue, the same credentials work perfectly in the UI and with Connect-VIServer.

 

Example script:

$username = "root"
$password = "Pa55word5!"
$esxiHostMgmtIP = "10.40.1.101"

$certFile = "P:\VMware\VCF_Lab\Certificates\vcf-m02-esxi-301.vcf.momusconsulting.com.cer"
$keyFile = "P:\VMware\VCF_Lab\Certificates\vcf-m02-esxi-301.vcf.momusconsulting.com-private.key"

Clear

#Set required TLS version and ignore self-signed/invalid certificates
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }

#Create the Base64 Auth String
$authInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("$($username):$($password)")))

#Create Header for Basic Auth 
$headers = @{
    Authorization="Basic $($authInfo)"
}

#Create http PUT request to upload new certificate
$certContent = Get-Content -Path $certFile -Raw
$certRequest = Invoke-WebRequest -Uri "https://$esxiHostMgmtIP/host/ssl_cert" -Headers $headers -Method PUT -Body $certContent -ContentType "application/x-x509-ca-cert" -Verbose

#Create http PUT request to upload new key
$keyContent = Get-Content -Path $keyFile -Raw
$keyRequest = Invoke-WebRequest -Uri "https://$esxiHostMgmtIP/host/ssl_key" -Headers $headers -Method PUT -Body $keyContent -ContentType "application/x-pem-file" -Verbose

#Reboot Host here.

 

ESXi 7.0x Host Response:

VERBOSE: PUT https://10.30.1.101/host/ssl_cert with -1-byte payload
VERBOSE: received 0-byte response of content type text/plain; charset=utf-8
VERBOSE: PUT https://10.30.1.101/host/ssl_key with -1-byte payload
VERBOSE: received 0-byte response of content type text/plain; charset=utf-8

PS C:\Users\Administrator> 

 

ESXi 8.0x Host Response:

VERBOSE: PUT https://10.40.1.101/host/ssl_cert with -1-byte payload
Invoke-WebRequest : The remote server returned an error: (401) Unauthorized.
At line:24 char:16
+ ... rtRequest = Invoke-WebRequest -Uri "https://$esxiHostMgmtIP/host/ssl_ ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
 
VERBOSE: PUT https://10.40.1.101/host/ssl_key with -1-byte payload
Invoke-WebRequest : The remote server returned an error: (401) Unauthorized.
At line:28 char:15
+ ... eyRequest = Invoke-WebRequest -Uri "https://$esxiHostMgmtIP/host/ssl_ ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
 

PS C:\Users\Administrator> 

 

Any thoughts?

Is there another way to do this with PowerShell / PowerCLI?

I do not need a method that requires vCenter Server to manage the certificate replacement process.

Cheers

M

0 Kudos
1 Solution

Accepted Solutions
MC1903
Enthusiast
Enthusiast
Jump to solution

Thanks again Luc.

Yeah, those *-VITrustedCertificate cmdlets look to connect to a vCenter Server only.

I have re-written my script to use SSH & SCP via the Posh-SSH module.

I appreciate your help.

Take care,

M

View solution in original post

0 Kudos
5 Replies
MC1903
Enthusiast
Enthusiast
Jump to solution

Some progress. It seems ESXi 8.0x implements an undocumented Cross-Site Request Forgery (CSRF) Token on the /host/ssl_cert uri. 

MC1903_0-1702036257919.png

Any one know how to deal with this in PowerShell?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did you try the workaround from KB78315


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
MC1903
Enthusiast
Enthusiast
Jump to solution

Hello Luc.

Thank you. I hadn't seen that KB, but looking at it; I am not sure it applies to this situation.

As far as understand  https://{esxi_host}/host/ssl_cert isn't a vSphere REST API endpoint.

Are you aware of any PowerCLI options for managing certificates directly on a ESXi host?

Cheers,

M

 

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The only thing I know of is this blog article, named Managing vSphere Certificates with PowerCLI.
Which contains a section on ESXi certificates, but I'm not sure it applies to the issue you are seeing.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

MC1903
Enthusiast
Enthusiast
Jump to solution

Thanks again Luc.

Yeah, those *-VITrustedCertificate cmdlets look to connect to a vCenter Server only.

I have re-written my script to use SSH & SCP via the Posh-SSH module.

I appreciate your help.

Take care,

M

0 Kudos