OpenShift 4 route with TLS secret and Cert Utils Operator

Oren Oichman
4 min readJan 2, 2022

TLS and Secrets

In Today modern world running application without TLS is on the verge of forbidden. All web application must run their front end with some time of TLS termination. Running Web application on OpenShift is no different and on OpenShift we have several options.

TLS Termination

When Running Application on top of OpenShift we are being provided with several option of running the application with TLS.
The first option is writing the application which uses the TLS library and start the session with the TLS certificates.
The second option is implementing an external load balancer which enables TLS termination. That will create a traffic which is secure between the customer and the Load Balancer but between the Load Balancer and OpenShift all the communication will be clear text.
the third option (which is our subject today) is to creating an OpenShift route that implements TLS termination.

What’s has changed ?

Until now we’ve created a route and added the Certificate + key (and the CA) in a clear text why to the route resource. Today we are going to see another way which is to create a secret and have that attached to the route automatically instead of adding it in clear text.

Why ?

By using the secret method we can protect our secret and key for example in our GIT repository when we store our route in a declarative manner by just stating the secret reference instead of providing the full certificate. more so we can create an automatic certificate rotation (for example in a letsencrypt scenario when we need a new certificate every 3 month) by just updating the secret and the route will be update automatically.
The way we implement this process is by adding a community version operator of the “Cert Util Operator” which takes care of the process for us.

Steps …

First the hole process is based on the cert util operator so we need to deploy it. In Openshift we will use OLM and deploy it from the operatorHUB.

The operator

First let’s create a new namespace :

# oc new-project cert-utils-operator

Prometheus compatible metrics are exposed by the Operator and can be integrated into OpenShift’s default cluster monitoring. To enable OpenShift cluster monitoring, label the namespace the operator is deployed in with the label openshift.io/cluster-monitoring="true"

# oc label namespace cert-utils-operator openshift.io/cluster-monitoring="true"

To deploy the operator we will need to create the following file :

# cat > cert-util-operator.yaml << EOF
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: cert-utils-operator
spec:
channel: alpha
installPlanApproval: Automatic
name: cert-utils-operator
source: community-operators
sourceNamespace: openshift-marketplace
---
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
name: cert-utils-operator
spec:
targetNamespaces: []
EOF

Now let’s deploy the subscription :

# oc apply -f cert-util-operator.yaml -n cert-utils-operator

This will create the appropriate OperatorGroup and Subscription and will trigger OLM to launch the operator in the specified namespace.

The route

First we need to create a secret in “tls” type. This document already assume that you have created a certificate request and key , signed the certificate with your Organization CA and obtain the certificate.

# oc create secret tls route-tls --key=route.key --cert=route.crt

Now let’s create the route to a YAML file:

# oc create route edge <route name> --service=<service> --port=<port> --insecure-policy=Redirect --dry-run=client -o yaml > route.yaml

Now let’s edit our newly created file. for edit the YAML file we can use a tool named yq and there is an image we can use (or just download the binary).

To download yq you can visit the link here . or build a container image with the yq binary.

Building the yq image

in order to build the image all we need is to create the following Containerfile which will download the yq command and add it to a UBI8 minimal image :

# cat > Containerfile << EOF
FROM ubi8/ubi AS builder
WORKDIR /opt/app-root/
RUN dnf install -y tar wget
RUN wget https://github.com/mikefarah/yq/releases/download/v4.16.2/yq_linux_amd64.tar.gz && \
tar -zxvf yq_linux_amd64.tar.gz
FROM ubi8/ubi-minimal
COPY --from=builder /opt/app-root/yq_linux_amd64 /usr/bin/yq
RUN mkdir /workdir
WORKDIR /workdir
RUN chown -R 1001:1001 /workdir
USER 1001
CMD ["/usr/bin/yq"]
ENTRYPOINT ["/usr/bin/yq"]
EOF

And build the image :

# buildah bud -f Containerfile -t ubi8/yq

For using the image we need to add the following function to our .bashrc file :

# echo 'yq() {
podman run --rm -i -v "${PWD}":/workdir:z ubi8/yq "$@"
}' >> ~/.bashrc

note!
If you are in a disconnected environment I strongly recommend download the binary/image to your environment.This tool is useful for many thinks (A relevant tutorial will be provided in the future).

And source the file :

# source ~/.bashrc

Now we can use the yq command to add the annotation to the route file :

# yq eval '.metadata.annotations += {"cert-utils-operator.redhat-cop.io/certs-from-secret": "route-tls"}' route.yaml > route-tls.yaml

And Apply our newly created file :

# oc apply -f route-tls.yaml

From this point and forward every time we will update the secret the the route will get updated.

We can view our new route with TLS with the following command :

# oc get route <route name> -o yaml

That’s it.

If you have any question feel free to responed/ leave a comment.
You can find on linkedin at : https://www.linkedin.com/in/orenoichman
Or twitter at : https://twitter.com/ooichman

--

--