acme.sh icon indicating copy to clipboard operation
acme.sh copied to clipboard

feat: Add deploy script for HP iLO (using Redfish REST API)

Open imgrant opened this issue 3 years ago • 4 comments

HP iLO deploy script

Deploy hook shell script to install a certificate in an HP iLO (via Redfish REST API).

⚡ Quick start

$ export HPILO_USERNAME=admin
$ export HPILO_PASSWORD=secret
$ export HPILO_HOST=ilo.example.com
$ acme.sh --deploy -d ilo.example.com --deploy-hook hpilo

🚚 Usage

📋 Generate a CSR

The process for installing a certificate into the iLO involves first generating a CSR on the iLO — the private key is generated on the device, there is no capability to import or install a private key, therefore the usual acme.sh workflow (of allowing acme.sh to generate a key, CSR, and then install the key and certificate) is not possible.

The CSR can be generated from the iLO web interface, via the SSH interface, using HPE iLO PowerShell cmdlets, or using the Redfish REST API — an example script that automates the latter is:

#!/usr/bin/env bash

# CSR generation script for HPE iLO4
#
# The following environment variables are
# needed for the deploy script to work:
#
# ```sh
# export HPILO_USERNAME=admin
# export HPILO_PASSWORD=secret
# export HPILO_HOST=ilo.example.com
#
# acme.sh --signcsr --csr <(/path/to/hpilo-generatecsr.sh ilo.example.com)
# ```

# Pass the domain name (common name) as an argument to the script
FQDN=$1

if [ -z "$HPILO_HOST" ]; then
  HPILO_HOST="$FQDN"
fi

if [ -z "$HPILO_USERNAME" ]; then
  echo >&2 "Need to set the env variable HPILO_USERNAME"
  exit 1
fi

if [ -z "$HPILO_PASSWORD" ]; then
  echo >&2 "Need to set the env variable HPILO_PASSWORD"
  exit 1
fi

if [ -z "$CSR_COUNTRY" ]; then
  CSR_COUNTRY="GB"
fi

if [ -z "$CSR_STATE" ]; then
  CSR_STATE="Greater London"
fi

if [ -z "$CSR_CITY" ]; then
  CSR_CITY="London"
fi

if [ -z "$CSR_ORG" ]; then
  CSR_ORG="HPE"
fi

if [ -z "$CSR_OU" ]; then
  CSR_OU="iLO"
fi

if [ -z "$CSR_CN" ]; then
  CSR_CN="$FQDN"
fi

echo >&2 "Asking '$HPILO_HOST' to generate a new CSR with CN '$CSR_CN'"

curl -sS -k -X POST -H "Content-Type: application/json" -d '{ "Action": "GenerateCSR", "Country": "'$CSR_COUNTRY'", "State": "'"$CSR_STATE"'", "City": "'"$CSR_CITY"'", "OrgName": "'"$CSR_ORG"'", "OrgUnit": "'"$CSR_OU"'", "CommonName": "'$CSR_CN'" }' -u $HPILO_USERNAME:$HPILO_PASSWORD https://$HPILO_HOST/redfish/v1/Managers/1/SecurityService/HttpsCert/

fetch_csr_cmd='curl -sS -k -u '$HPILO_USERNAME':'$HPILO_PASSWORD' https://'$HPILO_HOST'/redfish/v1/Managers/1/SecurityService/HttpsCert/ | grep -o \"CertificateSigningRequest\":\"[^\"]*\" | cut -d : -f 2 | tr -d \"'

echo >&2 "Checking to see if the CSR is ready yet ..."

resp=$(eval "$fetch_csr_cmd")
while [ "$resp" == "0" -o "$resp" == "" ]; do
    # The CSR is not ready yet, wait and try again
    sleep 10
    resp=$(eval "$fetch_csr_cmd")
done

# Print out the CSR
echo $resp | awk  '{gsub("\\\\n","\n")};1'

Also available at this GitHub gist: https://gist.github.com/imgrant/ea576d21c7e849a8d39378bcfec99307.

🖊️ Sign the CSR via acme.sh

E.g. to generate a certificate using DNS-01 challenge via Cloudflare (previously configured in acme.sh):

acme.sh --signcsr --csr path/to/csr.pem --dns dns_cf

📦 Install the certificate using the deploy hook

$ export HPILO_USERNAME=admin
$ export HPILO_PASSWORD=secret
$ export HPILO_HOST=ilo.example.com
$ acme.sh --deploy -d ilo.example.com --deploy-hook hpilo
[Sat 19 Mar 2022 15:29:28 GMT] Attempting to deploy certificate '/root/acme.sh/ilo.example.com/ilo.example.com.cer' to 'ilo.example.com'
{"Messages":[{"MessageID":"iLO.0.10.ImportCertSuccessfuliLOResetinProgress"}],"Type":"ExtendedError.1.0.0","error":{"@Message.ExtendedInfo":[{"MessageID":"iLO.0.10.ImportCertSuccessfuliLOResetinProgress"}],"code":"iLO.0.10.ExtendedInfo","message":"See @Message.ExtendedInfo for more information."}}
[Sat 19 Mar 2022 15:29:29 GMT] Success

The iLO will reboot, the web interface should be accessible with the generated certificate when it comes back up.

🔒 Profit! 🥳

For subsequent renewals, the existing CSR will be re-used.

Notes

Tested with iLO v4 (in a Proliant Microserver Gen8), I believe iLO v5 uses the same Redfish API. I couldn't see a way to specify SANs in the iLO CSR, so only a single Common Name is possible.

imgrant avatar Mar 19 '22 16:03 imgrant

see this guide for some of our common rules: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide

Neilpang avatar Mar 20 '22 04:03 Neilpang

see this guide for some of our common rules: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide

Thanks, I missed that (since it's about DNS API hooks, whereas this is a deploy hook). I have updated the script to use sh (instead of bash) and _post() (instead of curl) — is there anything else you were referring to?

imgrant avatar Mar 20 '22 16:03 imgrant

@imgrant @Neilpang It looks like HPE iLO 5 v2.78 added the ability to upload a certificate and private key via the Redfish API (using a P12 certificate?).

See link 1 and link 2

tjmullicani avatar Apr 17 '23 18:04 tjmullicani

Oh that would simplify things a little. However, people still using iLO v4 might not get that update so this would still be needed?

I've lost track of what updates were needed for this PR amongst acme.sh updates since I originally submitted it, but regardless, I've personally got rid of my HPE (iLO v4) kit now, so don't have a means of testing this (or indeed a need for it!)

imgrant avatar Apr 17 '23 20:04 imgrant