Nuclei Operator
A Kubernetes operator that automates security scanning of web applications exposed through Kubernetes Ingress resources and Istio VirtualService CRDs using Nuclei, a fast and customizable vulnerability scanner.
Overview
The Nuclei Operator watches for Ingress and VirtualService resources in your Kubernetes cluster and automatically creates security scans for the exposed endpoints. Scan results are stored in custom NucleiScan resources, making it easy to track and monitor vulnerabilities across your infrastructure.
Key Features
- Automatic Discovery: Watches Kubernetes Ingress and Istio VirtualService resources for new endpoints
- Automated Scanning: Automatically creates and runs Nuclei scans when new endpoints are discovered
- Scheduled Scans: Support for cron-based scheduled rescanning
- Flexible Configuration: Configurable templates, severity filters, and scan options
- Native Kubernetes Integration: Results stored as Kubernetes custom resources
- Owner References: Automatic cleanup when source resources are deleted
How It Works
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Ingress / │────▶│ Nuclei Operator │────▶│ NucleiScan │
│ VirtualService │ │ Controllers │ │ Resource │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Nuclei Engine │────▶│ Scan Results │
│ (Scanner) │ │ (Findings) │
└─────────────────┘ └─────────────────┘
- Watch: The operator watches for Ingress and VirtualService resources
- Extract: URLs are extracted from the resource specifications
- Create: A NucleiScan custom resource is created with the target URLs
- Scan: The Nuclei scanner executes security scans against the targets
- Store: Results are stored in the NucleiScan status for easy access
Prerequisites
- Kubernetes cluster v1.26+
- kubectl configured to access your cluster
- Istio (optional, required for VirtualService support)
- Container runtime (Docker, containerd, etc.)
Installation
Using kubectl/kustomize
- Install the CRDs:
make install
- Deploy the operator:
# Using the default image
make deploy IMG=ghcr.io/mortenolsen/nuclei-operator:latest
# Or build and deploy your own image
make docker-build docker-push IMG=<your-registry>/nuclei-operator:tag
make deploy IMG=<your-registry>/nuclei-operator:tag
Using a Single YAML File
Generate and apply a consolidated installation manifest:
# Generate the installer
make build-installer IMG=<your-registry>/nuclei-operator:tag
# Apply to your cluster
kubectl apply -f dist/install.yaml
Building from Source
# Clone the repository
git clone https://github.com/mortenolsen/nuclei-operator.git
cd nuclei-operator
# Build the binary
make build
# Build the container image
make docker-build IMG=<your-registry>/nuclei-operator:tag
# Push to your registry
make docker-push IMG=<your-registry>/nuclei-operator:tag
Quick Start
1. Deploy the Operator
make deploy IMG=ghcr.io/mortenolsen/nuclei-operator:latest
2. Create an Ingress Resource
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
namespace: default
spec:
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80
kubectl apply -f my-ingress.yaml
3. View the NucleiScan Results
The operator automatically creates a NucleiScan resource:
# List all NucleiScans
kubectl get nucleiscans
# View detailed scan results
kubectl describe nucleiscan my-app-ingress-scan
# Get scan findings in JSON format
kubectl get nucleiscan my-app-ingress-scan -o jsonpath='{.status.findings}'
Example output:
NAME PHASE FINDINGS SOURCE AGE
my-app-ingress-scan Completed 3 Ingress 5m
Configuration
Environment Variables
The operator can be configured using the following environment variables:
| Variable | Description | Default |
|---|---|---|
NUCLEI_BINARY_PATH |
Path to the Nuclei binary | nuclei |
NUCLEI_TEMPLATES_PATH |
Path to Nuclei templates directory | (uses Nuclei default) |
NUCLEI_TIMEOUT |
Default scan timeout | 30m |
NucleiScan Spec Options
| Field | Type | Description |
|---|---|---|
sourceRef |
SourceReference | Reference to the source Ingress/VirtualService |
targets |
[]string | List of URLs to scan |
templates |
[]string | Nuclei templates to use (optional) |
severity |
[]string | Severity filter: info, low, medium, high, critical |
schedule |
string | Cron schedule for periodic scans (optional) |
suspend |
bool | Suspend scheduled scans |
Example NucleiScan
apiVersion: nuclei.homelab.mortenolsen.pro/v1alpha1
kind: NucleiScan
metadata:
name: my-security-scan
namespace: default
spec:
sourceRef:
apiVersion: networking.k8s.io/v1
kind: Ingress
name: my-ingress
namespace: default
uid: "abc123"
targets:
- https://myapp.example.com
- https://api.example.com
severity:
- medium
- high
- critical
templates:
- cves/
- vulnerabilities/
schedule: "@every 24h"
suspend: false
CRD Reference
NucleiScan
The NucleiScan custom resource represents a security scan configuration and its results.
Short names: ns, nscan
Print columns:
Phase: Current scan phase (Pending, Running, Completed, Failed)Findings: Total number of findingsSource: Source resource kind (Ingress/VirtualService)Age: Resource age
For detailed API documentation, see docs/api.md.
Development
Prerequisites
- Go 1.24+
- Docker or Podman
- kubectl
- Access to a Kubernetes cluster (kind, minikube, or remote)
Building the Project
# Generate manifests and code
make manifests generate
# Build the binary
make build
# Run tests
make test
# Run linter
make lint
Running Locally
# Install CRDs
make install
# Run the operator locally (outside the cluster)
make run
Running Tests
# Unit tests
make test
# End-to-end tests (requires Kind)
make test-e2e
Project Structure
nuclei-operator/
├── api/v1alpha1/ # CRD type definitions
├── cmd/ # Main entry point
├── config/ # Kubernetes manifests
│ ├── crd/ # CRD definitions
│ ├── default/ # Default kustomization
│ ├── manager/ # Operator deployment
│ ├── rbac/ # RBAC configuration
│ └── samples/ # Example resources
├── internal/
│ ├── controller/ # Reconciliation logic
│ └── scanner/ # Nuclei scan execution
└── test/ # Test suites
Troubleshooting
Common Issues
Operator not creating NucleiScan resources
-
Check operator logs:
kubectl logs -n nuclei-operator-system deployment/nuclei-operator-controller-manager -
Verify RBAC permissions:
kubectl auth can-i list ingresses --as=system:serviceaccount:nuclei-operator-system:nuclei-operator-controller-manager -
Ensure the Ingress has valid hosts defined
Scans stuck in Pending/Running state
- Check if Nuclei binary is available in the container
- Verify network connectivity to scan targets
- Check for timeout issues in operator logs
No findings in completed scans
- Verify targets are accessible from the operator pod
- Check if severity filters are too restrictive
- Ensure Nuclei templates are properly configured
Debugging Tips
# View operator logs
kubectl logs -f -n nuclei-operator-system deployment/nuclei-operator-controller-manager
# Check NucleiScan status
kubectl describe nucleiscan <scan-name>
# View events
kubectl get events --field-selector involvedObject.kind=NucleiScan
# Check operator metrics
kubectl port-forward -n nuclei-operator-system svc/nuclei-operator-controller-manager-metrics-service 8080:8080
curl localhost:8080/metrics
Uninstallation
# Remove all NucleiScan resources
kubectl delete nucleiscans --all --all-namespaces
# Undeploy the operator
make undeploy
# Remove CRDs
make uninstall
Documentation
- Architecture - Detailed architecture documentation
- API Reference - Complete CRD API reference
- User Guide - Detailed usage instructions
- Contributing - Contribution guidelines
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
License
Copyright 2025.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Acknowledgments
- Nuclei - The vulnerability scanner powering this operator
- Kubebuilder - Framework used to build this operator
- controller-runtime - Kubernetes controller library