This is unreleased documentation for Policy Manager 1.29-next. |
Hardening the Kubewarden webhooks
The Kubewarden stack uses webhooks to enforce policies in a Kubernetes cluster.
Each PolicyServer
instance exposes a webhook that the Kubernetes API server
calls to validate and mutate resources. Moreover, the kubewarden-controller
exposes webhooks to validate and mutate the custom resources provided by the
Kubewarden project.
To decrease their attack surface, you should limit access to these webhooks to the only valid callers they have:
-
the Kubernetes API server
-
the audit scanner component.
You can do this using network policies and authentication independently, or together, to harden the webhooks against attacks.
Block external traffic using network policies
Webhooks are only expected to accept requests from the Kubernetes API server and the audit scanner component. By default, however, webhooks can accept traffic from any source. If you are using a Container Network Interface (CNI) that supports Network Policies, you can create a policy that blocks traffic that doesn’t originate from the API server.
The built-in NetworkPolicy resource in Kubernetes can’t block or admit traffic
from the cluster hosts. Also, the kube-apiserver
process is always running on
the host network. Therefore, you must use the advanced network policy resources
from the CNI in use. Examples for Calico and Cilium follow. Consult the
documentation for your CNI for more details.
Calico
Use the NetworkPolicy resource in the crd.projectcalico.org/v1
API group,
to define a network policy like the following one:
apiVersion: crd.projectcalico.org/v1
kind: NetworkPolicy
metadata:
name: allow-k8s-and-audit-scanner
namespace: kubewarden
spec:
selector: 'app.kubernetes.io/component in {"kubewarden-controller", "policy-server"}'
types:
- Ingress
ingress:
- action: Allow
protocol: TCP
source:
nets:
- 192.168.42.0/24
destination:
selector: 'app.kubernetes.io/component in {"kubewarden-controller", "policy-server"}'
- action: Allow
protocol: TCP
source:
namespaceSelector: 'kubernetes.io/metadata.name == "kubewarden"'
destination:
selector: 'app.kubernetes.io/component in {"kubewarden-controller", "policy-server"}'
This network policy uses label selectors introduced in Kubewarden 1.23.0. If you are using an older version, update the labels in the policy to match your deployment. More sprecifically, write the
selectors as:
|
Cilium
Use the CiliumNetworkPolicy resource in the cilium.io/v2
API group to define
a network policy like the following one:
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: allow-k8s-and-audit-scanner
namespace: kubewarden
spec:
endpointSelector:
matchExpressions:
- key: app.kubernetes.io/component
operator: In
values:
- policy-server
- controller
ingress:
- fromEntities:
- host
- remote-node
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kubewarden
This network policy uses label selectors introduced in Kubewarden 1.23.0. If you are using an older version, update the labels in the policy to match your deployment. More specifically, write the
expression as:
|
Require the Kubernetes API Server to authenticate to the webhook
Refer to webook mTLS how-to for a step-by-step guide on configuring the Kubernetes API server of K3s to authenticate to the webhook. |
The webhooks exposed by the Kubewarden stack should only accept requests from the Kubernetes API server or from the audit scanner component. By default, these webhooks don’t require clients to authenticate to them. They accept any request.
You can configure the webhooks to require credentials so that only the API server and the audit scanner processes can access them. Refer to the Kubernetes documentation for more information.
-
Configure the API server to present a client certificate to the webhook, pointing to an
AdmissionConfiguration
file to configure theValidatingAdmissionWebhook
andMutatingAdmissionWebhook
plug-ins:Create a file named
admission.yaml
with the following contents:apiVersion: apiserver.config.k8s.io/v1 kind: AdmissionConfiguration plugins: - name: ValidatingAdmissionWebhook configuration: apiVersion: apiserver.config.k8s.io/v1 kind: WebhookAdmissionConfiguration kubeConfigFile: "/etc/k8s/admission/kubeconfig" - name: MutatingAdmissionWebhook configuration: apiVersion: apiserver.config.k8s.io/v1 kind: WebhookAdmissionConfiguration kubeConfigFile: "/etc/k8s/admission/kubeconfig"
This is the same configuration file used to configure other plug-ins, such as
PodSecurity
. If your distribution or setup uses additional admission plug-ins, you should also configure those. -
Create the
kubeconfig
file the admission plug-ins refer to. Kubewarden only supports client certificate authentication, so generate a TLS key pair, and set the kubeconfig to use either client-certificate and client-key or client-certificate-data and client-key-data.For example:
apiVersion: v1 kind: Config users: - name: '*.kubewarden.svc' user: client-certificate: /path/to/client/cert client-key: /path/to/client/key
-
Start the
kube-apiserver
binary with the flag--admission-control-config-file
pointing to yourAdmissionConfiguration
file. The way to do this varies by distribution, and it isn’t supported universally, such as in hosted Kubernetes providers. Consult the documentation for your Kubernetes distribution. -
Make the certificate of the root CA that issued the API server client certificate available to the Kubewarden stack.
Put its content into a
ConfigMap
under thekubewarden
namespace using a key namedclient-ca.crt
.Assuming the root CA is available at
/etc/k8s/admission/certs/rootCA.crt
, create theConfigMap
with the following command:kubectl create configmap -n kubewarden api-server-mtls \ --from-file=client-ca.crt=/etc/k8s/admission/certs/rootCA.crt
-
Finally, when installing the
kubewarden-controller
Helm chart, make sure to enable the following values:-
Set
mTLS.enable
totrue
. -
Set
mTLS.configMapName
to the name of theConfigMap
that was previously created.The
ConfigMap
name isapi-server-mtls
, so the Helm command to install thekubewarden-controller
is:helm install --wait -n kubewarden kubewarden-controller kubewarden/kubewarden-controller \ --set mTLS.enable=true \ --set mTLS.configMapName=api-server-mtls
The Kubewarden controller creates a client certificate for use by the audit scanner component. The certificate is automatically rotated by the controller when needed.
-