How to setup HTTPS within Jetty

Introduction

The following concepts are needed to fully understand this article.

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 .pem above)
  • .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

  • You want to use a SSL certificate in your Jenkins server.
  • You want to have Jenkins using HTTPS with the Jetty container.

Environment

  • CloudBees Jenkins Enterprise
  • CloudBees Operation Center
  • Jenkins and the embedded Jetty HTTPS

Resolution

Jenkins is built with an internal web container called Jetty.
Jetty has the ability to serve HTTPS as one of the methods of authentication.

Note: At the time of writing this article, the jetty container currently does not support PKCS#8 format.
If you are using another format like PKCS#8 format it is required to convert the format for Jetty to understand.
If you already have the certificate in a different format, then it is safe to skip this step.
The first step is to convert the certificate file (crt) to a pem file:

openssl x509 -in jenkins-cert.crt -out jenkins-cert.pem -outform PEM

Once the certificate is converted to PEM, then the certificate should be converted to PKCS#12.
Note Please make sure to use a password. Having a certificate without a password throws exceptions later on.

openssl pkcs12 -inkey certificate.key -in jenkins-cert.pem -export -out jenkins-cert.p12

The next step is to create a Java Keystore.
In this part we will be creating an empty keystore.
The values used for the keystore can be anything as we will be deleting the certificate leaving it a blank keystore:
Note Please make sure to set a password for the keystore also.

keytool -genkey -alias jenkins -keystore jenkins.jks

Next step is to delete the certificate which was genearted from the above step:

keytool -delete -alias jenkins -keystore jenkins.jks

The final step is to take the certificate and import it into the java keystore.
This command will look different depending on the format of certificate:

keytool -v -importkeystore -srckeystore <SRC-CERTIFICATE.CRT> -srcstoretype <SRC-CERT-FORMAT> -destkeystore jenkins.jks -deststoretype JKS

An example using PKCS#12 keystore:

keytool -v -importkeystore -srckeystore jenkins.p12 -srcstoretype PKCS12 -destkeystore jenkins.jks -deststoretype JKS

The final step is to add the certificate to the list of Jenkins arguments. This will tell the jetty container which certificate to use. Depending on how Jenkins was installed, the JENKINS_ARGS variable needs to be altered to contain the following:

JENKINS_ARGS="--httpPort=-1 --httpsKeyStore=/path/to/keystore/jenkins.jks --httpsKeyStorePassword=changeit --httpsPort=443"

The httpPort=-1 will tell the jetty container to use https only. If you are switching from an already existing Jenkins instance using https it is recommended to leave the httpPort alone and play with the https port only. Once the Jenkins instance looks good rendering https then the http port can be set to -1.
The httpsKeySore and httpsKeyStorePassword are variables which were set when creating the empty keystore.
The httpsPort will tell the jetty container to use https on any port (no default value).

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.