Jerzy Suzanowicz

I work mostly with Java, AngularJs, ReactJs, Docker, GKE, K8s, OpenShift.

Use Let’s Encrypt SSL Certificates on OpenShift 4.x Ingress / Routes

21 May 2023 » openshift, okd

In Red Hat OpenShift Container Platform, Certificates are used to encrypt communications to the applications exposed using Routes/Ingress as well as Web Console access. When deploying OpenShift Container Platform, the installer will automatically generate self-signed certificates which are configured for cluster use without any further customizations. While using self-signed certificates, you’ll often see security warnings about unknown certificates in most web browsers when accessing the Web Console or any application exposed via HTTPS.

It is recommended to use proper certificates, signed by a known CA to encrypt the API endpoints and applications exposed on routes. Let’s Encrypt is one viable option towards getting secure Certificates for free, the beauty of open source!. I’m running an OpenShift 4.8 cluster in my Lab environment. In OpenShift 4.x, the process of updating or changing self-signed certificates generated and the time of cluster setup has been simplified and is reasonably straightforward.

In this article we walk you through the process of getting Let’s Encrypt SSL Certificates and using it in an OpenShift 4.x cluster. The main requirements for this setup are:

  • A running OpenShift / OKD 4.x Cluster
  • API endpoint URL (Example – api.ocp4.example.com)
  • Ingress Controller Wildcard Domain (Example – apps.ocp4.example.com)
  • Access to OpenShift Cluster with oc as admin user

Step 1: Download acme.sh Project Code

We’ll use the acme.sh client tool to request for Let’s Encrypt certificates on our Bastion machine. The ACME protocol client is written purely in Shell (Unix shell) language with no dependencies on python. It has support for SAN and wildcard certificates. In fact, we will request Wildcard Let’s Encrypt certificates for our Ingress Controller Wildcard Domain.

Clone the acme.sh GitHub repository.

cd ~/
git clone https://github.com/acmesh-official/acme.sh.git

Change your current working directory to acme.sh:

cd acme.sh

Step 2: Configure DNS API / CNAME on your DNS Provider

Since we will be requesting for a Wildcard certificate, there is a need to get your DNS API credentials for automated certificates generation with acme.sh.

Requesting Let’s Encrypt Certificates

Make sure you’re logged in to Red Hat OpenShift Cluster as a user with cluster administrator permissions

$ oc whoami
system:admin

Obtain OpenShift API Endpoint fully qualified domain name and set to variable OCP_API_DOMAIN:

export OCP_API_DOMAIN=$(oc whoami --show-server | cut -f 2 -d ':' | cut -f 3 -d '/' | sed 's/-api././')
echo $OCP_API_DOMAIN

Obtain OpenShift configured Wildcard Domain and save in a variable OCP_WILDCARD_DOMAIN:

export OCP_WILDCARD_DOMAIN=$(oc get ingresscontroller default -n openshift-ingress-operator -o jsonpath='{.status.domain}')
echo $OCP_WILDCARD_DOMAIN

Create a directory where generated certificates will be saved:

export CERTDIR=$HOME/openshift_certificates
mkdir -p ${CERTDIR}

Register account with acme while replacing your_email_address@example.com with your email address.

$ ~/acme.sh/acme.sh --register-account -m your_email_address@example.com

Next step is generating Let’s Encrypt SSL certificates with google dns provider:

${HOME}/acme.sh/acme.sh --issue --dns dns_gcloud -d ${OCP_API_DOMAIN} -d *.${OCP_WILDCARD_DOMAIN} --debug

Let’s save the certs in the directory we created.

${HOME}/acme.sh/acme.sh --install-cert -d ${OCP_API_DOMAIN} -d *.${OCP_WILDCARD_DOMAIN} --cert-file ${CERTDIR}/cert.pem --key-file ${CERTDIR}/key.pem --fullchain-file ${CERTDIR}/fullchain.pem --ca-file ${CERTDIR}/ca.cer

Step 3: Install Let’s Encrypt Certificates to OpenShift Ingress Controller

OpenShift Ingress Controller consumes certificates stored in a secret object. The secret should be created in the openshift-ingress namespace.

Create a secret in the openshift-ingress project:

oc -n openshift-ingress create secret tls router-certs --cert=${CERTDIR}/fullchain.pem --key=${CERTDIR}/key.pem

Secret creation output:

secret/router-certs created

Thereafter we update the Custom Resource for the ingress controller located in the openshift-ingress-operator project and named default:

$ oc get ingresscontroller -n openshift-ingress-operator
NAME      AGE
default   2d6h

Update the custom resource by running the command below:

oc -n openshift-ingress-operator patch ingresscontroller default  --type=merge --patch='{"spec": { "defaultCertificate": { "name": "router-certs" }}}'

Command expected output:

ingresscontroller.operator.openshift.io/default patched

Router pods in the openshift-ingress should be restarted automatically in a short while:

$ oc get pods -n openshift-ingress
NAME                              READY   STATUS    RESTARTS   AGE
router-default-7b7d5bb68f-4lzft   1/1     Running   0          2m11s
router-default-7b7d5bb68f-x44lb   1/1     Running   0          2m49s

We now have generated Let’s Encrypt SSL certificates applied on the Ingress router. The certificates also used by the applications exposed using the default route and Red Hat OpenShift Cluster Web Console and other services such as the Monitoring stack.

Cert PICTURE from browser

Step 4: Installing Certificates to the Red Hat OpenShift API Endpoint (Optional)

You can also apply the certificates in API Endpoint.

The OpenShift API Server also expects the certificates in a Secret. We should create the certificates secret in the openshift-config project.

$ oc get secret -n openshift-config
NAME                                      TYPE                                  DATA   AGE
builder-dockercfg-nxjhg                   kubernetes.io/dockercfg               1      2d6h
builder-token-mc5fj                       kubernetes.io/service-account-token   4      2d6h
builder-token-wd9nc                       kubernetes.io/service-account-token   4      2d6h
default-dockercfg-t7h6m                   kubernetes.io/dockercfg               1      2d6h
default-token-4vsjs                       kubernetes.io/service-account-token   4      2d6h
default-token-gsmt9                       kubernetes.io/service-account-token   4      2d6h
deployer-dockercfg-hmfmz                  kubernetes.io/dockercfg               1      2d6h
deployer-token-b9t58                      kubernetes.io/service-account-token   4      2d6h
deployer-token-khbdh                      kubernetes.io/service-account-token   4      2d6h
etcd-client                               kubernetes.io/tls                     2      2d6h
etcd-metric-client                        kubernetes.io/tls                     2      2d6h
etcd-metric-signer                        kubernetes.io/tls                     2      2d6h
etcd-signer                               kubernetes.io/tls                     2      2d6h
initial-service-account-private-key       Opaque                                1      2d6h
pull-secret                               kubernetes.io/dockerconfigjson        1      2d6h
webhook-authentication-integrated-oauth   Opaque                                1      2d6h

Create a secret named api-certs

oc -n openshift-config create secret tls api-certs --cert=${CERTDIR}/fullchain.pem --key=${CERTDIR}/key.pem

Confirm that the secret is created successfully:

secret/api-certs created

Run the command below to apply the certs on API endpoint

oc patch apiserver cluster --type merge --patch="{\"spec\": {\"servingCerts\": {\"namedCertificates\": [ { \"names\": [  \"$OCP_API_DOMAIN\"  ], \"servingCertificate\": {\"name\": \"api-certs\" }}]}}}"

How to renew the certificates generated

You’re not required to renew the certs manually since they will be renewed automatically every 60 days.

However, you can also force to renew a cert:

export OCP_API_DOMAIN=$(oc whoami --show-server | cut -f 2 -d ':' | cut -f 3 -d '/' | sed 's/-api././')
export OCP_WILDCARD_DOMAIN=$(oc get ingresscontroller default -n openshift-ingress-operator -o jsonpath='{.status.domain}')
~/acme.sh/acme.sh --renew -d ${OCP_API_DOMAIN} -d *.${OCP_WILDCARD_DOMAIN} --force

https://computingforgeeks.com/use-lets-encrypt-wildcard-certificates-on-openshift-ingress-routes/