Jeremy Davis
Jeremy Davis
Sitecore, C# and web development
Article printed from: https://blog.jermdavis.dev/posts/2021/revising-that-old-solr-install-script

Revising that old Solr install script

Published 12 April 2021
PowerShell Solr ~1 min. read

With all the excitement about containers and SaaS and the like, it's been a while since I've spent time worrying about local Solr installs. But recently my good pal low-effort Solr Installs" script doesn't work with recent Solr releases. So I figured I should fix that, because it's clearly still useful for some people...

The issue:

Corey pointed out that in Solr 8.8.0 the defaults in the solr.in.cmd config file have changed. When I originally wrote the script, the commented-out lines describing the location of the SSL key file looked like this:

REM Be sure to update the paths to the correct keystore for your environment
REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks
REM set SOLR_SSL_KEY_STORE_PASSWORD=secret
REM set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.jks
REM set SOLR_SSL_TRUST_STORE_PASSWORD=secret

					

But with v8.8.0 this file has changed to:

REM Be sure to update the paths to the correct keystore for your environment
REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.p12
REM set SOLR_SSL_KEY_STORE_PASSWORD=secret
REM set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.p12
REM set SOLR_SSL_TRUST_STORE_PASSWORD=secret

					

It's a small difference, but the file extension for the keystore file has changed from .jks to .p12. And that breaks my script because when I re-wrote these lines to configure Solr with the SSL certificate file it generates, I used an exact match:

$newCfg = $cfg | % { $_ -replace "REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks", "set SOLR_SSL_KEY_STORE=$certStore" }

					

So as Corey points out, this doesn't work if you've moved to Solr v8.8...

Fixing it:

Having sat and thought about this, the fix is pretty simple really: When you use -replace in PowerShell, it's actually expecting a regular expression. When I first wrote this I'd not been expecting any variations, but it's easy enough to account for them with some regex... So if we want to find "either .jks or .p12" we can change that replace statement to:

$newCfg = $cfg | % { $_ -replace "REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore\.(jks|p12)", "set SOLR_SSL_KEY_STORE=$certStore" }

					

(side issue – clearly I wasn't thinking about the regular expressions here when I wrote the original scrip, since it didn't escape the . in the path... So I've fixed that here too)

And that should work with both versions of the config file.

While I was investigating this, I noticed another bug: The replacement in this operation uses a PowerShell variable $certStore to inject the location of the SSL certificate file. But if you look at the code, it's possible that this variable doesn't get initialised. It gets set by this code:

    # export the cert to pfx using solr's default password
    if(!(Test-Path -Path "$solrRoot\server\etc\solr-ssl.keystore.pfx"))
    {
        Write-Host "Exporting cert for Solr to use"

        $cert = Get-ChildItem Cert:\LocalMachine\Root | where FriendlyName -eq "$solrName"
    
        $certStore = "$solrRoot\server\etc\solr-ssl.keystore.pfx"
        $certPwd = ConvertTo-SecureString -String "secret" -Force -AsPlainText
        $cert | Export-PfxCertificate -FilePath $certStore -Password $certpwd | Out-Null
    }

					

But that code only runs if the .pfx file does not exist. If it does, this initialisation never happens... Ooops.

It would be better to re-arrange this code slightly to:

    $certStore = "$solrRoot\server\etc\solr-ssl.keystore.pfx"

    # export the cert to pfx using solr's default password
    if(!(Test-Path -Path "$solrRoot\server\etc\solr-ssl.keystore.pfx"))
    {
        Write-Host "Exporting cert for Solr to use"

        $cert = Get-ChildItem Cert:\LocalMachine\Root | where FriendlyName -eq "$solrName"
    
        $certPwd = ConvertTo-SecureString -String "secret" -Force -AsPlainText
        $cert | Export-PfxCertificate -FilePath $certStore -Password $certpwd | Out-Null
    }

					

That way the variable is always initialised.

And running a test with those changes seems to work, as Solr v8.8 fires up with SSL working:

Solr v8

So the gist for this is updated – hopefully it'll keep it useful for a bit longer... (I've also updated the gist for doing this via SIF and the repo for my SolrCloud install scripts)

↑ Back to top