How to setup HTTPS within Jetty?

Article ID:219001547
2 minute readKnowledge base

Issue

  • You want to use an 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

  • Jenkins Docker container

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.

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.
  1. 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
  2. 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
  3. 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
  4. Delete the certificate which was generated from the above step:

     keytool -delete -alias jenkins -keystore jenkins.jks
  5. 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-cert.p12 -srcstoretype PKCS12 -destkeystore jenkins.jks -deststoretype JKS

    If you are running Jenkins in a Docker container it is recommended that you use a Docker volume or bind mount for the directory that the keystore is located in. This way the certificate won’t have to be copied into each container and all containers can share the same certificate.

  6. 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 httpsKeyStore 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).

    If you are running Jenkins in a Docker container you will want to add the JENKINS_ARGS to the docker run command. For example:

     docker run -p 443:443 --env JENKINS_ARGS="--httpPort=-1 --httpsKeyStore=/path/to/keystore/jenkins.jks --httpsKeyStorePassword=changeit --httpsPort=443" <JENKINS_IMAGE>

    The -p 443:443 option will publish the containers 443 port to the hosts 443 port. The --env option will set environment variables inside the docker container. In this case, that would be the JENKINS_ARGS environment variable.

References