Backstory

Recently during a support incident, we encountered a proxy configuration that we had yet to see when using Jenkins. In this particular instance, web traffic using ssl (HTTPS) was being intercepted, and a Trusted Root certificate provided by the Proxy Server handed to the browser. This configuration was causing Jenkins to be unable to use the proxy server, as the cacert file Jenkins uses was blissfully unaware of the existence of those Trusted Root certificates.

The fix

In order to overcome this issue the following steps were taken:

  1. Shut down the Jenkins service with Stop-Service jenkins
  2. Export the Trusted Root certificates from the LocalMachine certificate store to .cer files
  3. Use keytool to import the Trusted Root certificates into the Java cacert file.
  4. Start the Jenkins service with Start-Service jenkins

Code

The following PowerShell script does all of the heavy lifting to quickly overcome this issue:

[CmdletBinding()]
Param(
    [Parameter()]
    [String]
    $ExportPath = 'C:\certs',

    [Parameter(Mandatory=$true)]
    [String]
    $CertificateSubjectFilter
)

begin {
    if(-not (Get-Command keytool)){
        throw "keytool is required for this script to work"
    }

    if(-not (Test-Path $ExportPath)){
        $null = New-Item $ExportPath -ItemType Directory
    }
}

process {

    #Use a counter to increment
    $counter = 1
    Get-ChildItem Cert:\LocalMachine\Root |
    Where-Object { $_.Subject -match "CN=$CertificateSubjectFilter*" } |
    Foreach-Object {
        Export-Certificate -Cert $_ -Type CERT -FilePath "$ExportPath\$($_.Thumbprint)_$counter.cer"
        $counter++
    }

    Get-ChildItem $ExportPath -Filter *.cer |
    Foreach-Object {
        keytool -import -trustcacerts -alias $($_.BaseName) -keystore 'C:\Program Files (x86)\jenkins\jre\lib\security\cacerts' -file $($_.Fullname) -noprompt -storepass changeit
        
    }

}

comments powered by Disqus