# Connect F5 WAF for NGINX to NGINX Security Monitoring Type of document: How-to guide Product: NGINX Ingress Controller --- This document explains how to use NGINX Ingress Controller to configure NGINX Agent to send F5 WAF for NGINX metrics to NGINX Security Monitoring. You can send security metrics to either: - **NGINX Instance Manager** using NGINX Agent 2 - **NGINX One Console** using NGINX Agent 3 (available starting with NGINX Ingress Controller 5.5.0, using images with the `-agent` suffix) #### NGINX Instance Manager ## Before you begin This guide assumes that you have an installation of NGINX Instance Manager with NGINX Security Monitoring which is reachable from the Kubernetes cluster on which NGINX Ingress Controller is deployed. NGINX Ingress Controller images with F5 WAF for NGINX include NGINX Agent 2. See the [Technical specifications](/nic/technical-specifications.md#images-with-nginx-plus) for the full list of available image variants. ## Deploy NGINX Ingress Controller with NGINX Agent ### Using Helm 1. Add the below arguments to the `values.yaml` file: ```yaml nginxAgent: enable: true instanceManager: host: "" ``` 2. Follow the [Installation with Helm](/nic/install/helm.md) instructions to deploy NGINX Ingress Controller with custom resources enabled, and optionally set other `nginxAgent.*` values if required. ### Using Manifests 1. Add the following arguments to the `args` section of your NGINX Ingress Controller Deployment, DaemonSet, or StatefulSet: ```yaml args: - -agent=true - -agent-instance-group= ``` 2. Create a ConfigMap with an `nginx-agent.conf` file which must be mounted to `/etc/nginx-agent/nginx-agent.conf` in the NGINX Ingress Controller pod. ```yaml kind: ConfigMap apiVersion: v1 metadata: name: namespace: data: nginx-agent.conf: |- log: level: error path: "" server: host: "" grpcPort: 443 tls: enable: true skip_verify: false features: - registration - nginx-counting - metrics - dataplane-status extensions: - nginx-app-protect - nap-monitoring nginx_app_protect: report_interval: 15s precompiled_publication: true nap_monitoring: collector_buffer_size: 20000 processor_buffer_size: 20000 syslog_ip: 127.0.0.1 syslog_port: 1514 ``` See the [NGINX Agent Configuration Overview](/agent/configuration/configuration-overview.md) for more configuration options. **Note:** The `features` list must not contain `nginx-config-async` or `nginx-ssl-config` as these features can cause conflicts with NGINX Ingress Controller. 3. Mount the ConfigMap to the NGINX Ingress Controller pod at `/etc/nginx-agent/nginx-agent.conf` and the dynamic agent config at `/var/lib/nginx-agent` by adding the following to your Deployment, DaemonSet, or StatefulSet: ```yaml volumes: - name: agent-conf configMap: name: agent-conf - name: agent-dynamic emptyDir: {} ``` ```yaml volumeMounts: - name: agent-conf mountPath: /etc/nginx-agent/nginx-agent.conf subPath: nginx-agent.conf - name: agent-dynamic mountPath: /var/lib/nginx-agent ``` 4. Follow the [Installation with Manifests](/nic/install/manifests.md) instructions to deploy NGINX Ingress Controller with custom resources enabled. Once installed and configured, the pods will be visible in the NGINX Instance Manager Instances dashboard. #### NGINX One Console ## Before you begin This guide assumes that you have an NGINX One Console account with access to create data plane keys. - Create a [data plane key](/nginx-one-console/connect-instances/create-manage-data-plane-keys.md) from NGINX One Console. Pay attention to the expiration date of that key. - Create a Kubernetes Secret with the data plane key in the same namespace where NGINX Ingress Controller will be deployed: ```shell kubectl create secret generic dataplane-key \ --from-literal=dataplane.key= \ -n ``` - Use an image variant with the `-agent` suffix, available starting with NGINX Ingress Controller 5.5.0 (for example, `debian-plus-nap-agent` for F5 WAF for NGINX v4, or `debian-plus-nap-v5-agent` for v5). Images without the `-agent` suffix include NGINX Agent 2 and are not compatible with NGINX One Console. See the [Technical specifications](/nic/technical-specifications.md#images-with-nginx-plus) for the full list of available image variants. ## Deploy NGINX Ingress Controller with NGINX Agent ### Use Helm 1. Add the below arguments to the `values.yaml` file: ```yaml nginxAgent: enable: true dataplaneKeySecretName: "" endpointHost: "agent.connect.nginx.com" endpointPort: 443 ``` 2. Follow the [Installation with Helm](/nic/install/helm.md) instructions to deploy NGINX Ingress Controller with custom resources enabled. See the [Connect NGINX Ingress Controller to NGINX One Console](/nginx-one-console/k8s/add-nic.md) guide for more details on connecting to NGINX One Console. ### Use Manifests 1. Add the following argument to the `args` section of your NGINX Ingress Controller Deployment, DaemonSet, or StatefulSet: ```yaml args: - -agent=true ``` 2. Create a Kubernetes Secret with the data plane key if you have not already done so: ```shell kubectl create secret generic dataplane-key \ --from-literal=dataplane.key= \ -n ``` 3. Create a ConfigMap with an `nginx-agent.conf` file: ```yaml kind: ConfigMap apiVersion: v1 metadata: name: nginx-agent-config namespace: data: nginx-agent.conf: |- log: level: info path: "" allowed_directories: - /etc/nginx - /usr/lib/nginx/modules - /etc/app_protect features: - certificates - connection - metrics - file-watcher - logs-nap command: server: host: agent.connect.nginx.com port: 443 auth: tokenpath: "/etc/nginx-agent/secrets/dataplane.key" tls: skip_verify: false collector: log: path: "stdout" ``` The `logs-nap` feature enables NGINX Agent to collect F5 WAF for NGINX security events. The `/etc/app_protect` entry in `allowed_directories` is required for WAF-enabled deployments. 4. Mount the ConfigMap and the data plane key Secret to the NGINX Ingress Controller pod: ```yaml volumes: - name: agent-conf configMap: name: nginx-agent-config - name: agent-etc emptyDir: {} - name: dataplane-key secret: secretName: "" - name: agent-dynamic emptyDir: {} ``` ```yaml volumeMounts: - name: agent-etc mountPath: /etc/nginx-agent - name: agent-conf mountPath: /etc/nginx-agent/nginx-agent.conf subPath: nginx-agent.conf - name: dataplane-key mountPath: /etc/nginx-agent/secrets - name: agent-dynamic mountPath: /var/lib/nginx-agent ``` 5. Follow the [Installation with Manifests](/nic/install/manifests.md) instructions to deploy NGINX Ingress Controller with custom resources enabled. Once installed, the pods will be visible in NGINX One Console. See [Verify a connection to NGINX One Console](/nginx-one-console/k8s/add-nic.md#verify-a-connection-to-nginx-one-console) for details. ## Configure F5 WAF for NGINX to send metrics to NGINX Agent NGINX Agent runs a syslog listener. Configure F5 WAF for NGINX to send logs to this listener so that NGINX Agent can forward metrics to NGINX Security Monitoring. This applies to deployments using NGINX Instance Manager and NGINX One Console. In NGINX One Console deployments (which uses NGINX Agent 3.x), the `logs-nap` feature handles syslog collection automatically. Configure the WAF Policy `logDest` to send logs to the NGINX Agent syslog listener at `syslog:server=127.0.0.1:1514`. For F5 WAF for NGINX v4, see the [VirtualServer example](https://github.com/nginx/kubernetes-ingress/tree/v/examples/custom-resources/security-monitoring) and [Ingress example](https://github.com/nginx/kubernetes-ingress/tree/v/examples/ingress-resources/security-monitoring) in the repository. Do not modify the APLogConf in these examples, because NGINX Agent expects a specific log format. For F5 WAF for NGINX v5, see the [VirtualServer example](https://github.com/nginx/kubernetes-ingress/tree/v/examples/custom-resources/security-monitoring-v5) and [Ingress example](https://github.com/nginx/kubernetes-ingress/tree/v/examples/ingress-resources/security-monitoring-v5) in the repository. Compile policy and log configurations into bundles (`.tgz` files). Do not use APPolicy and APLogConf custom resources. The log bundle must be compiled from a log profile that matches the format required by NGINX Security Monitoring. See the [F5 WAF for NGINX v5 configuration guide](/nic/integrations/app-protect-waf-v5/configuration.md) for details on compiling policy and log bundles. When using NGINX One Console, you can create and manage WAF policies under **WAF > Policies**. After you create a policy, compile it into a `.tgz` bundle using the waf-compiler image and copy it to the pod at `/etc/app_protect/bundles/`. See [Compile WAF Policy from JSON to Bundle](/nic/install/waf-helm.md#compile-waf-policy-from-json-to-bundle) for the compilation steps. For the required log bundle, the `secops_dashboard` log profile is available to download directly from **WAF > Log Profiles** in NGINX One Console — no compilation needed. See [Set up security monitoring](https://docs.nginx.com/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring/) in the NGINX One Console documentation for details. ## Upgrade from NGINX Instance Manager to NGINX One Console If you have an existing deployment using NGINX Instance Manager (NGINX Agent 2) and want to migrate to NGINX One Console (NGINX Agent 3, available starting with NGINX Ingress Controller 5.5.0), follow these steps: 1. **Obtain a data plane key** from NGINX One Console. See [Create and manage data plane keys](/nginx-one-console/connect-instances/create-manage-data-plane-keys.md). 2. **Create the data plane key Secret** in the same namespace as your NGINX Ingress Controller deployment: ```shell kubectl create secret generic dataplane-key \ --from-literal=dataplane.key= \ -n ``` 3. To continue the conversion to NGINX One Console, **update your deployment** to use NGINX Agent 3: #### Using Helm Update your `values.yaml` to replace the NGINX Instance Manager configuration with NGINX One Console configuration: ```yaml # Remove these values: # nginxAgent: # instanceManager: # host: "nim.example.com" # syslog: ... # napMonitoring: ... # Add NGINX One Console configuration: nginxAgent: enable: true dataplaneKeySecretName: "dataplane-key" endpointHost: "agent.connect.nginx.com" endpointPort: 443 ``` Run the upgrade: ```shell helm upgrade oci://ghcr.io/nginx/charts/nginx-ingress --version \ -f values.yaml \ -n ``` #### Using Manifests 1. Update the container image in your Deployment or DaemonSet to an image variant with the `-agent` suffix, available starting with NGINX Ingress Controller 5.5.0 For example, depending on your Linux distribution, you could use `debian-plus-nap-agent` for WAF v4, or `debian-plus-nap-v5-agent` for WAF v5. 2. Update the container args to remove `-agent-instance-group`: ```yaml args: - -agent=true # Remove: - -agent-instance-group= ``` 3. Replace the `nginx-agent.conf` ConfigMap with the NGINX Agent 3 configuration shown in the [Using NGINX One Console - Using Manifests](#using-nginx-one-console) section. 4. Update volumes and volumeMounts: Remove the NGINX Instance Manager TLS volume and mount: ```yaml # Remove: # - name: nginx-agent-tls # projected: # sources: # - secret: # name: # - secret: # name: ``` Add the data plane key volume and mount: ```yaml volumes: - name: dataplane-key secret: secretName: "dataplane-key" volumeMounts: - name: dataplane-key mountPath: /etc/nginx-agent/secrets ``` 5. Apply the updated manifests: ```shell kubectl apply -f .yaml ``` 4. **Verify the upgrade** by checking the agent version and connection: ```shell kubectl exec -it -n -- nginx-agent -v ``` The output should show `nginx-agent version v3.x.x`. Check the NGINX One Console dashboard under **Manage > Instances** to confirm your instances appear. 5. **Clean up** old NGINX Instance Manager TLS secrets if they are no longer needed: ```shell kubectl delete secret -n ``` **Note:** Modifying the APLogConf in the examples may result in the Security Monitoring integration not working, as NGINX Agent expects a specific log format.