The following concepts are needed to fully understand this article.
Intermediate Certificate
An intermediate certificate is a subordinate certificate issued by the trusted root specifically to issue end-entity server certificates. The result is a certificate chain known as Chained Root Certificates or Chain of Trust.
-
The client sends a request to the SSL server.
-
The server responds with the
IdentityandIntermediate certificates. -
The client confirms authenticity of the
Intermediate certificateby decrypting thedigital signatureusing theRoot CA public key. -
Next the client confirms the authenticity of the
Identity certificateby decrypting thedigital signatureusing theIntermediates public key. -
The client then clarifies that the URL that is being requested by matching the DN (Distinguished Name) within the
Identity Certificate. -
Traffic is then encrypted/decrypted by a) the client using the public key b) the server using the private key.
Filename extensions for X.509 certificates
Common filename extensions for X.509 certificates:
-
.pem— (Privacy-enhanced Electronic Mail) Base64 encoded DER certificate, enclosed between "----BEGIN CERTIFICATE----" and "----END CERTIFICATE----" -
.cer,.crt,.der— usually in binary DER form, but Base64-encoded certificates are common too (see.pemabove) -
.p7b,.p7c— PKCS#7 SignedData structure without data, just certificate(s) or CRL(s) -
.p12— PKCS#12, may contain certificate(s) (public) and private keys (password protected) -
.pfx— PFX, predecessor of PKCS#12 (usually contains data in PKCS#12 format, e.g., with PFX files generated in IIS)
On the other hand, .key is a file containing just the private-key of a specific certificate and is merely a conventional name and not a standardized one. It is .pem formatted.
Issue
-
Installing SSL certificate chains in Jetty.
-
How to publish Jenkins using HTTPS with an intermediate certificate.
-
The Chained Root Certificates or Chain of Trust is broken.
Environment
-
CloudBees Jenkins Enterprise
-
CloudBees Operation Center
-
Jenkins and the embedded Jetty HTTPS
Resolution
| If you do not have intermediate certificates, you can follow the simpler steps found in How do you set up HTTPS with CloudBees CI on traditional platforms?. |
Requirements:
-
An exiting SSL cert for Jenkins - As example,
$MYJENKINS.pfxbut other formats are also possible. -
Identity Certificatefiles also known as Domain Certificate -$IDENTITY.crt. -
Intermediate Certificateshould have the same class as your Domain Certificate -$INTERMEDIATE.crt. -
Root Certificate-$ROOT.crt
Notes:
-
Any of the certificates (2, 3 and 4) start with "`----BEGIN CERTIFICATE----"`. Please, make sure there is an end-of-line at the end of the file.
-
Certificates 3 and 4 should be available to download from your SSL Issuer.
Steps:
1. Extract the private key from your own SSL certificate into a .key file. By default, it is in .pem format so it needs to be converted into PKCS#12 because it is the format required by Jetty Winstone container.
openssl pkcs12 -nocerts -in $MYJENKINS.pfx -out $MYJENKINS.key
2. cat together all the certificates in the chain. Order is important.
cat $IDENTITY.crt $INTERMEDIATE.crt $ROOT.crt > $NAME.chain.txt
3. Combine certificates and private key into a .p12 file.
openssl pkcs12 -export -inkey $MYJENKINS.key -in $NAME.chain.txt -out $NAME.chain.p12
4. Finally, create a keystore containing it all. Make sure the keystore file does not already exist.
keytool -importkeystore -srckeystore $NAME.chain.p12 -srcstoretype PKCS12 -destkeystore $MYJENKINS.keystore
5. Test that the 3 certificates are included into the keystore
keytool -list -v -keystore "/path/to/$MYJENKINS.keystore"
A similar output like this should be displayed on the Terminal:
Keystore type: JKS Keystore provider: SUN Your keystore contains 1 entry Alias name: 1 Creation date: Jun 24, 2016 Entry type: PrivateKeyEntry Certificate chain length: 3 Certificate[1]: Owner: CN=*.$YOUR_DOMAIN.com, ... Issuer: CN=$YOUR_ISSUER Secure Certificate Authority ... ... Certificate[2]: Owner: CN=$YOUR_ISSUER Secure Certificate Authority ... Issuer: CN=$YOUR_ISSUER Root Certificate Authority .... ... Certificate[3]: Owner: CN=$YOUR_ISSUER Root Certificate Authority ... Issuer: CN=$YOUR_ISSUER Root Certificate Authority ... ...
Notes:
-
If you have set different Jenkins environments (for instance TEST, DEV and PROD), steps from 2 to 5 should be repeated in each of those environments.
-
The resulting
$MYJENKINS.keystorefile must then be copied to each of machines to the path specified by--httpsKeyStore=/path/to/$MYJENKINS.keystoreparameter of the Jenkins Arguments. -
The
--httpsKeyStorePassword=changeitparameter value is defined when creating the keystore file.
References
-
SSL certificate validation tool to check if The Chained Root Certificates or Chain of Trust is broken.