Secure webhooks with mutual TLS with K3s

This guide shows you how to enable mutual TLS (mTLS) for all the webhooks used by the Kubewarden stack when using K3s as your Kubernetes distribution.

For more information on how to harden the webhooks, refer to the reference page.

Prerequisites

Before installing K3s, you need to create a certificate authority (CA) and a client certificate to use to secure the communication between the Kubewarden webhooks and the Kubernetes API server.

As a first step, create the /etc/rancher/k3s/admission/certs directory:

sudo mkdir -p /etc/rancher/k3s/admission/certs

Create a root CA and the client certificate

As root user, change directory to the /etc/rancher/k3s/admission/certs directory and create all needed certificates:

export FQDN=mtls.kubewarden.io

# Create CA
openssl req -nodes -batch -x509 -sha256 -days 365 -newkey rsa:2048 -keyout rootCA.key -out rootCA.crt

# Create CSR
openssl req -nodes -batch -newkey rsa:2048 -keyout client.key -out client.csr \
    -addext "subjectAltName = DNS:$FQDN"

# Create CRT
openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in client.csr -out client.crt -days 365 -CAcreateserial \
    -extfile <(echo "subjectAltName=DNS:$FQDN")

# Print CRT
openssl x509 -text -noout -in client.crt

The following files should have been created:

  • client.crt

  • client.csr

  • client.key

  • rootCA.crt

  • rootCA.key

  • rootCA.srl

Create the Kubernetes configuration file

Create the /etc/rancher/admission/admission.yaml file with the following content:

# /etc/rancher/admission/admission.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ValidatingAdmissionWebhook
  configuration:
    apiVersion: apiserver.config.k8s.io/v1
    kind: WebhookAdmissionConfiguration
    kubeConfigFile: "/etc/rancher/k3s/admission/kubeconfig"
- name: MutatingAdmissionWebhook
  configuration:
    apiVersion: apiserver.config.k8s.io/v1
    kind: WebhookAdmissionConfiguration
    kubeConfigFile: "/etc/rancher/k3s/admission/kubeconfig"

Finally, create a kubeconfig file at /etc/rancher/k3s/admission/kubeconfig:

# /etc/rancher/admission/kubeconfig
apiVersion: v1
kind: Config
users:
- name: '*.kubewarden.svc' # namespace where the kubewarden stack is deployed
  user:
    client-certificate: /etc/rancher/k3s/admission/certs/client.crt
    client-key: /etc/rancher/k3s/admission/certs/client.key

Create a K3s configuration file

Create a K3s configuration file at /etc/rancher/k3s/config.yaml:

# /etc/rancher/k3s/config.yaml
kube-apiserver-arg:
- admission-control-config-file=/etc/rancher/k3s/admission/admission.yaml

Install K3s

Install K3s using the following command:

curl -sfL https://get.k3s.io | sh -

Wait for the installation to complete.

Install the Kubewarden stack

Prerequisites

The certificate of the root CA, that issued the Kubernetes client certificate, must be made available to the Kubewarden stack.

The root CA is available at /etc/rancher/k3s/admission/certs/rootCA.crt on the Kubernetes node. Its content has to be put into a ConfigMap under the kubewarden namespace. The contents of the rootCA.crt file must be stored in a key named client-ca.crt.

First, create the kubewarden namespace:

kubectl create namespace kubewarden

Then create the ConfigMap in it. The following command, run on the Kubernetes node, does that:

kubectl create configmap -n kubewarden api-server-mtls \
    --from-file=client-ca.crt=/etc/rancher/k3s/admission/certs/rootCA.crt

The resulting ConfigMap is named api-server-mtls.

Install the Kubewarden stack

Install the Kubewarden stack as described in the quickstart guide. Follow all the steps, but when installing the kubewarden-controller Helm chart, make sure to enable the following values:

  • mTLS.enable: must be set to true.

  • mTLS.configMapName: must be set to the name of the ConfigMap that was previously created.

Given the ConfigMap was named api-server-mtls, the Helm command to install the kubewarden-controller is:

helm install --wait -n kubewarden kubewarden-controller kubewarden/kubewarden-controller \
    --set mTLS.enable=true \
    --set mTLS.configMapName=api-server-mtls

Once this command finishes, the Kubewarden stack is installed and its webhooks are secured with mTLS.