Connect F5 WAF for NGINX to NGINX Security Monitoring
This document explains how to use NGINX Ingress Controller to configure NGINX Agent for sending 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
-agentsuffix)
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 that include F5 WAF for NGINX also include NGINX Agent 2. See the Technical specifications for the full list of available image variants.
-
Add the below arguments to the
values.yamlfile:yaml nginxAgent: enable: true instanceManager: host: "<FQDN or IP address of NGINX Instance Manager>" -
Follow the Installation with Helm instructions to deploy NGINX Ingress Controller with custom resources enabled, and optionally set other
nginxAgent.*values if required.
-
Add the below arguments to the
argssection of your NGINX Ingress Controller Deployment, DaemonSet, or StatefulSet:yaml args: - -agent=true - -agent-instance-group=<NGINX Ingress Controller deployment name> -
Create a ConfigMap with an
nginx-agent.conffile which must be mounted to/etc/nginx-agent/nginx-agent.confin the NGINX Ingress Controller pod.yaml kind: ConfigMap apiVersion: v1 metadata: name: <configmap name> namespace: <namespace where NGINX Ingress Controller will be installed> data: nginx-agent.conf: |- log: level: error path: "" server: host: "<FQDN or IP address of NGINX Instance Manager>" 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: 1514See the NGINX Agent Configuration Overview for more configuration options.
Thefeatureslist must not containnginx-config-asyncornginx-ssl-configas these features can cause conflicts with NGINX Ingress Controller.
-
Mount the ConfigMap to the NGINX Ingress Controller pod at
/etc/nginx-agent/nginx-agent.confand the dynamic agent config at/var/lib/nginx-agentby 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 -
Follow the Installation with Manifests instructions to deploy NGINX Ingress Controller with custom resources enabled.
Once installed, the pods will be visible in the NGINX Instance Manager Instances dashboard.
This guide assumes that you have an NGINX One Console account with access to create data plane keys.
-
Create a data plane key 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=<Your Dataplane Key> \ -n <namespace> -
Use an image variant with the
-agentsuffix, available starting with NGINX Ingress Controller 5.5.0 (for example,debian-plus-nap-agentfor F5 WAF for NGINX v4, ordebian-plus-nap-v5-agentfor v5). Images without the-agentsuffix include NGINX Agent 2 and are not compatible with NGINX One Console. See the Technical specifications for the full list of available image variants.
-
Add the below arguments to the
values.yamlfile:yaml nginxAgent: enable: true dataplaneKeySecretName: "<data_plane_key_secret_name>" endpointHost: "agent.connect.nginx.com" endpointPort: 443 -
Follow the Installation with Helm instructions to deploy NGINX Ingress Controller with custom resources enabled.
See the Connect NGINX Ingress Controller to NGINX One Console guide for more details on connecting to NGINX One Console.
-
Add the below argument to the
argssection of your NGINX Ingress Controller Deployment, DaemonSet, or StatefulSet:yaml args: - -agent=true -
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=<Your Dataplane Key> \ -n <namespace> -
Create a ConfigMap with an
nginx-agent.conffile:yaml kind: ConfigMap apiVersion: v1 metadata: name: nginx-agent-config namespace: <namespace where NGINX Ingress Controller will be installed> 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-napfeature enables NGINX Agent to collect F5 WAF for NGINX security events. The/etc/app_protectentry inallowed_directoriesis required for WAF-enabled deployments. -
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: "<data_plane_key_secret_name>" - 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 -
Follow the Installation with Manifests 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 for details.
NGINX Agent runs a syslog listener which F5 WAF for NGINX can be configured to send logs to, which will then allow NGINX Agent to send metrics to NGINX Security Monitoring. This applies to both NGINX Instance Manager (NGINX Agent 2) and NGINX One Console (NGINX Agent 3) deployments. When using NGINX Agent 3, 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 and Ingress example in the repository. Do not modify the APLogConf in these examples, as NGINX Agent expects a specific log format.
For F5 WAF for NGINX v5, see the VirtualServer example and Ingress example in the repository. Policy and log configurations are compiled into bundles (.tgz files) instead of using 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 for details on compiling policy and log bundles.
When using NGINX One Console, you can create and manage WAF policies under WAF > Policies. Once you have 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 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 in the NGINX One Console documentation for details.
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:
-
Obtain a data plane key from NGINX One Console. See Create and manage data plane keys.
-
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=<Your Dataplane Key> \ -n <namespace> -
Update your deployment to use NGINX Agent 3:
Update your values.yaml to replace the NGINX Instance Manager configuration with NGINX One Console configuration:
# 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: 443Run the upgrade:
helm upgrade <release-name> oci://ghcr.io/nginx/charts/nginx-ingress --version 2.5.1 \
-f values.yaml \
-n <namespace>-
Update the container image in your Deployment or DaemonSet to an image variant with the
-agentsuffix, available starting with NGINX Ingress Controller 5.5.0 (for example,debian-plus-nap-agentfor WAF v4, ordebian-plus-nap-v5-agentfor WAF v5). -
Update the container args to remove
-agent-instance-group:yaml args: - -agent=true # Remove: - -agent-instance-group=<name> -
Replace the
nginx-agent.confConfigMap with the NGINX Agent 3 configuration shown in the Using NGINX One Console - Using Manifests section above. -
Update volumes and volumeMounts:
Remove the NGINX Instance Manager TLS volume and mount:
yaml # Remove: # - name: nginx-agent-tls # projected: # sources: # - secret: # name: <nim-tls-secret> # - secret: # name: <nim-ca-secret>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 -
Apply the updated manifests:
kubectl apply -f <your-deployment-manifest>.yaml
-
Verify the upgrade by checking the agent version and connection:
kubectl exec -it -n <namespace> <pod_name> -- nginx-agent -vThe output should show
nginx-agent version v3.x.x. Check the NGINX One Console dashboard under Manage > Instances to confirm your instances appear. -
Clean up old NGINX Instance Manager TLS secrets if they are no longer needed:
kubectl delete secret <nim-tls-secret> <nim-ca-secret> -n <namespace>
Your F5 WAF for NGINX Policy resources (APPolicy, APLogConf, or compiled bundles for v5) do not need to change during this migration. The WAF configuration and thelogDestsyslog destination (syslog:server=127.0.0.1:1514) remain the same.