rancher-external-ip-webhook

Edit on GitHub

/services/rancher-external-ip-webhook

Type

Helm

Namespace

rancher-external-ip-webhook

Overview

The rancher-external-ip-webhook service is a validating webhook that protects against CVE-2020-8554 in Kubernetes. It needs to be deployed on any Kubernetes cluster where untrusted users may be able to spawn pods with control over the pod configuration.

Kubernetes allows anyone with pod creation permissions to claim an IP address via externalIP configuration. If they do this, Kubernetes will route all traffic for that IP address to that pod, even if the IP would otherwise be routed to the Internet. This allows a malicious pod to claim addresses like 8.8.8.8 and run a rogue DNS server, or intercept other traffic from other pods. This service defeats this attack by adding a validating webhook that rejects any pod that specifies an external IP address. (We use ingresses instead.)

Kubernetes provides the validating webhook, and the Rancher project provides a Helm chart to install it. The Helm chart requires cert-manager to generate a self-signed certificate (it’s not entirely clear why), so we only deploy it on platforms where we’re also installing cert-manager.

Testing

The following commands can be used to test whether this service is performing as expected:

$ kubectl run nginx --image nginx:latest --port 80
pod/nginx created
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: my-evil-service
spec:
  selector:
    run: nginx
  type: ClusterIP
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
  externalIPs:
    - 23.185.0.3 #cncf.io
EOF
Error from server (spec.externalIPs: Invalid value: "23.185.0.3" [...]

Taken from the relevant Kubernetes issue. Adjust if the IP address of cncf.io changes.

If this does not produce an error, the validating webhook is not working. You can then demonstrate the attack with:

$ kubectl run --rm -i --tty curl --image=curlimages/curl --restart=Never -- curl -I http://cncf.io

and look at the Server header in the output. If it’s nginx, the attack works (cncf.io uses Varnish).