# Validating webhook (admission controller) ## Overview Nginx ingress controller offers the option to validate ingresses before they enter the cluster, ensuring controller will generate a valid configuration. This controller is called, when [ValidatingAdmissionWebhook][1] is enabled, by the Kubernetes API server each time a new ingress is to enter the cluster, and rejects objects for which the generated nginx configuration fails to be validated. This feature requires some further configuration of the cluster, hence it is an optional feature, this section explains how to enable it for your cluster. ## Configure the webhook ### Generate the webhook certificate #### Self signed certificate Validating webhook must be served using TLS, you need to generate a certificate. Note that kube API server is checking the hostname of the certificate, the common name of your certificate will need to match the service name. !!! example To run the validating webhook with a service named `ingress-validation-webhook` in the namespace `ingress-nginx`, run ```bash openssl req -x509 -newkey rsa:2048 -keyout certificate.pem -out key.pem -days 365 -nodes -subj "/CN=ingress-validation-webhook.ingress-nginx.svc" ``` ##### Using Kubernetes CA Kubernetes also provides primitives to sign a certificate request. Here is an example on how to use it !!! example ``` #!/bin/bash SERVICE_NAME=ingress-nginx NAMESPACE=ingress-nginx TEMP_DIRECTORY=$(mktemp -d) echo "creating certs in directory ${TEMP_DIRECTORY}" cat <> ${TEMP_DIRECTORY}/csr.conf [req] req_extensions = v3_req distinguished_name = req_distinguished_name [req_distinguished_name] [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = ${SERVICE_NAME} DNS.2 = ${SERVICE_NAME}.${NAMESPACE} DNS.3 = ${SERVICE_NAME}.${NAMESPACE}.svc EOF openssl genrsa -out ${TEMP_DIRECTORY}/server-key.pem 2048 openssl req -new -key ${TEMP_DIRECTORY}/server-key.pem \ -subj "/CN=${SERVICE_NAME}.${NAMESPACE}.svc" \ -out ${TEMP_DIRECTORY}/server.csr \ -config ${TEMP_DIRECTORY}/csr.conf cat <&2 exit 1 fi echo ${SERVER_CERT} | openssl base64 -d -A -out ${TEMP_DIRECTORY}/server-cert.pem kubectl create secret generic ingress-nginx.svc \ --from-file=key.pem=${TEMP_DIRECTORY}/server-key.pem \ --from-file=cert.pem=${TEMP_DIRECTORY}/server-cert.pem \ -n ${NAMESPACE} ``` ### Ingress controller flags To enable the feature in the ingress controller, you _need_ to provide 3 flags to the command line. |flag|description|example usage| |-|-|-| |`--validating-webhook`|The address to start an admission controller on|`:8080`| |`--validating-webhook-certificate`|The certificate the webhook is using for its TLS handling|`/usr/local/certificates/validating-webhook.pem`| |`--validating-webhook-key`|The key the webhook is using for its TLS handling|`/usr/local/certificates/validating-webhook-key.pem`| ### kube API server flags Validating webhook feature requires specific setup on the kube API server side. Depending on your kubernetes version, the flag can, or not, be enabled by default. To check that your kube API server runs with the required flags, please refer to the [kubernetes][1] documentation. ### Additional kubernetes objects Once both the ingress controller and the kube API server are configured to serve the webhook, add the you can configure the webhook with the following objects: ```yaml apiVersion: v1 kind: Service metadata: name: ingress-validation-webhook namespace: ingress-nginx spec: ports: - name: admission port: 443 protocol: TCP targetPort: 8080 selector: app: nginx-ingress component: controller --- apiVersion: admissionregistration.k8s.io/v1beta1 kind: ValidatingWebhookConfiguration metadata: name: check-ingress webhooks: - name: validate.nginx.ingress.kubernetes.io rules: - apiGroups: - networking.k8s.io/v1beta1 apiVersions: - v1beta1 operations: - CREATE - UPDATE resources: - ingresses failurePolicy: Fail clientConfig: service: namespace: ingress-nginx name: ingress-validation-webhook path: /networking.k8s.io/v1beta1/ingress caBundle: ``` [1]: https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook ### Using Helm On nginx-ingress helm chart, set `controller.admissionWebhooks.enable` to `true` (default to `false`) to enabled Validating webhook. With `controller.admissionWebhooks.patch.enabled` set to `true` (default value) a certificate will be automatically created and the CA added to ValidatingWebhookConfiguration. For more details check [here](https://github.com/helm/charts/tree/master/stable/nginx-ingress/templates/admission-webhooks/job-patch).