Title
Create new category
Edit page index title
Edit category
Edit link
NGINX Ingress Controller Integration
OMetaScan NGINX Ingress Controller Configuration
This document covers the new approach using the OPSWAT-customised image on top of the NGINX Ingress Controller Helm chart (maintained by NGINX Org). For the Kubernetes Ingress Controller (EOL March 2026), starting from version of the controller 5.4.2 will be compatible with the Ingress Controller provided by NGINX Org.
ConfigMaps
ConfigMaps allow you to decouple configuration artifacts from image content to keep containerized applications portable.
The ConfigMap API resource stores configuration data as key-value pairs. The data provides the configurations for system components for the nginx-controller.
| Name | Type | Default | Usage |
|---|---|---|---|
| enable-ometascan | bool | “false” | Enable or Disable ometascan module globally Note: You must enable this config to use ometascan module |
Annotations
| Name | Type | Default | Usage |
|---|---|---|---|
| nginx.org/ometascan-send-timeout | number | 60 | Sets a timeout for transmitting a request to the proxied server. The timeout is set only between two successive write operations, not for the transmission of the whole request. If the proxied server does not receive anything within this time, the connection is closed. |
| nginx.org/ometascan-read-timeout | number | 86400 (1 day) | Defines a timeout for reading a response from the proxied server. The timeout is set only between two successive read operations, not for the transmission of the whole response. If the proxied server does not transmit anything within this time, the connection is closed. |
| nginx.org/ometascan-pre-cache-size | number |
(maximum number of Nginx) | Config maximum caching size per request. |
| nginx.org/ometascan-pre-cache | "true" or "false" | "false" | Turn on/off pre-caching request when sending to ICAP Server |
| nginx.org/ometascan-pass | string | No default | Sets the protocol and address of a ICAP server and an optional URI to which a location should be mapped. Note: Must have it for enable annotation |
| nginx.org/ometascan-methods | string | GET HEAD POST PUT PATCH DELETE | This directive specifies HTTP request methods that are considered by ometascan_pass. HTTP request methods not listed will be skipped completely. The following HTTP methods are allowed: GET, HEAD, POST, PUT, PATCH, and DELETE |
| nginx.org/ometascan-connect-timeout | number | 60 | Defines a timeout for establishing a connection with a proxied server. It should be noted that this timeout cannot usually exceed 75 seconds. |
| nginx.org/ometascan-x-forwarded-for | string | off | Parse X-Forwarded-For for client IP |
| nginx.org/ometascan-intercept-errors | string | off | Intercept error responses for scanning |
| nginx.org/ometascan-allow-bad-request-traffic | string | off | Allow traffic on ICAP bad request |
| nginx.org/ometascan-set-header | string | Custom headers to send to ICAP (multi-line) | |
| nginx.org/ometascan-ssl-trusted-certificate | string | CA secret reference (namespace/name) | |
| nginx.org/ometascan-ssl-ciphers | string | DEFAULT | SSL ciphers |
| nginx.org/ometascan-ssl-protocols | string | TLSv1.2 TLSv1.3 | SSL protocols |
| nginx.org/ometascan-ssl-name | string | $proxy_host | SSL server name |
| nginx.org/ometascan-ssl-verify | number | 1 | Certificate chain depth |
| nginx.org/ometascan-ssl-server-name | string | off | Enable SNI |
| nginx.org/ometascan-ssl-session-reuse | string | on | SSL session reuse |
| nginx.org/ometascan-health-check | string | The annotation enables active health checking of the MD ICAP Server upstream. When enabled, NGINX periodically probes the ICAP server and automatically marks it UP or DOWN based on the results. Requests are not sent to servers marked DOWN. E.g: nginx.org/ometascan-health-check: "interval=<ms> [passes=<n>] [fails=<n>] [timeout=<ms>] [jitter=<ms>] [mandatory [persistent]]" |
You can add these Kubernetes annotations to specific Ingress objects to customize their behavior.
OMetaScan NGINX Ingress on Minikube
Requirement
Minikube: https://minikube.sigs.k8s.io/docs/
NGINX Ingress with OMetascan module images on Docker Hub
- For example:
- latest image: opswat/nginx-ingress
- or specify the tag: opswat/nginx-ingress:controller-5.4.1_ometascan-1.5.0_r1
- For example:
MD ICAP Server at least version v5.1.0, which has already enabled NGINX integration NGINX Integration Configurations
Pre-setup
Enable Nginx ingress on Minikube
- Start minikube
xxxxxxxxxxminikube start- Install the NGINX Ingress controller, following this CLI
xxxxxxxxxxhelm install <my-release> oci://ghcr.io/nginx/charts/nginx-ingress --version 2.5.2- Verify that the NGINX Ingress controller is running
xxxxxxxxxxkubectl get ingressclassesThe output is similar to:
xxxxxxxxxxNAME CONTROLLER PARAMETERS AGEnginx nginx.org/ingress-controller <none> 10mChange the default Nginx Ingress image to Nginx Ingress with the OMetascan module image
- Update the default image to opswat/nginx-ingress using the following command:
xxxxxxxxxxkubectl set image deployment/nginx-ingress-controller \ nginx-ingress=opswat/nginx-ingress- Verify that the images have changed:
xxxxxxxxxxkubectl get deploy nginx-ingress-controller -o jsonpath='{.spec.template.spec.containers}'The output:
xxxxxxxxxx[ { "image": "opswat/nginx-ingress:controller-5.4.1_ometascan-1.5.0_r1", "imagePullPolicy": "Always", "name": "nginx-ingress", }]- Verify that the NGINX Ingress controller is replaced and running
xxxxxxxxxxkubectl get pods -A | grep nginx-ingressThe output is similar to:
xxxxxxxxxxNAME READY STATUS RESTARTS AGEnginx-ingress-controller-785746b95c-djcjx 1/1 Running 0 119sEnable OMetascan Module
- Set enable-ometascan: "true" to turn on the OMetascan module on ConfigMaps of ingress-nginx-controller:
xxxxxxxxxxcat <<EOF | kubectl apply -f -apiVersion: v1data: enable-ometascan: "true"kind: ConfigMapmetadata: annotations: meta.helm.sh/release-name: nginx-ingress meta.helm.sh/release-namespace: default labels: app.kubernetes.io/instance: nginx-ingress app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: nginx-ingress app.kubernetes.io/version: 5.4.1 helm.sh/chart: nginx-ingress-2.5.1 name: nginx-ingress namespace: defaultEOFDeploy Echo Server as Service A
refer to: https://github.com/Ealenn/Echo-Server#kubernetes
xxxxxxxxxxcat <<EOF | kubectl apply -f -apiVersion: v1kind: Namespacemetadata: name: echoserver---apiVersion: apps/v1kind: Deploymentmetadata: name: echoserver namespace: echoserverspec: replicas: 5 selector: matchLabels: app: echoserver template: metadata: labels: app: echoserver spec: containers: - image: ealen/echo-server:latest imagePullPolicy: IfNotPresent name: echoserver ports: - containerPort: 80 env: - name: PORT value: "80"---apiVersion: v1kind: Servicemetadata: name: echoserver namespace: echoserverspec: ports: - port: 80 targetPort: 80 protocol: TCP type: ClusterIP selector: app: echoserverEOFExample:
/path1rewrite to/subpathA(use ometascan)/path2rewrite to/subpathB(use ometascan)- Only PUT methods
- Max client body size 100 Mb
/path3rewrite to /subpathC(do not use ometascan)

xxxxxxxxxxcat <<EOF | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ingress-rule-a namespace: echoserver annotations: nginx.org/rewrite-target: /subpathA nginx.org/ometascan-pass: "http://10.40.161.167:8043"spec: rules: - host: testserver-a.com http: paths: - path: /path1 pathType: Prefix backend: service: name: echoserver port: number: 80---apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ingress-rule-b namespace: echoserver annotations: nginx.org/rewrite-target: /subpathB nginx.org/ometascan-pass: "http://10.40.161.167:8043" nginx.org/ometascan-methods: "PUT" nginx.org/client-max-body-size: 100Mspec: rules: - host: testserver-b.com http: paths: - path: /path2 pathType: Prefix backend: service: name: echoserver port: number: 80---apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ingress-rule-c namespace: echoserver annotations: nginx.org/rewrite-target: /subpathCspec: rules: - host: testserver-c.com http: paths: - path: /path3 pathType: Prefix backend: service: name: echoserver port: number: 80EOFOMetaScan NGINX Ingress on Kubernetes
Requirements
- An existing K8S cluster
- Helm CLI
- NGINX Ingress with OMetascan module images:
xxxxxxxxxx# pull latest imagedocker pull opswat/nginx-ingress #or specific the tagdocker pull opswat/nginx-ingress:controller-5.4.1_ometascan-1.5.0_r1- An existing MD ICAP Server on Kubernetes
Instructions
Example:

1. Install NGINX Ingress Controller via Helm Chart
xxxxxxxxxxhelm install nginx-ingress oci://ghcr.io/nginx/charts/nginx-ingress \--version 2.5.2Output:
xxxxxxxxxxPulled: ghcr.io/nginx/charts/nginx-ingress:2.5.2Digest: sha256:0d0548ec8f087ef431f2f7e26503775d99cd8f5644261f571d9133264d183094NAME: nginx-ingressLAST DEPLOYED: Wed May 20 15:07:07 2026NAMESPACE: defaultSTATUS: deployedREVISION: 1TEST SUITE: NoneNOTES:NGINX Ingress Controller 5.4.2 has been installed. For release notes, see: https://docs.nginx.com/nginx-ingress-controller/changelog/ For Helm installation instructions, see: https://docs.nginx.com/nginx-ingress-controller/install/helm/Verify the result, install nginx-ingress as CLI:
xxxxxxxxxxkubectl get pods -A | grep nginx-ingressOutput:
xxxxxxxxxxNAME READY STATUS RESTARTS AGEnginx-ingress-controller-69fbfb9f44-frjgg 1/1 Running 0 69sMake sure your nginx install with status of the pod nginx-ingress is running!
2. Replace The Ingress Controller Image
To replace the ingress controller image, we need to patch the existing k8s resource (deployment, DaemonSet, etc.) for the existing ingress controller to include the new image. For this, edit the ingress-controller-patch-image.yml file and replace the container name to match the existing controller and run the following command (replace 'deployment' and 'ingress-nginx-controller' with your specific resource type and name for the controller):
ingress-controller-patch-image.yml
xxxxxxxxxx---spec: template: spec: containers: - name: nginx-ingress image: opswat/nginx-ingressxxxxxxxxxxkubectl patch deployment nginx-ingress-controller \ --patch-file ingress-controller-patch-image.ymlOutput:
xxxxxxxxxxdeployment.apps/nginx-ingress-controller patchedCreate the file update-configmap-ingress-controller.yml
xxxxxxxxxxapiVersion: v1kind: ConfigMapmetadata: name: nginx-ingress namespace: defaultdata: enable-ometascan: "true"xxxxxxxxxxkubectl apply -f update-configmap-ingress-controller.ymlOutput:
xxxxxxxxxxconfigmap/nginx-ingress configured3. Deploy A Service To Test with MetaDefender ICAP Server
3.1. Create deployment sample:
xxxxxxxxxxkubectl create deployment backend --image=gcr.io/google-samples/hello-app:1.0Output:

3.2.Expose service sample:
xxxxxxxxxxkubectl expose deployment backend --port=8080 --type=ClusterIPOutput:

3.3.Create file ingress for sample app:
ingress-be.yml
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ingress-be-rule-a annotations: nginx.org/rewrite-target: /subpathA nginx.org/ometascan-pass: "http://md-icapsrv:8043" # Replace with the address and port of an existing ICAP instace, for example, if ICAP is running in the same cluster: http://<ICAP_SERVICE_NAME>.<ICAP_NAMESPACE>.svc.cluster.local:<ICAP_PORT> spec: ingressClassName: nginx rules: - host: testserver-a.com http: paths: - path: /subpathA pathType: Prefix backend: service: name: backend port: number: 8080---apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ingress-be-rule-b annotations: nginx.org/rewrite-target: /subpathB nginx.org/ometascan-pass: "http://md-icapsrv:8043" # Replace with the address and port of an existing ICAP instace, for example, if ICAP is running in the same cluster: http://<ICAP_SERVICE_NAME>.<ICAP_NAMESPACE>.svc.cluster.local:<ICAP_PORT> nginx.org/ometascan-methods: "PUT" nginx.org/client-body-buffer-size: 100Mspec: ingressClassName: nginx rules: - host: testserver-b.com http: paths: - path: /subpathB pathType: Prefix backend: service: name: backend port: number: 8080---apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ingress-be-rule-c annotations: nginx.org/rewrite-target: /subpathCspec: ingressClassName: nginx rules: - host: testserver-c.com http: paths: - path: /subpathC pathType: Prefix backend: service: name: backend port: number: 8080xxxxxxxxxxkubectl apply -f ingress-be.ymlOutput:

Add the following line to the bottom of the /etc/hosts file on your computer (you will need administrator access):
xxxxxxxxxx10.40.162.150 testserver.com mdicapsrvs-ui.opswat.localSend requests to Backend: curl -X GET testserver-a.com/subPathAcurl -X POST testserver-a.com/subPathAcurl -X PUT testserver-b.com/subPathBcurl -X GET testserver-b.com/subPathBcurl -X GET testserver-c.com/subPathCThe expected MD ICAP Server will scan requests
