Configuration

Overview

This document explains how to use F5 NGINX Ingress Controller to configure NGINX App Protect WAF v5.

Note:
Check out the complete NGINX Ingress Controller with NGINX App Protect WAF example resources on GitHub for VirtualServer resources.

Global Configuration

NGINX Ingress Controller has global configuration parameters that match those in NGINX App Protect WAF. They are found in the ConfigMap resource: the NGINX App Protect WAF parameters are prefixed with app-protect*.

Enable NGINX App Protect WAF v5

NGINX App Protect WAF v5 can be enabled and configured for custom resources only(VirtualServer, VirtualServerRoute). You need to create a Policy Custom Resource referencing a policy bundle, then add it to the VirtualServer/VirtualServerRoute definition. Additional detail can be found in the Policy Resource documentation.

NGINX App Protect WAF Bundles

You define App Protect WAF bundles for VirtualServer custom resources by creating policy bundles and putting them on a mounted volume accessible from NGINX Ingress Controller.

Before applying a policy, a WAF policy bundle must be created, then copied to a volume mounted to /etc/app_protect/bundles.

Note:
NGINX Ingress Controller supports securityLogs for policy bundles. Log bundles must also be copied to a volume mounted to /etc/app_protect/bundles.

This example shows how a policy is configured by referencing a generated WAF Policy Bundle:

apiVersion: k8s.nginx.org/v1
kind: Policy
metadata:
  name: <policy_name>
spec:
  waf:
    enable: true
    apBundle: "<policy_bundle_name>.tgz"

This example shows the same policy as above but with a log bundle used for security log configuration:

apiVersion: k8s.nginx.org/v1
kind: Policy
metadata:
  name: <policy_name>
spec:
  waf:
    enable: true
    apBundle: "<policy_bundle_name>.tgz"
    securityLogs:
    - enable: true
      apLogBundle: "<log_bundle_name>.tgz"
      logDest: "syslog:server=syslog-svc.default:514"

Configuration in NGINX Plus Ingress Controller using Virtual Server Resource

This example shows how to deploy NGINX Ingress Controller with NGINX Plus and NGINX App Protect WAF v5, deploy a simple web application, and then configure load balancing and WAF protection for that application using the VirtualServer resource.

Note:
You can find the files for this example on GitHub.

Prerequisites

  1. Follow the installation instructions to deploy NGINX Ingress Controller with NGINX Plus and NGINX App Protect WAF version 5.

  2. Save the public IP address of NGINX Ingress Controller into a shell variable:

     IC_IP=XXX.YYY.ZZZ.III
    
  3. Save the HTTP port of NGINX Ingress Controller into a shell variable:

     IC_HTTP_PORT=<port number>
    

Step 1. Deploy a Web Application

Create the application deployment and service:

kubectl apply -f https://raw.githubusercontent.com/nginxinc/kubernetes-ingress/v3.6.1/examples/custom-resources/app-protect-waf-v5/webapp.yaml

Step 2. Create the Syslog Service

Create the syslog service and pod for the NGINX App Protect WAF security logs:

kubectl apply -f https://raw.githubusercontent.com/nginxinc/kubernetes-ingress/v3.6.1/examples/custom-resources/app-protect-waf-v5/syslog.yaml

Step 3 - Deploy the WAF Policy

Note:
Configuration settings in the Policy resource enable WAF protection by configuring NGINX App Protect WAF with the log configuration created in the previous step. The policy bundle referenced as your_policy_bundle_name.tgz need to be created and placed in the /etc/app_protect/bundles volume first.

Create and deploy the WAF policy.

 kubectl apply -f https://raw.githubusercontent.com/nginxinc/kubernetes-ingress/v3.6.1/examples/custom-resources/app-protect-waf-v5/waf.yaml

Step 4 - Configure Load Balancing

Note:
VirtualServer references the waf-policy created in Step 3.
  1. Create the VirtualServer Resource:

    kubectl apply -f https://raw.githubusercontent.com/nginxinc/kubernetes-ingress/v3.6.1/examples/custom-resources/app-protect-waf-v5/virtual-server.yaml
    

Step 5 - Test the Application

To access the application, curl the coffee and the tea services. We’ll use the --resolve option to set the Host header of a request with webapp.example.com

  1. Send a request to the application:
curl --resolve webapp.example.com:$IC_HTTP_PORT:$IC_IP http://webapp.example.com:$IC_HTTP_PORT/
Server address: 10.12.0.18:80
Server name: webapp-7586895968-r26zn
  1. Try to send a request with a suspicious URL:
curl --resolve webapp.example.com:$IC_HTTP_PORT:$IC_IP "http://webapp.example.com:$IC_HTTP_PORT/<script>"
<html><head><title>Request Rejected</title></head><body>
  1. Check the security logs in the syslog pod:
kubectl exec -it <SYSLOG_POD> -- cat /var/log/messages

Example VirtualServer configuration

The GitHub repository has a full VirtualServer example.

apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  name: webapp
spec:
  host: webapp.example.com
  policies:
  - name: waf-policy
  upstreams:
  - name: webapp
    service: webapp-svc
    port: 80
  routes:
  - path: /
    action:
      pass: webapp