Skip to content

Commit

Permalink
SRVKE-1520: Add transport-encryption documentation (#107)
Browse files Browse the repository at this point in the history
Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>
  • Loading branch information
pierDipi authored Mar 14, 2024
1 parent 0d8c6e2 commit b26cbd2
Show file tree
Hide file tree
Showing 3 changed files with 305 additions and 0 deletions.
1 change: 1 addition & 0 deletions antora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ asciidoc:
product-title: OpenShift
ocp: OpenShift Container Platform
serverlessoperatorname: OpenShift Serverless Operator
certmanageroperatorname: OpenShift Cert-Manager Operator
serverlessproductname: OpenShift Serverless
product_name: OpenShift Serverless Logic
kogito_version_redhat: 1.44.0.Final-redhat-00005
Expand Down
2 changes: 2 additions & 0 deletions modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*** xref:serverless:service-mesh/common-service-mesh-network-isolation.adoc[Use Service Mesh to isolate network-traffic]
*** xref:serverless:service-mesh/eventing-service-mesh-containersource.adoc[Eventing: Using ContainerSource with OpenShift Service Mesh]
*** xref:serverless:service-mesh/eventing-service-mesh-sinkbinding.adoc[Eventing: Using SinkBinding with OpenShift Service Mesh]
** Features
*** xref:serverless:features/transport-encryption/transport-encryption-setup.adoc[Setup transport encryption in Eventing]
** Serving
*** xref:serverless:serving/serving-with-ingress-sharding.adoc[Use Serving with OpenShift ingress sharding]
*** xref:serverless:serving/scaleability-and-performance-of-serving.adoc[Scalability and performance of {serverlessproductname} Serving]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
= Setup transport encryption in Eventing
:compat-mode!:
// Metadata:
:description: Setup {serverlessproductname} transport encryption for Eventing

This page describes the transport encryption feature which allows transporting data and events over secured and encrypted HTTPS connections using TLS.

[IMPORTANT]
====
{serverlessproductname} transport encryption for Eventing is a Developer Preview feature only.
Developer Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete.
Red Hat does not recommend using them in production.
These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
For more information about the support scope of Red Hat Developer Preview features, see https://access.redhat.com/support/offerings/devpreview/.
====

== Prerequisites

* You have access to an {product-title} account with cluster administrator access.

* Install the OpenShift CLI (`oc`).

* Install the {serverlessoperatorname}.

* Install the {certmanageroperatorname}.

== Setup a `SelfSigned` `ClusterIssuer` [[setup_selfsigned_clusterissuer]]

[INFO]
====
`ClusterIssuers`, are Kubernetes resources that represent certificate authorities (CAs) that are able to generate signed certificates by honoring certificate signing requests.
All cert-manager certificates require a referenced issuer that is in a ready condition to attempt to honor the request. +
Reference: https://cert-manager.io/docs/concepts/issuer/
====

[IMPORTANT]
====
For the simplicity of this guide, we will use a `SelfSigned` issuer as root certificate, however, be aware of the implications and limitations as documented at https://cert-manager.io/docs/configuration/selfsigned/ of this method. +
If you're running your company specific Private Key Infrastructure (PKI), we recommend the CA issuer.
Refer to the cert-manager documentation for more details: https://cert-manager.io/docs/configuration/ca/, however, you can use any other issuer that is usable for cluster-local services.
====

. Create a `SelfSigned` `ClusterIssuer`:
+
[source,yaml]
----
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: knative-eventing-selfsigned-issuer
spec:
selfSigned: {}
----
+
. Apply the `ClusterIssuer` resource:
+
[source,terminal]
----
$ oc apply -f <filename>
----

. Create a root certificate using the previously created `SelfSigned` `ClusterIssuer`:
+
[source,yaml]
----
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: knative-eventing-selfsigned-ca
namespace: cert-manager <1>
spec:
secretName: knative-eventing-ca <2>
isCA: true
commonName: selfsigned-ca
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: knative-eventing-selfsigned-issuer
kind: ClusterIssuer
group: cert-manager.io
----
+
<1> The {certmanageroperatorname} namespace, `cert-manager` by default.
<2> Secret name later used for the `ClusterIssuer` for Eventing
+
. Apply the `Certificate` resource:
+
[source,terminal]
----
$ oc apply -f <filename>
----

== Setup `ClusterIssuer` for Eventing

. Create the `knative-eventing-ca-issuer` `ClusterIssuer` for Eventing:
+
[source,yaml]
----
# This is the issuer that every Eventing component should use to issue their server's certs.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: knative-eventing-ca-issuer
spec:
ca:
secretName: knative-eventing-ca <1>
----
+
<1> Secret name in the {certmanageroperatorname} namespace (`cert-manager` by default) containing the certificate that can then be used by Knative Eventing components for new certificates.
+
[IMPORTANT]
====
The name of the `ClusterIssuer` must be `knative-eventing-ca-issuer`.
====
+
. Apply the `ClusterIssuer` resource:
+
[source,terminal]
----
$ oc apply -f <filename>
----

== Understanding the transport encryption configuration

The transport-encryption feature flag is an enum configuration that configures how Addressables (Broker, Channel, Sink) should or must accept events.

The possible values for `transport-encryption` are:

* *`disabled`* (this is equivalent to the current behavior)
** Addressables may accept events to HTTPS endpoints
** Producers may send events to HTTPS endpoints
* *`permissive`*
** Addressables should accept events on both HTTP and HTTPS endpoints
** Addressables should advertise both HTTP and HTTPS endpoints
** Producers should prefer sending events to HTTPS endpoints, if available
* *`strict`*
** Addressables must not accept events to non-HTTPS endpoints
** Addressables must only advertise HTTPS endpoints

== Setup transport encryption in `KnativeEventing`

. Enabling transport-encryption in `KnativeEventing`:
+
[source,yaml]
----
apiVersion: operator.knative.dev/v1beta1
kind: KnativeEventing
metadata:
name: knative-eventing
namespace: knative-eventing
spec:
# Other spec fields omitted ...
# ...
config:
features:
transport-encryption: strict <1>
----
+
<1> Configure `transport-encryption` to `strict`.

. Apply the `KnativeEventing` resource:
+
[source,terminal]
----
$ oc apply -f <filename>
----

== Configure additional CA trust bundles [[configure_addition_ca_trust_bundles]]

By default, Eventing clients trusts the OpenShift CA bundle that you have configured when using a custom PKI for OpenShift, as documented at https://docs.openshift.com/container-platform/4.14/networking/configuring-a-custom-pki.html.

If you need to add additional CA bundles for Eventing, you can do so by creating `ConfigMaps` in the `knative-eventing` namespace with label `networking.knative.dev/trust-bundle: true`:

[IMPORTANT]
====
Whenever CA bundles `ConfigMaps` are updated, the Eventing clients will automatically add them to their trusted CA bundles when a new connection is established.
====

. Create a CA bundle for Eventing:

[source,yaml]
----
kind: ConfigMap
metadata:
name: my-org-eventing-bundle <1>
namespace: knative-eventing
labels:
networking.knative.dev/trust-bundle: "true"
data: <2>
ca.crt: ...
ca1.crt: ...
tls.crt: ...
----

<1> Use a name that is unlikely to conflict with existing or future Eventing `ConfigMap`.
<2> All keys containing valid PEM-encoded CA bundles will be trusted by Eventing clients.

=== Configure custom event sources to trust the Eventing CA

The recommended way of creating custom event sources is using a SinkBinding, SinkBinding will inject the configured CA trust bundles as projected volume into each container using the directory `/knative-custom-certs`.

[INFO]
====
Some organizations might inject company specific CA trust bundles into base container images and automatically configure runtimes (openjdk, node, etc) to trust that CA bundle. +
In that case, you might not need to configure your clients.
====

Using the previous example of the `my-org-eventing-bundle` `ConfigMap` with data keys being `ca.crt`, `ca1.crt` and `tls.crt`, you will have a `/knative-custom-certs` directory that will have the following layout:

[source,terminal]
----
/knative-custom-certs/ca.crt
/knative-custom-certs/ca1.crt
/knative-custom-certs/tls.crt
----

Those files can then be used to add CA trust bundles to HTTP clients sending events to Eventing.

[INFO]
====
Depending on the runtime, programming language or library that you're using, there are different ways of configuring custom CA certs files using command line flags, environment variables, or by reading the content of those files. +
Refer to their documentation for more details.
====

== Adding `SelfSigned` `ClusterIssuer` to CA trust bundles

In case you are using a `SelfSigned` `ClusterIssuer` as described in the <<setup_selfsigned_clusterissuer>> section, you can add the CA to the Eventing CA trust bundles by running the following commands:

. Export the CA from the `knative-eventing-ca` secret in the {certmanageroperatorname} namespace, `cert-manager` by default:
+
[source,terminal]
----
$ oc get secret -n cert-manager knative-eventing-ca -o=jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt
----
. Create a CA trust bundle in the `knative-eventing` namespace:
+
[source,terminal]
----
$ oc create configmap -n knative-eventing my-org-selfsigned-ca-bundle --from-file=ca.crt
----
. Label the `ConfigMap` with `networking.knative.dev/trust-bundle: "true"` label:
+
[source,terminal]
----
$ oc label configmap -n knative-eventing my-org-selfsigned-ca-bundle networking.knative.dev/trust-bundle=true
----

== Ensure seamless CA rotation

Ensuring seamless CA rotation is essential to avoid service downtime, or to deal with an emergency.
The following procedure explains how you can seamlessly rotate a CA.

. Create a new CA certificate.
. Add the public key of the new CA certificate to the CA trust bundles as described in the <<configure_addition_ca_trust_bundles>> section. +
Make sure to also keep the public key of the existing CA.
. Ensure that all clients have consumed the latest set of CA trust bundles. +
Knative Eventing components will automatically reload the changed CA trust bundles.
If you have custom workload consuming trust bundles as well, make sure to reload/restart them accordingly.
. Update the `knative-eventing-ca-issuer` `ClusterIssuer` to reference the secret containing the CA certificate created at step 1.
. Force cert-manager to renew certificates in the `knative-eventing` namespace. +
Refer to the cert-manager documentation for more details: https://cert-manager.io/docs/usage/certificate/#reissuance-triggered-by-user-actions.
. As soon as the CA rotation is fully completed, you can remove the public key of the old CA from the trust bundle `ConfigMap`.

== Verification

. Create an `InMemoryChannel`:
+
[source,yaml]
----
apiVersion: messaging.knative.dev/v1
kind: InMemoryChannel
metadata:
name: transport-encryption-test
----

. Apply the `InMemoryChannel` resource:
+
[source,terminal]
----
$ oc apply -f <filename>
----

. View the `InMemoryChannel` address:
+
[source,terminal]
----
$ oc get inmemorychannels.messaging.knative.dev transport-encryption-test
----
+
.Example output
[source,terminal]
----
NAME URL AGE READY REASON
transport-encryption-test https://imc-dispatcher.knative-eventing.svc.cluster.local/default/transport-encryption-test 17s True
----

0 comments on commit b26cbd2

Please sign in to comment.