{"id":634,"date":"2021-03-13T14:38:50","date_gmt":"2021-03-13T14:38:50","guid":{"rendered":"http:\/\/192.168.8.14\/?p=634"},"modified":"2021-05-12T21:36:52","modified_gmt":"2021-05-12T20:36:52","slug":"vcenter-vcsa-cert-checking","status":"publish","type":"post","link":"https:\/\/www.jasonstreet.com\/?p=634","title":{"rendered":"vCenter\/VCSA Cert checking"},"content":{"rendered":"\n<p>If you look after a vCenter or VCSA at some point you are going to have the certificates expire on you. And if you look after a lot of vCenter servers then expiring Certs are a constant headache that pops up just at the time that is most inconvenient. <br>VMWare detail that only in some circumstances do Certs expire every 2 years but in my experience Certs will expire every time I am on-call.<\/p>\n\n\n\n<p>Im not going to pretend to know much (anything) about vCenters certificates. In any production environment I normally end up logging a support case with VMWare. <\/p>\n\n\n\n<p>Just about every vCenter I have ever worked with uses self signed certs, so that is what Im going to be looking at in this post. I am also assuming the PSC is imbedded as this is the best practice. <br>vCenter Certificates (for me) fall in to two categories. STS certificate and everything else.<\/p>\n\n\n\n<p>Before making any changes make sure you have a backup and\/or snapshot of the vCenter\/PSC you are working on.<\/p>\n\n\n\n<p>To check the vCenter Cert expiry dates you can do this in the following ways<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"#SSH\" data-type=\"internal\" data-id=\"#SSH\">SSH console<\/a><\/li><li><a href=\"#Web interface\" data-type=\"internal\" data-id=\"#Web interface\">Web interface<\/a><\/li><\/ul>\n\n\n\n<p>SSH<\/p>\n\n\n\n<p>log on to the vCenter server using SSH using the root account and type<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">shell<br><br>for store in $(\/usr\/lib\/vmware-vmafd\/bin\/vecs-cli store list | grep -v TRUSTED_ROOT_CRLS); do echo &#8220;[*] Store :&#8221; $store; \/usr\/lib\/vmware-vmafd\/bin\/vecs-cli entry list &#8211;store $store &#8211;text | grep -ie &#8220;Alias&#8221; -ie &#8220;Not After&#8221;;done;<\/p>\n\n\n\n<p>You will get a list of all the certs (not the STS cert) on the vCenter. <br>Check the expiry date to see if any have or are going to expire.<\/p>\n\n\n\n<p>Web interface<\/p>\n\n\n\n<p>Go to the Admin menu and select Administration<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/192.168.8.14\/wp-content\/uploads\/2021\/03\/image.png\" alt=\"\" class=\"wp-image-635\" width=\"422\" height=\"541\" srcset=\"https:\/\/www.jasonstreet.com\/wp-content\/uploads\/2021\/03\/image.png 561w, https:\/\/www.jasonstreet.com\/wp-content\/uploads\/2021\/03\/image-234x300.png 234w, https:\/\/www.jasonstreet.com\/wp-content\/uploads\/2021\/03\/image-300x385.png 300w\" sizes=\"auto, (max-width: 422px) 100vw, 422px\" \/><figcaption>The vCenter admin menu<\/figcaption><\/figure>\n\n\n\n<p>Then on the left select Certificate Management.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/192.168.8.14\/wp-content\/uploads\/2021\/03\/image-1-1024x423.png\" alt=\"\" class=\"wp-image-636\" width=\"661\" height=\"272\" srcset=\"https:\/\/www.jasonstreet.com\/wp-content\/uploads\/2021\/03\/image-1-1024x423.png 1024w, https:\/\/www.jasonstreet.com\/wp-content\/uploads\/2021\/03\/image-1-300x124.png 300w, https:\/\/www.jasonstreet.com\/wp-content\/uploads\/2021\/03\/image-1-1536x635.png 1536w, https:\/\/www.jasonstreet.com\/wp-content\/uploads\/2021\/03\/image-1-850x351.png 850w, https:\/\/www.jasonstreet.com\/wp-content\/uploads\/2021\/03\/image-1.png 1543w\" sizes=\"auto, (max-width: 661px) 100vw, 661px\" \/><figcaption>Certificates on the vCenter<\/figcaption><\/figure>\n\n\n\n<p>To renew the certs you will need to run the <br><a href=\"https:\/\/kb.vmware.com\/s\/article\/2097936\" target=\"_blank\" rel=\"noreferrer noopener\">Certificate manager<\/a><\/p>\n\n\n\n<p><strong>Checking the STS Certificate<\/strong><\/p>\n\n\n\n<p>The STS (Security Token Service) is not listed above and when that expires nothing is going to work. It used be visible in the flash UI in the same place as all the other certs. But not anymore.<br>A useful KB is <a rel=\"noreferrer noopener\" href=\"https:\/\/kb.vmware.com\/s\/article\/79248\" target=\"_blank\">here<\/a> that details determining if the STS cert has expired. If the vCenter has been rebooted then I do not get the error in the vpxd-svcs.log. The KB for renewing the cert is <a rel=\"noreferrer noopener\" href=\"https:\/\/kb.vmware.com\/s\/article\/76719\" target=\"_blank\">here<\/a><\/p>\n\n\n\n<p>Before making any changes make sure you have a backup and\/or snapshot of the vCenter\/PSC you are working on.<\/p>\n\n\n\n<p>I go straight to downloading the Checksts.py script<\/p>\n\n\n\n<p>I find the easy way is to simple SSH to the vCenter. open vi, paste in the contacts of the script and save it.<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Shell<br>cd \/tmp<br>vi checksts.py<\/p>\n\n\n\n<p>Paste in the code and <br>type [Esc] then : then w! [enter]<br>type [Esc] then : then q [enter]<br>You can now run the script using <\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">python checksts.py<br><\/p>\n\n\n\n<p>if you get a syntax error then check the script as some times the first couple of lines to not get copyed in.<\/p>\n\n\n\n<p>You will get a list of the 2 STS certs and there expiry date. If they need to be renewed keep reading.<\/p>\n\n\n\n<p><strong>Renewing STS certs<\/strong><\/p>\n\n\n\n<p>Please do not just blindly follow the below steps. Read the KB articles so you understand what you are doing.<\/p>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/kb.vmware.com\/s\/article\/68171\" target=\"_blank\">There are certificate that expired or about to expire<\/a><br><a rel=\"noreferrer noopener\" href=\"https:\/\/kb.vmware.com\/s\/article\/76719\" target=\"_blank\">Signing certificate is not valid<\/a><\/p>\n\n\n\n<p>Again, I find the easy way is to simply SSH to the vCenter. open vi, paste in the contacts of the script and save it.<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">Shell<br>cd \/tmp<br>vi fixsts.sh<\/p>\n\n\n\n<p>Paste in the code and<br>type [Esc] then : then w! [enter]<br>type [Esc] then : then q [enter]<br>You now need to make the script executable and then it can be run.<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">chmod +x fixsts.sh<br>.\/fixsts.sh<\/p>\n\n\n\n<p>Now you can restart services or reboot the vCenter<\/p>\n\n\n\n<p class=\"has-white-color has-black-background-color has-text-color has-background\">service-control &#8211;stop &#8211;all<br>service-control &#8211;start &#8211;all<\/p>\n\n\n\n<p>I will list the scripts below for easy copy and pasting.<\/p>\n\n\n\n<p>I hope this is of use.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>checksts.pl<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n#!\/opt\/vmware\/bin\/python\n\n\n&quot;&quot;&quot;\nCopyright 2020-2022 VMware, Inc.  All rights reserved. -- VMware Confidential\nAuthor:  Keenan Matheny (keenanm@vmware.com)\n\n&quot;&quot;&quot;\n##### BEGIN IMPORTS #####\n\nimport os\nimport sys\nimport json\nimport subprocess\nimport re\nimport pprint\nimport ssl\nfrom datetime import datetime, timedelta\nimport textwrap\nfrom codecs import encode, decode\nimport subprocess\nfrom time import sleep\ntry:\n    # Python 3 hack.\n    import urllib.request as urllib2\n    import urllib.parse as urlparse\nexcept ImportError:\n    import urllib2\n    import urlparse\n\nsys.path.append(os.environ&#x5B;&#039;VMWARE_PYTHON_PATH&#039;])\nfrom cis.defaults import def_by_os\nsys.path.append(os.path.join(os.environ&#x5B;&#039;VMWARE_CIS_HOME&#039;],\n                def_by_os(&#039;vmware-vmafd\/lib64&#039;, &#039;vmafdd&#039;)))\nimport vmafd\nfrom OpenSSL.crypto import (load_certificate, dump_privatekey, dump_certificate, X509, X509Name, PKey)\nfrom OpenSSL.crypto import (TYPE_DSA, TYPE_RSA, FILETYPE_PEM, FILETYPE_ASN1 )\n\ntoday = datetime.now()\ntoday = today.strftime(&quot;%d-%m-%Y&quot;)\n\nvcsa_kblink = &quot;https:\/\/kb.vmware.com\/s\/article\/76719&quot;\nwin_kblink = &quot;https:\/\/kb.vmware.com\/s\/article\/79263&quot;\n\n##### END IMPORTS #####\n\nclass parseCert( object ):\n    # Certificate parsing\n\n    def format_subject_issuer(self, x509name): \n        items = &#x5B;]\n        for item in x509name.get_components():\n            items.append(&#039;%s=%s&#039; %  (decode(item&#x5B;0],&#039;ascii&#039;), decode(item&#x5B;1],&#039;ascii&#039;)))\n        return &quot;, &quot;.join(items)\n\n    def format_asn1_date(self, d):\n        return datetime.strptime(decode(d,&#039;ascii&#039;), &#039;%Y%m%d%H%M%SZ&#039;).strftime(&quot;%Y-%m-%d %H:%M:%S GMT&quot;)\n\n    def merge_cert(self, extensions, certificate):\n        z = certificate.copy()\n        z.update(extensions)\n        return z\n\n    def __init__(self, certdata):\n\n        built_cert = certdata\n        self.x509 = load_certificate(FILETYPE_PEM, built_cert)\n        keytype = self.x509.get_pubkey().type()\n        keytype_list = {TYPE_RSA:&#039;rsaEncryption&#039;, TYPE_DSA:&#039;dsaEncryption&#039;, 408:&#039;id-ecPublicKey&#039;}\n        extension_list = &#x5B;&quot;extendedKeyUsage&quot;,\n                        &quot;keyUsage&quot;,\n                        &quot;subjectAltName&quot;,\n                        &quot;subjectKeyIdentifier&quot;,\n                        &quot;authorityKeyIdentifier&quot;]\n        key_type_str = keytype_list&#x5B;keytype] if keytype in keytype_list else &#039;other&#039;\n\n        certificate = {}\n        extension = {}\n        for i in range(self.x509.get_extension_count()):\n            critical = &#039;critical&#039; if self.x509.get_extension(i).get_critical() else &#039;&#039;\n\n            if decode(self.x509.get_extension(i).get_short_name(),&#039;ascii&#039;) in extension_list:\n                extension&#x5B;decode(self.x509.get_extension(i).get_short_name(),&#039;ascii&#039;)] = self.x509.get_extension(i).__str__()\n\n        certificate = {&#039;Thumbprint&#039;: decode(self.x509.digest(&#039;sha1&#039;),&#039;ascii&#039;), &#039;Version&#039;: self.x509.get_version(),\n         &#039;SignatureAlg&#039; : decode(self.x509.get_signature_algorithm(),&#039;ascii&#039;), &#039;Issuer&#039; :self.format_subject_issuer(self.x509.get_issuer()), \n         &#039;Valid From&#039; : self.format_asn1_date(self.x509.get_notBefore()), &#039;Valid Until&#039; : self.format_asn1_date(self.x509.get_notAfter()),\n         &#039;Subject&#039; : self.format_subject_issuer(self.x509.get_subject())}\n        \n        combined = self.merge_cert(extension,certificate)\n        cert_output = json.dumps(combined)\n\n        self.subjectAltName = combined.get(&#039;subjectAltName&#039;)\n        self.subject = combined.get(&#039;Subject&#039;)\n        self.validfrom = combined.get(&#039;Valid From&#039;)\n        self.validuntil = combined.get(&#039;Valid Until&#039;)\n        self.thumbprint = combined.get(&#039;Thumbprint&#039;)\n        self.subjectkey = combined.get(&#039;subjectKeyIdentifier&#039;)\n        self.authkey = combined.get(&#039;authorityKeyIdentifier&#039;)\n        self.combined = combined\n\nclass parseSts( object ):\n\n    def __init__(self):\n        self.processed = &#x5B;]\n        self.results = {}\n        self.results&#x5B;&#039;expired&#039;] = {}\n        self.results&#x5B;&#039;expired&#039;]&#x5B;&#039;root&#039;] = &#x5B;]\n        self.results&#x5B;&#039;expired&#039;]&#x5B;&#039;leaf&#039;] = &#x5B;]\n        self.results&#x5B;&#039;valid&#039;] = {}\n        self.results&#x5B;&#039;valid&#039;]&#x5B;&#039;root&#039;] = &#x5B;]\n        self.results&#x5B;&#039;valid&#039;]&#x5B;&#039;leaf&#039;] = &#x5B;]\n\n    def get_certs(self,force_refresh):\n        urllib2.getproxies = lambda: {}\n        vmafd_client = vmafd.client(&#039;localhost&#039;)\n        domain_name = vmafd_client.GetDomainName()\n\n        dc_name = vmafd_client.GetAffinitizedDC(domain_name, force_refresh)\n        if vmafd_client.GetPNID() == dc_name:\n            url = (\n                &#039;http:\/\/localhost:7080\/idm\/tenant\/%s\/certificates?scope=TENANT&#039;\n                % domain_name)\n        else:\n            url = (\n                &#039;https:\/\/%s\/idm\/tenant\/%s\/certificates?scope=TENANT&#039;\n                % (dc_name,domain_name))\n        return json.loads(urllib2.urlopen(url).read().decode(&#039;utf-8&#039;))\n\n    def check_cert(self,certificate):\n        cert = parseCert(certificate)\n        certdetail = cert.combined\n\n            #  Attempt to identify what type of certificate it is\n        if cert.authkey:\n            cert_type = &quot;leaf&quot;\n        else:\n            cert_type = &quot;root&quot;\n        \n        #  Try to only process a cert once\n        if cert.thumbprint not in self.processed:\n            # Date conversion\n            self.processed.append(cert.thumbprint)\n            exp = cert.validuntil.split()&#x5B;0]\n            conv_exp = datetime.strptime(exp, &#039;%Y-%m-%d&#039;)\n            exp = datetime.strftime(conv_exp, &#039;%d-%m-%Y&#039;)\n            now = datetime.strptime(today, &#039;%d-%m-%Y&#039;)\n            exp_date = datetime.strptime(exp, &#039;%d-%m-%Y&#039;)\n            \n            # Get number of days until it expires\n            diff = exp_date - now\n            certdetail&#x5B;&#039;daysUntil&#039;] = diff.days\n\n            # Sort expired certs into leafs and roots, put the rest in goodcerts.\n            if exp_date &lt;= now:\n                self.results&#x5B;&#039;expired&#039;]&#x5B;cert_type].append(certdetail)\n            else:\n                self.results&#x5B;&#039;valid&#039;]&#x5B;cert_type].append(certdetail)\n    \n    def execute(self):\n\n        json = self.get_certs(force_refresh=False)\n        for item in json:\n            for certificate in item&#x5B;&#039;certificates&#039;]:\n                self.check_cert(certificate&#x5B;&#039;encoded&#039;])\n        return self.results\n\ndef main():\n\n    warning = False\n    warningmsg = &#039;&#039;&#039;\n    WARNING! \n    You have expired STS certificates.  Please follow the KB corresponding to your OS:\n    VCSA:  %s\n    Windows:  %s\n    &#039;&#039;&#039; % (vcsa_kblink, win_kblink)\n    parse_sts = parseSts()\n    results = parse_sts.execute()\n    valid_count = len(results&#x5B;&#039;valid&#039;]&#x5B;&#039;leaf&#039;]) + len(results&#x5B;&#039;valid&#039;]&#x5B;&#039;root&#039;])\n    expired_count = len(results&#x5B;&#039;expired&#039;]&#x5B;&#039;leaf&#039;]) + len(results&#x5B;&#039;expired&#039;]&#x5B;&#039;root&#039;])\n          \n    \n    #### Display Valid ####\n    print(&quot;\\n%s VALID CERTS\\n================&quot; % valid_count)\n    print(&quot;\\n\\tLEAF CERTS:\\n&quot;)\n    if len(results&#x5B;&#039;valid&#039;]&#x5B;&#039;leaf&#039;]) &gt; 0:\n        for cert in results&#x5B;&#039;valid&#039;]&#x5B;&#039;leaf&#039;]:\n            print(&quot;\\t&#x5B;] Certificate %s will expire in %s days (%s years).&quot; % (cert&#x5B;&#039;Thumbprint&#039;], cert&#x5B;&#039;daysUntil&#039;], round(cert&#x5B;&#039;daysUntil&#039;]\/365)))\n    else:\n        print(&quot;\\tNone&quot;)\n    print(&quot;\\n\\tROOT CERTS:\\n&quot;)\n    if len(results&#x5B;&#039;valid&#039;]&#x5B;&#039;root&#039;]) &gt; 0:\n        for cert in results&#x5B;&#039;valid&#039;]&#x5B;&#039;root&#039;]:\n            print(&quot;\\t&#x5B;] Certificate %s will expire in %s days (%s years).&quot; % (cert&#x5B;&#039;Thumbprint&#039;], cert&#x5B;&#039;daysUntil&#039;], round(cert&#x5B;&#039;daysUntil&#039;]\/365)))\n    else:\n        print(&quot;\\tNone&quot;)\n\n\n    #### Display expired ####\n    print(&quot;\\n%s EXPIRED CERTS\\n================&quot; % expired_count)\n    print(&quot;\\n\\tLEAF CERTS:\\n&quot;)\n    if len(results&#x5B;&#039;expired&#039;]&#x5B;&#039;leaf&#039;]) &gt; 0:\n        for cert in results&#x5B;&#039;expired&#039;]&#x5B;&#039;leaf&#039;]:\n            print(&quot;\\t&#x5B;] Certificate: %s expired on %s!&quot; % (cert.get(&#039;Thumbprint&#039;),cert.get(&#039;Valid Until&#039;)))\n            continue\n    else:\n        print(&quot;\\tNone&quot;)\n\n    print(&quot;\\n\\tROOT CERTS:\\n&quot;)\n    if len(results&#x5B;&#039;expired&#039;]&#x5B;&#039;root&#039;]) &gt; 0:\n        for cert in results&#x5B;&#039;expired&#039;]&#x5B;&#039;root&#039;]:\n            print(&quot;\\t&#x5B;] Certificate: %s expired on %s!&quot; % (cert.get(&#039;Thumbprint&#039;),cert.get(&#039;Valid Until&#039;)))\n            continue\n    else:\n        print(&quot;\\tNone&quot;)\n\n    if expired_count &gt; 0:\n        print(warningmsg)\n\n\nif __name__ == &#039;__main__&#039;:\n    exit(main())\n\n\n<\/pre><\/div>\n\n\n<p><\/p>\n\n\n\n<p>fixsts.sh<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n#!\/bin\/bash\n# Run this from the affected PSC\/VC\n# Luciano Delorenzi &#x5B;ldelorenzi@vmware.com] - 1\/2\/2020\n\n# NOTE: This works on external and embedded PSCs\n# This script will do the following\n# 1: Regenerate STS certificate\n#\n#\n# What is needed?\n# 1: Offline snapshots of VCs\/PSCs\n# 2: SSO Admin Password\n\nNODETYPE=$(cat \/etc\/vmware\/deployment.node.type)\nif &#x5B; &quot;$NODETYPE&quot; = &quot;management&quot; ]; then\n    echo &quot;Detected this node is a vCenter server with external PSC.&quot;\n\techo &quot;Please run this script from a vCenter with embedded PSC, or an external PSC&quot;\n\texit 0\nfi\n\n\necho &quot;NOTE: This works on external and embedded PSCs&quot;\necho &quot;This script will do the following&quot;\necho &quot;1: Regenerate STS certificate&quot;\necho &quot;What is needed?&quot;\necho &quot;1: Offline snapshots of VCs\/PSCs&quot;\necho &quot;2: SSO Admin Password&quot;\necho &quot;IMPORTANT: This script should only be run on a single PSC per SSO domain&quot;\n\n\nmkdir -p \/tmp\/vmware-fixsts\nSCRIPTPATH=&quot;\/tmp\/vmware-fixsts&quot;\nLOGFILE=&quot;$SCRIPTPATH\/fix_sts_cert.log&quot;\n\necho &quot;==================================&quot; | tee -a $LOGFILE\necho &quot;Resetting STS certificate for $HOSTNAME started on $(date)&quot; | tee -a $LOGFILE\necho &quot;&quot;| tee -a $LOGFILE\necho &quot;&quot;\nDN=$(\/opt\/likewise\/bin\/lwregshell list_values &#039;&#x5B;HKEY_THIS_MACHINE\\Services\\vmdir]&#039; | grep dcAccountDN | awk &#039;{$1=$2=$3=&quot;&quot;;print $0}&#039;|tr -d &#039;&quot;&#039;|sed -e &#039;s\/^&#x5B; \\t]*\/\/&#039;)\necho &quot;Detected DN: $DN&quot; | tee -a $LOGFILE \nPNID=$(\/opt\/likewise\/bin\/lwregshell list_values &#039;&#x5B;HKEY_THIS_MACHINE\\Services\\vmafd\\Parameters]&#039; | grep PNID | awk &#039;{print $4}&#039;|tr -d &#039;&quot;&#039;)\necho &quot;Detected PNID: $PNID&quot; | tee -a $LOGFILE\nPSC=$(\/opt\/likewise\/bin\/lwregshell list_values &#039;&#x5B;HKEY_THIS_MACHINE\\Services\\vmafd\\Parameters]&#039; | grep DCName | awk &#039;{print $4}&#039;|tr -d &#039;&quot;&#039;)\necho &quot;Detected PSC: $PSC&quot; | tee -a $LOGFILE\nDOMAIN=$(\/opt\/likewise\/bin\/lwregshell list_values &#039;&#x5B;HKEY_THIS_MACHINE\\Services\\vmafd\\Parameters]&#039; | grep DomainName | awk &#039;{print $4}&#039;|tr -d &#039;&quot;&#039;)\necho &quot;Detected SSO domain name: $DOMAIN&quot; | tee -a $LOGFILE\nSITE=$(\/opt\/likewise\/bin\/lwregshell list_values &#039;&#x5B;HKEY_THIS_MACHINE\\Services\\vmafd\\Parameters]&#039; | grep SiteName | awk &#039;{print $4}&#039;|tr -d &#039;&quot;&#039;)\nMACHINEID=$(\/usr\/lib\/vmware-vmafd\/bin\/vmafd-cli get-machine-id --server-name localhost)\necho &quot;Detected Machine ID: $MACHINEID&quot; | tee -a $LOGFILE\nIPADDRESS=$(ifconfig | grep eth0 -A1 | grep &quot;inet addr&quot; | awk -F &#039;:&#039; &#039;{print $2}&#039; | awk -F &#039; &#039; &#039;{print $1}&#039;)\necho &quot;Detected IP Address: $IPADDRESS&quot; | tee -a $LOGFILE\nDOMAINCN=&quot;dc=$(echo &quot;$DOMAIN&quot; | sed &#039;s\/\\.\/,dc=\/g&#039;)&quot;\necho &quot;Domain CN: $DOMAINCN&quot;\nADMIN=&quot;cn=administrator,cn=users,$DOMAINCN&quot;\nUSERNAME=&quot;administrator@${DOMAIN^^}&quot;\nROOTCERTDATE=$(openssl x509  -in \/var\/lib\/vmware\/vmca\/root.cer -text | grep &quot;Not After&quot; | awk -F &#039; &#039; &#039;{print $7,$4,$5}&#039;)\nTODAYSDATE=$(date | awk -F &#039; &#039; &#039;{print $6,$2,$3}&#039;)\n\necho &quot;#&quot; &gt; $SCRIPTPATH\/certool.cfg\necho &quot;# Template file for a CSR request&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;#&quot; &gt;&gt; certool.cfg\necho &quot;# Country is needed and has to be 2 characters&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;Country = DS&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;Name = $PNID&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;Organization = VMware&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;OrgUnit = VMware&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;State = VMware&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;Locality = VMware&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;IPAddress = $IPADDRESS&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;Email = email@acme.com&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;Hostname = $PNID&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\n\necho &quot;==================================&quot; | tee -a $LOGFILE\necho &quot;==================================&quot; | tee -a $LOGFILE\necho &quot;&quot;\necho &quot;Detected Root&#039;s certificate expiration date: $ROOTCERTDATE&quot; | tee -a $LOGFILE\necho &quot;Detected today&#039;s date: $TODAYSDATE&quot; | tee -a $LOGFILE\n\necho &quot;==================================&quot; | tee -a $LOGFILE\n\nflag=0\nif &#x5B;&#x5B; $TODAYSDATE &gt; $ROOTCERTDATE ]];\nthen\n    echo &quot;IMPORTANT: Root certificate is expired, so it will be replaced&quot; | tee -a $LOGFILE\n    flag=1\n\tmkdir \/certs &amp;&amp; cd \/certs\n    cp $SCRIPTPATH\/certool.cfg \/certs\/vmca.cfg\n    \/usr\/lib\/vmware-vmca\/bin\/certool --genselfcacert --outprivkey \/certs\/vmcacert.key  --outcert \/certs\/vmcacert.crt --config \/certs\/vmca.cfg\n    \/usr\/lib\/vmware-vmca\/bin\/certool --rootca --cert \/certs\/vmcacert.crt --privkey \/certs\/vmcacert.key\nfi\n\necho &quot;#&quot; &gt; $SCRIPTPATH\/certool.cfg\necho &quot;# Template file for a CSR request&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;#&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;# Country is needed and has to be 2 characters&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;Country = DS&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;Name = STS&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;Organization = VMware&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;OrgUnit = VMware&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;State = VMware&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;Locality = VMware&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;IPAddress = $IPADDRESS&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;Email = email@acme.com&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\necho &quot;Hostname = $PNID&quot; &gt;&gt; $SCRIPTPATH\/certool.cfg\n\n\n\necho &quot;&quot;\necho &quot;Exporting and generating STS certificate&quot; | tee -a $LOGFILE\necho &quot;&quot;\n\ncd $SCRIPTPATH\n\n\/usr\/lib\/vmware-vmca\/bin\/certool --server localhost --genkey --privkey=sts.key --pubkey=sts.pub\n\/usr\/lib\/vmware-vmca\/bin\/certool --gencert --cert=sts.cer --privkey=sts.key --config=$SCRIPTPATH\/certool.cfg\n\nopenssl x509 -outform der -in sts.cer -out sts.der\nCERTS=$(csplit -f root \/var\/lib\/vmware\/vmca\/root.cer &#039;\/-----BEGIN CERTIFICATE-----\/&#039; &#039;{*}&#039; | wc -l)\nopenssl pkcs8 -topk8 -inform pem -outform der -in sts.key -out sts.key.der -nocrypt\ni=1\nuntil &#x5B; $i -eq $CERTS ]\ndo\n\topenssl x509 -outform der -in root0$i -out vmca0$i.der\n\t((i++))\ndone\n\necho &quot;&quot;\necho &quot;&quot;\nread -s -p &quot;Enter password for administrator@$DOMAIN: &quot; DOMAINPASSWORD\n\n\nTENANTS=$(\/opt\/likewise\/bin\/ldapsearch -h localhost -p 389 -b &quot;cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN&quot; -D &quot;cn=administrator,cn=users,$DOMAINCN&quot; -w &quot;$DOMAINPASSWORD&quot; &quot;(objectclass=vmwSTSTenantCredential)&quot; | grep numEntries | awk &#039;{print $3}&#039;)\necho &quot;&quot;\nTRUSTEDCERTCHAINS=$(\/opt\/likewise\/bin\/ldapsearch -h localhost -p 389 -b &quot;cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN&quot; -D &quot;cn=administrator,cn=users,$DOMAINCN&quot; -w &quot;$DOMAINPASSWORD&quot; &quot;(objectclass=vmwSTSTenantTrustedCertificateChain)&quot; | grep numEntries | awk &#039;{print $3}&#039;)\necho &quot;Amount of tenant credentials: $TENANTS&quot; | tee -a $LOGFILE\ni=1\nif &#x5B; ! -z $TENANTS ]  \nthen\n\tuntil &#x5B; $i -gt $TENANTS ]\n\tdo\n\t\techo &quot;Exporting tenant $i to $SCRIPTPATH&quot; | tee -a $LOGFILE\n\t\techo &quot;&quot;\n\t\tldapsearch -h localhost -D &quot;cn=administrator,cn=users,$DOMAINCN&quot; -w &quot;$DOMAINPASSWORD&quot; -b &quot;cn=TenantCredential-$i,cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN&quot; &gt; $SCRIPTPATH\/tenantcredential-$i.ldif\n\t\techo &quot;Deleting tenant $i&quot; | tee -a $LOGFILE\n\t\tldapdelete -h localhost -D &quot;cn=administrator,cn=users,$DOMAINCN&quot; -w &quot;$DOMAINPASSWORD&quot; &quot;cn=TenantCredential-$i,cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN&quot; | tee -a $LOGFILE\n\t\t((i++))\n\tdone\nfi\necho &quot;&quot;\n\necho &quot;Amount of trustedcertchains: $TRUSTEDCERTCHAINS&quot; | tee -a $LOGFILE\ni=1\nif &#x5B; ! -z $TRUSTEDCERTCHAINS ]  \nthen\n\tuntil &#x5B; $i -gt $TRUSTEDCERTCHAINS ]\n\tdo\n\t\techo &quot;Exporting trustedcertchain $i to $SCRIPTPATH&quot; | tee -a $LOGFILE\n\t\tldapsearch -h localhost -D &quot;cn=administrator,cn=users,$DOMAINCN&quot; -w &quot;$DOMAINPASSWORD&quot; -b &quot;cn=TrustedCertChain-$i,cn=TrustedCertificateChains,cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN&quot; &gt; $SCRIPTPATH\/trustedcertchain-$i.ldif\n\t\techo &quot;&quot;\n\t\techo &quot;Deleting trustedcertchain $i&quot; | tee -a $LOGFILE\n\t\tldapdelete -h localhost -D &quot;cn=administrator,cn=users,$DOMAINCN&quot; -w &quot;$DOMAINPASSWORD&quot; &quot;cn=TrustedCertChain-$i,cn=TrustedCertificateChains,cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN&quot; | tee -a $LOGFILE\n\t\t((i++))\n\tdone\nfi\necho &quot;&quot;\n\ni=1\necho &quot;dn: cn=TenantCredential-1,cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN&quot; &gt; sso-sts.ldif\necho &quot;changetype: add&quot; &gt;&gt; sso-sts.ldif\necho &quot;objectClass: vmwSTSTenantCredential&quot; &gt;&gt; sso-sts.ldif\necho &quot;objectClass: top&quot; &gt;&gt; sso-sts.ldif\necho &quot;cn: TenantCredential-1&quot; &gt;&gt; sso-sts.ldif\necho &quot;userCertificate:&lt; file:sts.der&quot; &gt;&gt; sso-sts.ldif\nuntil &#x5B; $i -eq $CERTS ]\ndo\n\techo &quot;userCertificate:&lt; file:vmca0$i.der&quot; &gt;&gt; sso-sts.ldif\n\t((i++))\ndone\necho &quot;vmwSTSPrivateKey:&lt; file:sts.key.der&quot; &gt;&gt; sso-sts.ldif\necho &quot;&quot; &gt;&gt; sso-sts.ldif\necho &quot;dn: cn=TrustedCertChain-1,cn=TrustedCertificateChains,cn=$DOMAIN,cn=Tenants,cn=IdentityManager,cn=Services,$DOMAINCN&quot; &gt;&gt; sso-sts.ldif\necho &quot;changetype: add&quot; &gt;&gt; sso-sts.ldif\necho &quot;objectClass: vmwSTSTenantTrustedCertificateChain&quot; &gt;&gt; sso-sts.ldif\necho &quot;objectClass: top&quot; &gt;&gt; sso-sts.ldif\necho &quot;cn: TrustedCertChain-1&quot; &gt;&gt; sso-sts.ldif\necho &quot;userCertificate:&lt; file:sts.der&quot; &gt;&gt; sso-sts.ldif\ni=1\nuntil &#x5B; $i -eq $CERTS ]\ndo\n\techo &quot;userCertificate:&lt; file:vmca0$i.der&quot; &gt;&gt; sso-sts.ldif\n\t((i++))\ndone\necho &quot;&quot;\necho &quot;Applying newly generated STS certificate to SSO domain&quot; | tee -a $LOGFILE\n\n\/opt\/likewise\/bin\/ldapmodify -x -h localhost -p 389 -D &quot;cn=administrator,cn=users,$DOMAINCN&quot; -w &quot;$DOMAINPASSWORD&quot; -f sso-sts.ldif | tee -a $LOGFILE\necho &quot;&quot;\necho &quot;Replacement finished - Please restart services on all vCenters and PSCs in your SSO domain&quot; | tee -a $LOGFILE\necho &quot;==================================&quot; | tee -a $LOGFILE\necho &quot;IMPORTANT: In case you&#039;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&quot; | tee -a $LOGFILE\necho &quot;==================================&quot; | tee -a $LOGFILE\necho &quot;==================================&quot; | tee -a $LOGFILE\nif &#x5B; $flag == 1 ]\nthen\n\techo &quot;Since your Root certificate was expired and was replaced, you will need to replace your MachineSSL and Solution User certificates&quot; | tee -a $LOGFILE\n\techo &quot;You can do so following this KB: https:\/\/kb.vmware.com\/s\/article\/2097936&quot; | tee -a $LOGFILE\nfi\n\n\n\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>If you look after a vCenter or VCSA at some point you are going to have the certificates expire on you. And if you look after a lot of vCenter servers then expiring Certs are a constant headache that pops up just at the time that is most inconvenient. VMWare detail that only in some&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[44,1,43],"tags":[125,126,47,127,128,20,46],"class_list":["post-634","post","type-post","status-publish","format-standard","hentry","category-fix","category-uncategorized","category-vmware","tag-cert","tag-certificate","tag-expired","tag-expiring","tag-sts","tag-vcenter","tag-vcsa"],"_links":{"self":[{"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/posts\/634","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=634"}],"version-history":[{"count":3,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/posts\/634\/revisions"}],"predecessor-version":[{"id":682,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/posts\/634\/revisions\/682"}],"wp:attachment":[{"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=634"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=634"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=634"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}