Issue
You want to add an SSL certificate ("certX") for the following cases:
-
non-trusted (self-signed) certificate
-
trusted certificate provided by CA that isn’t included in the default JRE
TrustStore
For several security features that you want to use over a secure connection. Some examples because you would need to add the mentioned certificate are:
-
Connecting to Jenkins a secure service (SSL/TLS). As an example an Active Directory or LDAP
-
Accessing Jenkins to a remote HTTPS resource
-
Configuring HTTPS for CloudBees Jenkins Enterprise via haproxy
This article describes the process to follow on non Kubernetes based installation, for Kubernetes based installations please refer to this article |
Resolution
A. Locate "certX" (optional)
In most cases, please reach out to your operations team for the necessary "certX" files.
If configuring HA and you need to download the SSL server certificate (CloudBees Jenkins Operations Center, haproxy virtual machine, etc), use a tool such as:
-
openssl
> openssl s_client -connect <SERVER_HOSTNAME>:443
-
keytool
> keytool -printcert -rfc -sslServer <SERVER_HOSTNAME>
-
gnutls-cli
> gnutls-cli --print-cert --insecure <SERVER_HOSTNAME>
Embedded in the response is the certificate identifiable by the fragment starting with -----BEGIN CERTIFICATE----- and ending with -----END CERTIFICATE----- . Store the certificate in a file "path/to/<YOUR_CA_FILE>.pem", including -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- .
|
Example
> openssl s_client -connect www.example.com:443
CONNECTED(00000003)
depth=1 /C=US/O=GeoTrust Inc./CN=GeoTrust SSL CA - G3
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=California/L=San Francisco/O=Example Technologies, Inc/CN=*.example.com
...
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIE7jCCA9agAwIBAgIQJ85dBpYNN5a56Pa7AA0t6TANBgkqhkiG9w0BAQsFADBE
...
ggLk2IYTdtzZsxYK96maAwmg
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=San Francisco/O=Example Technologies, Inc/CN=*.example.com
issuer=/C=US/O=GeoTrust Inc./CN=GeoTrust SSL CA - G3
---
No client certificate CA names sent
---
SSL handshake has read 2513 bytes and written 456 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
...
---
closed
Best practice: Download the certificate, transform to an x509 format and then save it to a file
For instance, using openssl
tool on Unix and saving it into PEM format would be like:
openssl s_client -showcerts -connect www.example.com:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > /opt/Labs/resources/certs/example.com.pem
B. Adding "certX" to the TrustStore
To use "certX", you have several options:
-
Adding it to a fresh
TrustStore
-
Adding it to a copy of an existing
TrustStore
-
Adding it to the existing
TrustStore
By default, Java Applications (as Jenkins) make use of the JVM TrustStore
. If a Java Application needs to make use of a custom TrustStore
, it needs to be configured to be able to do so.
Notes:
-
Default password of the JVM
TrustStore
ischangeit
(orchangeme
). -
Modifications on the
TrustStore
will be deleted on every JVM update.
Best practice: Option 2. of the JVM TrustStore
for the following reasons:
-
Your
TrustStore
would contains certificates trusted by your JVM. -
Certificates needed by Jenkins would be stored into a single place.
-
In case of JVM update, your
TrustStore
would not be overridden.
Procedure
For the following steps we assume the following points:
-
You have a "certX" located and available
-
This
TrustStore
is custom and it is created by copying the existing JVMTrustStore
into a new location withinJENKINS_HOME
, including a new cert ("certX") -
This
TrustStore
is not included yet intoJENKINS_JAVA_ARGS
-
JENKINS_HOME
andJAVA_HOME
env variables need to be defined
1. Create a custom TrustStore from the JVM TrustStore
Once you have logged with the jenkins
user:
-
For Unix:
CUSTOM_TrustStore=$JENKINS_HOME/.cacerts/ mkdir -p $CUSTOM_TrustStore cp $JAVA_HOME/jre/lib/security/cacerts $CUSTOM_TrustStore
-
For Windows:
CUSTOM_TrustStore=%JENKINS_HOME%\.cacerts\ md %CUSTOM_TrustStore% copy %JAVA_HOME%\jre\lib\security\cacerts %CUSTOM_TrustStore%
2. Import your certificate:
-
For Unix:
$JAVA_HOME/bin/keytool -keystore $JENKINS_HOME/.cacerts/cacerts \ -import -alias <YOUR_ALIAS_HERE> -file <YOUR_CA_FILE>
-
For Windows:
%JAVA_HOME%\bin\keytool -keystore %JENKINS_HOME%\.cacerts\cacerts -import -alias <YOUR_ALIAS_HERE> -file <YOUR_CA_FILE>
Note:
-
At this point, you will be asked for the TrustStore password.
-
When prompted
Trust this certificate? [no]:
enteryes
to confirm the key import:
3. Add the certificate to the Jenkins startup parameters:
The following JAVA properties should be added depending on your OS:
-
For Unix:
-Djavax.net.ssl.trustStore=$JENKINS_HOME/.cacerts/cacerts \ -Djavax.net.ssl.trustStorePassword=changeit
-
For Windows:
-Djavax.net.ssl.trustStore=%JENKINS_HOME%\.cacerts\cacerts -Djavax.net.ssl.trustStorePassword=changeit
Follow instructions on How to add Java arguments to Jenkins for your particular case.
4. You must restart Jenkins for the parameters to take effect.
Import certificates in Linux OS
In some cases we also need to import the certificate in the OS to use it with tools like curl
, git
, etc. To import the certificate, follow the steps below based on your Linux distribution.
Ubuntu
-
Obtain the server certificate and the certificates chain need to import (in PEM format)
-
Copy your certificates in
/usr/share/ca-certificates
directory -
Update your certificates running the command
sudo update-ca-certificates --fresh
sudo openssl s_client -showcerts -connect server.example.com:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > /tmp/server_example_com.pem sudo cp /tmp/server_example_com.pem /usr/share/ca-certificates/server_example_com.pem sudo update-ca-certificates
RHEL/CentOS
-
Obtain the server certificate and the certificates chain need to import (in PEM format)
-
Copy your certificates in
/etc/pki/ca-trust/source/anchors/
-
Update your certificates running the command
sudo update-ca-trust extract
-
On RHEL6 you also have to enable the CAs
sudo update-ca-trust enable
sudo openssl s_client -showcerts -connect server.example.com:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > /tmp/server_example_com.pem sudo cp /tmp/server_example_com.pem /etc/pki/ca-trust/source/anchors/server_example_com.pem sudo update-ca-trust extract sudo update-ca-trust enable