Java keystore certificate missing after Jenkins upgrade

Following a tricky upgrade to a Jenkins server it was found that the server was no longer able to communicate with the Git server, although SSH access with private keys was stil working correctly. On invrestigating the Jenkins logs (found at Logs at: http://YOUR-JENKINS-SERVER-URL/log/all) this error was found to be the problem:

Failed to login with creds MYCREDENTIALNAMEHERE
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
Caused: sun.security.validator.ValidatorException: PKIX path building failed
at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
Caused: javax.net.ssl.SSLHandshakeException

The problem here is that the Java runtime is not able to validate the connection as it doesnt have the relevant SSL certificate. To resolve I needed to download the certificate from the site and add it to the Java Keystore.

Photo by Chunlea Ju on Unsplash

On the server download the relevant web certificate for connecting to the relevant site (a GitHub server in my instance) that you are trying to access. Next find which Java JRE your Jenkins was using. This can be found in your Jenkins.xml file under the executable element. For example %BASE%\jre\bin\java means c:\Jenkins\JRE\bin\java if you have installed Jenkins to C:\Jenkins on Windows. Now find the cacerts file inside that Java runtime that it was using (for example C:\Jenkins\jre\lib\security\cacerts) where you will need to install the Certificate. To add the cert to the Java Keystore for that Java install run the below in a terminal:

keytool -import -alias INSERT_ALIAS_NAME_HERE -keystore PATH_TO_JRE_HERE\security\cacerts -file CERTIFICATE_FILE_NAME

for example…

keytool -import -alias ExampleName -keystore C:\Jenkins\jre\lib\security\cacerts -file exampleCertFile.cer

If you are asked for a password then it will be ‘changeit‘ by default.

Now the JRE Java runtime on the box that Jenkins is now using has the Certificate installed it will be able to make a SSL connection.

Advertisement

Jenkins: Script not permitted to use method signature

I’ve recently ran into an error in a Jenkins CI/CD pipeline when using java.util.Date objects in my Groovy script pipeline and so I’d thought I’d share the problem and workaround.

Problem

In order to create a date time and build number stamp into an output build package as part of a Jenkins build I made use of the java Date object in Groovy, something like this:

def date1 = new Date(1456533546)
def today = new Date()
def diff = (today-date1)

On running the build I get this error in the console log:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException:
Scripts not permitted to use staticMethod 
org.codehaus.groovy.runtime.DateGroovyMethods minus java.util.Date

It turns out that as the Groovy script jenkinsfile is running in the Groovy Sandbox in Jenkins it has a white-list of approved method signatures out of the box, but java.util.Date is not one of them.

Solution

If you add the Script Security Plugin to your Jenkins install, if its not there already, then you’ll be able to whitelist new methods and apis that can be used by the Jenkins pipeline scripts.

Log onto Jenkins as an Administrator and go to Manage Jenkins > In-process Script Approval and scroll to the bottom where the Script Security Plugin will have put new entries. Here you’ll find recent script permission failures and details.

options in Script Approval UI

Choosing to “Approve” the signature will then approve scripts to use this java signature (in this example the java.util.Date object) and the error should go away.

For more information see the official Jenkins docs here.

SonarQube migration issue- Jenkins Using old URL

I recently migrated a SonarQube server from one server to another in order to scale out the service to our dev team. All went well until builds failed due to them looking at both the old and new server URLs for the Sonar results and so I’m writing some notes here to help me (and others) out in the future if I hit this again.

I installed the same version of SonarQube on the new application server that is on the old server. The database was not being moved, just the application server (the server with the Sonar service running).

After installation I ensured that the same custom config settings were made onthe new server as had been made on the old server, and ensured that the same plugins were in place. I then stopped the Sonar service on the old server and started the service on the old box.

Once Sonar was confirmed to be up and running and connecting to the Database and showing the project dashboards I updated the Jenkins server configuration to point to the new box. All looked good so I ran a build, and then got this (log truncated)….

 
INFO: ANALYSIS SUCCESSFUL, you can browse http://OLDSERVER/dashboard?id=123
INFO: EXECUTION SUCCESS
The SonarQube Scanner has finished
Analysis results: http://NEWSERVER/dashboard/index/APP
Post-processing succeeded.
withSonarQubeEnv
waitForQualityGate
java.lang.IllegalStateException:
Fail to request http://OLDSERVER/api/ce/task?id=3423
at org.sonarqube.ws.client.HttpConnector.doCall(HttpConnector.java:212)

Bizarely the Jenkins build has managed to use both the new Sonar URL and the old one.The upload was successfull to the new server but some of the links for the resport point to the old server. Also the Quality Gate check whcih validates that the Sonar Quality Gate was successfull has tried to read the report on the OLD server and therefore failed as its not there (because its on the new sonar URL).

After checking Jenkins for any reference to the old Sonar server and restarting the service to clear any caches I was still getting the error. Eventually I ran a Jenkins build and interactively peeked into the Jenkins workspace on the Jenkins Slave and in there is an auto generated file containing lots of Sonar config settings. This file, SonarQubeAnalysisConfig.xml, is created during the Jenkins build initialisation stage. In the file I found references to the new Sonar URL but also this property pointing to the old URL:

  sonar.core.serverBaseURL  

This value is set in SonarQube configuration and is not dynamic and so will not be updated when you migrate the server or change the server URL/port. To change it open SonarQube > Administration > Configuration > General and change Server base URL to your new URL (e.g. http://yourhost.yourdomain/sonar). It says that this value is used to create links in emails etc but it in reality is also used to integate results.