diff --git a/inc/vCenter-SSL.ps1 b/inc/vCenter-SSL.ps1 new file mode 100644 index 00000000..1bbf665f --- /dev/null +++ b/inc/vCenter-SSL.ps1 @@ -0,0 +1,250 @@ +#!/usr/bin/env pwsh +. /opt/idssys/powerwall/settings.ps1 + +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force -Confirm:$false + +function Show-Failure { + $global:helpme = $body + $global:helpmoref = $moref + $global:result = $_.Exception.Response.GetResponseStream() + $global:reader = New-Object System.IO.StreamReader($global:result) + $global:responseBody = $global:reader.ReadToEnd(); + Write-Host -BackgroundColor:Black -ForegroundColor:Red "Status: A system exception was caught." + Write-Host -BackgroundColor:Black -ForegroundColor:Red $global:responsebody + Write-Host -BackgroundColor:Black -ForegroundColor:Red "The request body has been saved to `$global:helpme" + break +} + +$vCenterURL = $VCENTERHOST +$CommonName = $VCENTERHOST +$EmailContact = $ACMEEMAIL + +#[string]$userName = $VCENTERUSER +#[string]$userPassword = $VCENTERPASS +#[SecureString]$secureString = ConvertTo-SecureString $VCENTERPASS -AsPlainText -Force +[PSCredential]$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $VCENTERUSER, (ConvertTo-SecureString $VCENTERPASS -AsPlainText -Force) + +$pArgs = @{ + PowerDNSApiHost = $WDNSHOST + PowerDNSApiKey = $PDNSAPI | ConvertTo-SecureString -AsPlainText -Force + #PowerDNSApiKey = (Read-Host "API Key" -AsSecureString) + PowerDNSUseTLS = $true + PowerDNSPort = 443 + PowerDNSServerName = 'localhost' +} + + +Write-Host "Checking for Required Module Posh-ACME" -ForegroundColor Green + +if (Get-Module -ListAvailable -Name Posh-ACME) { + Write-Host "Posh-ACME Module Already Installed" -ForegroundColor Green +} +else { + Write-Host "Posh-ACME Module Not Found, Attempting to Install" -ForegroundColor Yellow + Write-Host "Restart of this Script is Required!" -ForegroundColor Yellow + Install-Module -Name Posh-ACME -Scope CurrentUser -Force -Confirm:$false + Return +} + +Do { + Write-host "Waiting to for Posh-ACME Module to be Loaded" -ForegroundColor Cyan + $PoshACME = Get-Module -ListAvailable -Name Posh-ACME + Start-Sleep -Seconds 5 +} +While ( $PoshACME -eq $null ) + +# --- Importing the Posh-ACME Module. +if (Get-Module -ListAvailable -Name Posh-ACME) { + Write-Host "Importing Posh-ACME Module" -ForegroundColor Green + Import-Module -Name Posh-ACME -Force +} +Else { + Write-host "Something Went Wrong, Stopping Script" -ForegroundColor Red + Break +} + +if ((Get-PAServer).name -eq "LE_PROD") { + Write-Host "ACME Server Already Set to $((Get-PAServer).Name)" -ForegroundColor Green +} +else { + Write-Host "Setting ACME Server to LE_PROD" -ForegroundColor Yellow + Set-PAServer -DirectoryUrl LE_PROD +} + +#Set-PAServer LE_STAGE + +$PAAccount = Get-PAAccount +If ($PAAccount) { + Write-host "ACME Account Found with Contact: "$($PAAccount).Contact.split(":")[1]"" +} +Else { + Write-Host "ACME Account Not Found, Setting ACME Account with Contact $($EmailContact)" + New-PAAccount -Contact $EmailContact -AcceptTOS -Force -Confirm:$false +} + +if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type) { + $certCallback = @" + using System; + using System.Net; + using System.Net.Security; + using System.Security.Cryptography.X509Certificates; + public class ServerCertificateValidationCallback + { + public static void Ignore() + { + if(ServicePointManager.ServerCertificateValidationCallback ==null) + { + ServicePointManager.ServerCertificateValidationCallback += + delegate + ( + Object obj, + X509Certificate certificate, + X509Chain chain, + SslPolicyErrors errors + ) + { + return true; + }; + } + } + } +"@ + Add-Type $certCallback +} +[ServerCertificateValidationCallback]::Ignore() + +$auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Credential.UserName + ':' + $Credential.GetNetworkCredential().Password)) +$head = @{ + 'Authorization' = "Basic $auth" +} + +$Params = @{ + + Method = "POST" + Headers = $head + Uri = "https://$vCenterURL/rest/com/vmware/cis/session" +} + +if ($IsCoreCLR) { + $Params.Add("SkipCertificateCheck", $true) +} + +try { + $RestApi = Invoke-WebRequest @Params + $token = (ConvertFrom-Json $RestApi.Content).value + $session = @{'vmware-api-session-id' = $token } + Write-Host "Session Token Created Successfully" -ForegroundColor Green +} +catch { + Write-Error "Unable to get Session Token, Terminating Script" + Show-Failure +} + +$Question = "No" +$CheckSLL = Get-PACertificate -MainDomain $CommonName +$RUN=$true +If ((($CheckSLL).AllSANs) -eq $CommonName) { + $daysUntilExpiration = (New-TimeSpan -Start (Get-Date) -End $CheckSLL.NotAfter).Days + If ($daysUntilExpiration -lt 30) { + Write-Host "Renewing cert for '$("$CommonName")' " -ForegroundColor Yellow + Submit-Renewal $CommonName + } + else { + Write-Host "Cert '$("$CommonName")' not ready for renewal" -ForegroundColor Yellow + $RUN=$false + } +} +else { + # --- Generate Free Let's Encrypt 90 Day SSL - Requires you to Validatr Domain Ownership. + If ($Question -match '^(No|N)$') { + If ($EmailContact) { + New-PACertificate $CommonName -AcceptTOS -Contact $EmailContact -PreferredChain "ISRG Root X1" -Plugin PowerDNS -PluginArgs $pArgs -Force + Write-Host "Requesting SSL for '$($CommonName)'" -ForegroundColor Green + } + else { + New-PACertificate $CommonName -AcceptTOS -PreferredChain "ISRG Root X1" -Plugin PowerDNS -PluginArgs $pArgs -Force + Write-Host "Requesting SSL for '$($CommonName)' Without Contact Email" -ForegroundColor Green + } + } +} + + +If ($RUN -eq $true) { + +Write-Host "Downloading ROOT CA" -ForegroundColor Green +$wc = [System.Net.WebClient]::new() +$rootCaPath = 'https://letsencrypt.org/certs/isrgrootx1.pem.txt' +$publishedHash = '22B557A27055B33606B6559F37703928D3E4AD79F110B407D04986E1843543D1' +$FileHash = Get-FileHash -InputStream ($wc.OpenRead($rootCaPath)) + +If ($FileHash.Hash -eq $publishedHash) { + $root_CA = (New-Object System.Net.WebClient).DownloadString($rootCaPath) + Write-Host "Successfully Validated ROOT CA" -ForegroundColor Green +} +else { + Throw "Could not validate ROOT CA - Please Raise an Issue at https://github.com/virtuallywired/Install-vCenterSSL" +} +Write-Host "Loading Certificate Files" -ForegroundColor Green +$sslcert = ((Get-Content ((Get-PACertificate).FullChainFile)) + $root_CA) -replace "`t|`n|`r", "" +$privatekey = Get-Content ((Get-PACertificate).KeyFile) +$fullchain = ((Get-Content ((Get-PACertificate).ChainFile)) + $root_CA) -replace "`t|`n|`r", "" + +Write-Host "Reformating Certificates to String" -ForegroundColor Green + +$cert = ((([string]$sslcert).Replace(" ", "")` + ).Replace("-----BEGINCERTIFICATE-----", "-----BEGIN CERTIFICATE-----\n")` +).Replace("-----ENDCERTIFICATE-----", "\n-----END CERTIFICATE-----") + +$key = ((([string]$privatekey).Replace(" ", "")` + ).Replace("-----BEGINPRIVATEKEY-----", "-----BEGIN PRIVATE KEY-----\n")` +).Replace("-----ENDPRIVATEKEY-----", "\n-----END PRIVATE KEY-----") + +$chain = ((([string]$fullchain).Replace(" ", "")` + ).Replace("-----BEGINCERTIFICATE-----", "-----BEGIN CERTIFICATE-----\n")` +).Replace("-----ENDCERTIFICATE-----", "\n-----END CERTIFICATE-----"` +).Replace("----------", "-----\n-----") + +Write-Host "Creating Payload" -ForegroundColor Green + +$json = @" +{ + "cert": "$cert", + "key": "$key", + "root_cert": "$chain" + } +"@ +$Params = @{ + Method = "PUT" + Headers = $session + Uri = "https://$vCenterURL/api/vcenter/certificate-management/vcenter/tls" + ContentType = "application/json" + Body = $json +} + +if ($IsCoreCLR) { + $Params.Add("SkipCertificateCheck", $true) +} +Write-Host "Preparing to Replace Certificate." -ForegroundColor Green + +try { + $Response = Invoke-WebRequest @Params + Write-Host "Response Code: $($Response.StatusCode)" -ForegroundColor Blue +} +catch { + Write-Error "Failed to Replace Certificate, Terminating Script" + Show-Failure +} + +If ($Response.StatusCode -eq "204") { + Write-Host "Successfully Replaced Certificate" -ForegroundColor Green + Write-Host "After this operation completes, the services using the certificate will be restarted for the new certificate to take effect." -ForegroundColor Green +} +else { + + Write-Error "Failed to Replace Certificate, Please verify Correct Configuration and Retry" +} + +Import-Module VMware.VimAutomation.Core +Rescan-VBREntity -AllHosts + +}