#!/bin/bash# Copyright (c) 2020-2021 VMware, Inc. All rights reserved.# VMware Confidential## Run this from the affected PSC/VC## NOTE: This works on external and embedded PSCs# This script will do the following# 1: Regenerate STS certificate## What is needed?# 1: Offline snapshots of VCs/PSCs# 2: SSO Admin PasswordNODETYPE=$(cat /etc/vmware/deployment.node.type)if [ "$NODETYPE" = "management" ]; then echo "Detected this node is a vCenter server with external PSC." echo "Please run this script from a vCenter with embedded PSC, or an external PSC" exit 1fiif [ "$NODETYPE" = "embedded" ] && [ ! -f /usr/lib/vmware-vmdir/sbin/vmdird ]; then echo "Detected this node is a vCenter gateway" echo "Please run this script from a vCenter with embedded PSC, or an external PSC" exit 1fiecho "NOTE: This works on external and embedded PSCs"echo "This script will do the following"echo "1: Regenerate STS certificate"echo "What is needed?"echo "1: Offline snapshots of VCs/PSCs"echo "2: SSO Admin Password"echo "IMPORTANT: This script should only be run on a single PSC per SSO domain"mkdir -p /tmp/vmware-fixstsSCRIPTPATH="/tmp/vmware-fixsts"LOGFILE="$SCRIPTPATH/fix_sts_cert.log"echo "==================================" | tee -a $LOGFILEecho "Resetting STS certificate for $HOSTNAME started on $(date)" | tee -a $LOGFILEecho ""| tee -a $LOGFILEecho ""DN=$(/opt/likewise/bin/lwregshell list_values '[HKEY_THIS_MACHINE\Services\vmdir]' | grep dcAccountDN | awk '{$1=$2=$3="";print $0}'|tr -d '"'|sed -e 's/^[ \t]*//')echo "Detected DN: $DN" | tee -a $LOGFILEPNID=$(/opt/likewise/bin/lwregshell list_values '[HKEY_THIS_MACHINE\Services\vmafd\Parameters]' | grep PNID | awk '{print $4}'|tr -d '"')echo "Detected PNID: $PNID" | tee -a $LOGFILEPSC=$(/opt/likewise/bin/lwregshell list_values '[HKEY_THIS_MACHINE\Services\vmafd\Parameters]' | grep DCName | awk '{print $4}'|tr -d '"')echo "Detected PSC: $PSC" | tee -a $LOGFILEDOMAIN=$(/opt/likewise/bin/lwregshell list_values '[HKEY_THIS_MACHINE\Services\vmafd\Parameters]' | grep DomainName | awk '{print $4}'|tr -d '"')echo "Detected SSO domain name: $DOMAIN" | tee -a $LOGFILESITE=$(/opt/likewise/bin/lwregshell list_values '[HKEY_THIS_MACHINE\Services\vmafd\Parameters]' | grep SiteName | awk '{print $4}'|tr -d '"')MACHINEID=$(/usr/lib/vmware-vmafd/bin/vmafd-cli get-machine-id --server-name localhost)echo "Detected Machine ID: $MACHINEID" | tee -a $LOGFILEIPADDRESS=$(ifconfig | grep eth0 -A1 | grep "inet addr" | awk -F ':' '{print $2}' | awk -F ' ' '{print $1}')echo "Detected IP Address: $IPADDRESS" | tee -a $LOGFILEDOMAINCN="dc=$(echo "$DOMAIN" | sed 's/\./,dc=/g')"echo "Domain CN: $DOMAINCN"ADMIN="cn=administrator,cn=users,$DOMAINCN"USERNAME="administrator@${DOMAIN^^}"ROOTCERTDATE=$(openssl x509 -in /var/lib/vmware/vmca/root.cer -text | grep "Not After" | awk -F ' ' '{print $7,$4,$5}')TODAYSDATE=$(date | awk -F ' ' '{print $6,$2,$3}')echo "#" > $SCRIPTPATH/certool.cfgecho "# Template file for a CSR request" >> $SCRIPTPATH/certool.cfgecho "#" >> certool.cfgecho "# Country is needed and has to be 2 characters" >> $SCRIPTPATH/certool.cfgecho "Country = DS" >> $SCRIPTPATH/certool.cfgecho "Name = $PNID" >> $SCRIPTPATH/certool.cfgecho "Organization = VMware" >> $SCRIPTPATH/certool.cfgecho "OrgUnit = VMware" >> $SCRIPTPATH/certool.cfgecho "State = VMware" >> $SCRIPTPATH/certool.cfgecho "Locality = VMware" >> $SCRIPTPATH/certool.cfgecho "IPAddress = $IPADDRESS" >> $SCRIPTPATH/certool.cfgecho "Email = email@acme.com" >> $SCRIPTPATH/certool.cfgecho "Hostname = $PNID" >> $SCRIPTPATH/certool.cfgecho "==================================" | tee -a $LOGFILEecho "==================================" | tee -a $LOGFILEecho ""echo "Detected Root's certificate expiration date: $ROOTCERTDATE" | tee -a $LOGFILEecho "Detected today's date: $TODAYSDATE" | tee -a $LOGFILEecho "==================================" | tee -a $LOGFILEflag=0if [[ $TODAYSDATE > $ROOTCERTDATE ]];then echo "IMPORTANT: Root certificate is expired, so it will be replaced" | tee -a $LOGFILE flag=1 mkdir /certs && cd /certs cp $SCRIPTPATH/certool.cfg /certs/vmca.cfg /usr/lib/vmware-vmca/bin/certool --genselfcacert --outprivkey /certs/vmcacert.key --outcert /certs/vmcacert.crt --config /certs/vmca.cfg /usr/lib/vmware-vmca/bin/certool --rootca --cert /certs/vmcacert.crt --privkey /certs/vmcacert.keyfiecho "#" > $SCRIPTPATH/certool.cfgecho "# Template file for a CSR request" >> $SCRIPTPATH/certool.cfgecho "#" >> $SCRIPTPATH/certool.cfgecho "# Country is needed and has to be 2 characters" >> $SCRIPTPATH/certool.cfgecho "Country = DS" >> $SCRIPTPATH/certool.cfgecho "Name = STS" >> $SCRIPTPATH/certool.cfgecho "Organization = VMware" >> $SCRIPTPATH/certool.cfgecho "OrgUnit = VMware" >> $SCRIPTPATH/certool.cfgecho "State = VMware" >> $SCRIPTPATH/certool.cfgecho "Locality = VMware" >> $SCRIPTPATH/certool.cfgecho "IPAddress = $IPADDRESS" >> $SCRIPTPATH/certool.cfgecho "Email = email@acme.com" >> $SCRIPTPATH/certool.cfgecho "Hostname = $PNID" >> $SCRIPTPATH/certool.cfgecho ""echo "Exporting and generating STS certificate" | tee -a $LOGFILEecho ""cd $SCRIPTPATH/usr/lib/vmware-vmca/bin/certool --server localhost --genkey --privkey=sts.key --pubkey=sts.pub/usr/lib/vmware-vmca/bin/certool --gencert --cert=sts.cer --privkey=sts.key --config=$SCRIPTPATH/certool.cfgopenssl x509 -outform der -in sts.cer -out sts.derCERTS=$(csplit -f root /var/lib/vmware/vmca/root.cer '/-----BEGIN CERTIFICATE-----/' '{*}' | wc -l)openssl pkcs8 -topk8 -inform pem -outform der -in sts.key -out sts.key.der -nocrypti=1until [ $i -eq $CERTS ]do openssl x509 -outform der -in root0$i -out vmca0$i.der ((i++))doneecho ""echo ""read -s -p "Enter password for administrator@$DOMAIN: " DOMAINPASSWORDecho ""# Find the highest tenant credentials indexMAXCREDINDEX=1while read -r linedo INDEX=$(echo "$line" | tr -dc '0-9') if [ $INDEX -gt $MAXCREDINDEX ] then MAXCREDINDEX=$INDEX fidone < <(/opt/likewise/bin/ldapsearch -h localhost -p 389 -b "cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN" -D "cn=administrator,cn=users,$DOMAINCN" -w "$DOMAINPASSWORD" "(objectclass=vmwSTSTenantCredential)" cn | grep cn:)# Sequentially search for tenant credentials up to max index and delete if foundecho "Highest tenant credentials index : $MAXCREDINDEX" | tee -a $LOGFILEi=1if [ ! -z $MAXCREDINDEX ]then until [ $i -gt $MAXCREDINDEX ] do echo "Exporting tenant $i to $SCRIPTPATH" | tee -a $LOGFILE echo "" ldapsearch -h localhost -D "cn=administrator,cn=users,$DOMAINCN" -w "$DOMAINPASSWORD" -b "cn=TenantCredential-$i,cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN" > $SCRIPTPATH/tenantcredential-$i.ldif if [ $? -eq 0 ] then echo "Deleting tenant $i" | tee -a $LOGFILE ldapdelete -h localhost -D "cn=administrator,cn=users,$DOMAINCN" -w "$DOMAINPASSWORD" "cn=TenantCredential-$i,cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN" | tee -a $LOGFILE else echo "Tenant $i not found" | tee -a $LOGFILE echo "" fi ((i++)) donefiecho ""# Find the highest trusted cert chains indexMAXCERTCHAINSINDEX=1while read -r linedo INDEX=$(echo "$line" | tr -dc '0-9') if [ $INDEX -gt $MAXCERTCHAINSINDEX ] then MAXCERTCHAINSINDEX=$INDEX fidone < <(/opt/likewise/bin/ldapsearch -h localhost -p 389 -b "cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN" -D "cn=administrator,cn=users,$DOMAINCN" -w "$DOMAINPASSWORD" "(objectclass=vmwSTSTenantTrustedCertificateChain)" cn | grep cn:)# Sequentially search for trusted cert chains up to max index and delete if foundecho "Highest trusted cert chains index: $MAXCERTCHAINSINDEX" | tee -a $LOGFILEi=1if [ ! -z $MAXCERTCHAINSINDEX ]then until [ $i -gt $MAXCERTCHAINSINDEX ] do echo "Exporting trustedcertchain $i to $SCRIPTPATH" | tee -a $LOGFILE echo "" ldapsearch -h localhost -D "cn=administrator,cn=users,$DOMAINCN" -w "$DOMAINPASSWORD" -b "cn=TrustedCertChain-$i,cn=TrustedCertificateChains,cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN" > $SCRIPTPATH/trustedcertchain-$i.ldif if [ $? -eq 0 ] then echo "Deleting trustedcertchain $i" | tee -a $LOGFILE ldapdelete -h localhost -D "cn=administrator,cn=users,$DOMAINCN" -w "$DOMAINPASSWORD" "cn=TrustedCertChain-$i,cn=TrustedCertificateChains,cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN" | tee -a $LOGFILE else echo "Trusted cert chain $i not found" | tee -a $LOGFILE fi echo "" ((i++)) donefiecho ""i=1echo "dn: cn=TenantCredential-1,cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN" > sso-sts.ldifecho "changetype: add" >> sso-sts.ldifecho "objectClass: vmwSTSTenantCredential" >> sso-sts.ldifecho "objectClass: top" >> sso-sts.ldifecho "cn: TenantCredential-1" >> sso-sts.ldifecho "userCertificate:< file:sts.der" >> sso-sts.ldifuntil [ $i -eq $CERTS ]do echo "userCertificate:< file:vmca0$i.der" >> sso-sts.ldif ((i++))doneecho "vmwSTSPrivateKey:< file:sts.key.der" >> sso-sts.ldifecho "" >> sso-sts.ldifecho "dn: cn=TrustedCertChain-1,cn=TrustedCertificateChains,cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN" >> sso-sts.ldifecho "changetype: add" >> sso-sts.ldifecho "objectClass: vmwSTSTenantTrustedCertificateChain" >> sso-sts.ldifecho "objectClass: top" >> sso-sts.ldifecho "cn: TrustedCertChain-1" >> sso-sts.ldifecho "userCertificate:< file:sts.der" >> sso-sts.ldifi=1until [ $i -eq $CERTS ]do echo "userCertificate:< file:vmca0$i.der" >> sso-sts.ldif ((i++))doneecho ""echo "Applying newly generated STS certificate to SSO domain" | tee -a $LOGFILE/opt/likewise/bin/ldapmodify -x -h localhost -p 389 -D "cn=administrator,cn=users,$DOMAINCN" -w "$DOMAINPASSWORD" -f sso-sts.ldif | tee -a $LOGFILEecho ""echo "Replacement finished - Please restart services on all vCenters and PSCs in your SSO domain" | tee -a $LOGFILEecho "==================================" | tee -a $LOGFILEecho "IMPORTANT: In case you're using HLM (Hybrid Linked Mode) without a gateway, you would need to re-sync the certs from Cloud to On-Prem after following this procedure" | tee -a $LOGFILEecho "==================================" | tee -a $LOGFILEecho "==================================" | tee -a $LOGFILEif [ $flag == 1 ]then echo "Since your Root certificate was expired and was replaced, you will need to replace your MachineSSL and Solution User certificates" | tee -a $LOGFILE echo "You can do so following this KB: https://kb.vmware.com/s/article/2097936" | tee -a $LOGFILEfi