Tuesday, August 17, 2021

Creating a new self-signed certificate for xDB (on-prem)

 So the SSL certificate for your xDB instance has expired, and you need to create a new one. Here’s some setup and troubleshooting steps (this is specific to On-Prem). The steps aren’t difficult but it took me a lot of searching and about five different articles to figure out everything I needed to do, so I’ve compiled the steps here.

NOTE: This pertains to lower environments. According to Sitecore documentation, self-signed certificates must NOT be used in production for security.

Use Powershell to create a new certificate with makecert.exe

There are a number of ways to generate a self-signed certificate, but it is important to make sure that 1) it has the correct common name (CN) so that it will be valid for your xconnect domain; and 2) that it has a private key so that you can install it on your CD instance.

Here is the Sitecore documentation for generating a certificate. However, the certificate I generated with this method did not have a Subject Alternative Name, so it came up as invalid in Chrome after I bound it to my xconnect instance. Instead, I used this command in Powershell:

1
New-SelfSignedCertificate -DnsName {DOMAIN} -CertStoreLocation cert:\LocalMachine\My

Get the thumbprint of the certificate you just created (Get-ChildItem -Path cert:\LocalMachine\My), and use that thumbprint to export a pfx file with the following command (replace $thumbprint with your thumbprint):

1
2
3
4
5
$certificateFilePath = "D:\Temp\$thumbprint.pfx"
Export-PfxCertificate `
    -cert cert:\LocalMachine\MY\$thumbprint `
    -FilePath "$certificateFilePath" `
    -Password (Read-Host -Prompt "Enter password that would protect the certificate" -AsSecureString)
If you have a separate CD server
  1. Copy the exported pfx file to your CD server
  2. Double click to run the installation wizard
  3. Place the certificate in the Personal store
  4. Check that the certificate is correctly installed on CD by opening Powershell and running Get-ChildItem -Path cert:\localmachine\my\$thumbprint

Add certificate to the Trusted Root Authority

If you see an invalid certificate warning, saying “CA Root certificate is not trusted”. Here is helpful documentation for that, but I’ll summarize the steps below:

  1. Browse to the location you exported your certificate to (e.g. D:\Temp) and double click the pfx file.
  2. Install -> Local Machine -> Place all certificate in the following store -> Trusted Root Certification Authorities
  3. Repeat and place certificate in the Personal store

Update thumbprints in your Sitecore instances

You need to update all of the certificate thumbprints in your xconnect app_settings and in each site that uses xconnect. You can see the full details for updating thumbprints here; I’ve summarized below:

  1. Get the thumbprint of your new certificate (on the machine that’s running xconnect). You can do this in Powershell using the command Get-ChildItem -Path Cert:\LocalMachine\My\ -DnsName "your.client.cert.dns*" . Copy the thumbprint.
  2. In your xconnect instance, update the thumbprint in \App_Config\AppSettings.config
  3. In all Sitecore XP roles, update the thumbprint in the connectionstrings
  4. If applicable, update the thumbprint in \App_Data\jobs\continuous\AutomationEngine\App_Config\ConnectionStrings.config and \App_Data\jobs\continuous\ProcessingEngine\App_Config\ConnectionStrings.config
  5. Ensure that the AllowInvalidClientCertificates app setting is true in xconnect and on all Sitecore XP roles (this is necessary for self-signed certificates)

Install the certificate on XP servers

If your Sitecore instances are hosted on a different server than xconnect (e.g. CD), you need to install the certificate on each of those servers as well.

  1. Browse to xconnect.
  2. Click on the Not Secure warning next to the domain and click on Certificate
  3. Go to Details -> Copy to Files -> Base 64 Encode
  4. Find the certificate in the location you copied it to and double click to begin the import wizard.

Note: if your connectionstrings are looking at “StoreName=My;StoreLocation=LocalMachine”, this corresponds to the “Personal” store

Additional Troubleshooting

Copy the following into a new file and save it as CertTestOnPremise.aspx; put this file in the root of your website:

<%@ Page Language="c#" Inherits="System.Web.UI.Page" CodePage="65001" %>

<%@ OutputCache Location="None" VaryByParam="none" %>
<%@ Import Namespace="Sitecore" %>
<%@ Import Namespace="Sitecore.Xdb.Common.Web" %>
<%@ Import Namespace="System.Security.Cryptography.X509Certificates" %>
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">
  <title>Welcome to Sitecore</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta name="CODE_LANGUAGE" content="C#" />
  <meta name="vs_defaultClientScript" content="JavaScript" />
  <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5" />
  <link href="/default.css" rel="stylesheet" />
</head>
<script runat="server">
  protected void Button1_Click(object sender, EventArgs e)
  {
    var thumbprint = TextBox1.Text;
    X509Certificate x509Certificate = FindClientCertificate(StoreName.My, StoreLocation.LocalMachine, X509FindType.FindByThumbprint, thumbprint, false);
    if (x509Certificate != null)
    {
      Label1.Text = x509Certificate.Subject;
    } else
    {
      Label1.Text = "Cert not found";
    }
  }

  protected void Button2_Click(object sender, System.EventArgs e)
  {
    var thumbprint = TextBox1.Text;
    X509Certificate x509Certificate = FindClientCertificate(StoreName.My, StoreLocation.LocalMachine, X509FindType.FindByThumbprint, thumbprint, true);
    if (x509Certificate != null)
    {
      Label2.Text = x509Certificate.Subject;
    } else
    {
      Label2.Text = "Cert not found";
    }
  }

  private static X509Certificate FindClientCertificate(StoreName storeName, StoreLocation storeLocation, X509FindType findType, object findValue, bool allowInvalidClientCertificates)
  {
    X509Store x509Store = new X509Store(storeName, storeLocation);
    try
    {
      x509Store.Open(OpenFlags.ReadOnly);
      X509Certificate2Collection x509Certificate2Collection = x509Store.Certificates.Find(findType, findValue, !allowInvalidClientCertificates);
      return (x509Certificate2Collection.Count > 0) ? x509Certificate2Collection[0] : null;
    }
    finally
    {
      x509Store.Close();
    }
  }


</script>
<body>
  <form id="mainform" method="post" runat="server">
    <div id="MainPanel">
      <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
      <br />
      <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Get valid cert" />
      <asp:Label ID="Label1" runat="server" Text="Valid cert"></asp:Label>
      <br />
      <asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="Get any cert" />
      <asp:Label ID="Label2" runat="server" Text="Any cert"></asp:Label>
    </div>
  </form>
</body>
</html>

Browse to yoursite/CertTestOnPremise.aspx. Put in the thumbprint and click “Get Valid Cert”; this will tell you if the certificate is valid or not found.

If the cert is not found…

  1. Verify that the user running your Sitecore instance has proper permissions (see https://support.sitecore.com/kb?id=kb_article_view&sysparm_article=KB0719199 and jump to “2.1”)
  2. Run this command in Powershell to determine if the certificate is correctly installed:

Get-ChildItem -Path cert:\localmachine\my\{thumbprint}

If that command says the certificate does not exist, verify the following:

  1. start -> run -> mmc -> File -> Add/Remove Snap-in -> Certificates -> Add -> Computer Account -> Local Computer
  2. Double click into Certificates -> Personal
  3. Verify the certificate is there
  4. Double click the certificate -> Details
  5. Verify Thumbprint is the same as you were using in the previous steps

No comments:

Post a Comment