mirror of
https://github.com/morten-olsen/homelab-nuclei-operator.git
synced 2026-02-08 02:16:23 +01:00
init
This commit is contained in:
381
README.md
Normal file
381
README.md
Normal file
@@ -0,0 +1,381 @@
|
||||
# Nuclei Operator
|
||||
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://goreportcard.com/report/github.com/mortenolsen/nuclei-operator)
|
||||
|
||||
A Kubernetes operator that automates security scanning of web applications exposed through Kubernetes Ingress resources and Istio VirtualService CRDs using [Nuclei](https://github.com/projectdiscovery/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) │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
1. **Watch**: The operator watches for Ingress and VirtualService resources
|
||||
2. **Extract**: URLs are extracted from the resource specifications
|
||||
3. **Create**: A NucleiScan custom resource is created with the target URLs
|
||||
4. **Scan**: The Nuclei scanner executes security scans against the targets
|
||||
5. **Store**: Results are stored in the NucleiScan status for easy access
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Kubernetes cluster v1.26+
|
||||
- kubectl configured to access your cluster
|
||||
- [Istio](https://istio.io/) (optional, required for VirtualService support)
|
||||
- Container runtime (Docker, containerd, etc.)
|
||||
|
||||
## Installation
|
||||
|
||||
### Using kubectl/kustomize
|
||||
|
||||
1. **Install the CRDs:**
|
||||
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
|
||||
2. **Deploy the operator:**
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
make deploy IMG=ghcr.io/mortenolsen/nuclei-operator:latest
|
||||
```
|
||||
|
||||
### 2. Create an Ingress Resource
|
||||
|
||||
```yaml
|
||||
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
|
||||
```
|
||||
|
||||
```bash
|
||||
kubectl apply -f my-ingress.yaml
|
||||
```
|
||||
|
||||
### 3. View the NucleiScan Results
|
||||
|
||||
The operator automatically creates a NucleiScan resource:
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```yaml
|
||||
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 findings
|
||||
- `Source`: Source resource kind (Ingress/VirtualService)
|
||||
- `Age`: Resource age
|
||||
|
||||
For detailed API documentation, see [docs/api.md](docs/api.md).
|
||||
|
||||
## Development
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Go 1.24+
|
||||
- Docker or Podman
|
||||
- kubectl
|
||||
- Access to a Kubernetes cluster (kind, minikube, or remote)
|
||||
|
||||
### Building the Project
|
||||
|
||||
```bash
|
||||
# Generate manifests and code
|
||||
make manifests generate
|
||||
|
||||
# Build the binary
|
||||
make build
|
||||
|
||||
# Run tests
|
||||
make test
|
||||
|
||||
# Run linter
|
||||
make lint
|
||||
```
|
||||
|
||||
### Running Locally
|
||||
|
||||
```bash
|
||||
# Install CRDs
|
||||
make install
|
||||
|
||||
# Run the operator locally (outside the cluster)
|
||||
make run
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
1. Check operator logs:
|
||||
```bash
|
||||
kubectl logs -n nuclei-operator-system deployment/nuclei-operator-controller-manager
|
||||
```
|
||||
|
||||
2. Verify RBAC permissions:
|
||||
```bash
|
||||
kubectl auth can-i list ingresses --as=system:serviceaccount:nuclei-operator-system:nuclei-operator-controller-manager
|
||||
```
|
||||
|
||||
3. Ensure the Ingress has valid hosts defined
|
||||
|
||||
#### Scans stuck in Pending/Running state
|
||||
|
||||
1. Check if Nuclei binary is available in the container
|
||||
2. Verify network connectivity to scan targets
|
||||
3. Check for timeout issues in operator logs
|
||||
|
||||
#### No findings in completed scans
|
||||
|
||||
1. Verify targets are accessible from the operator pod
|
||||
2. Check if severity filters are too restrictive
|
||||
3. Ensure Nuclei templates are properly configured
|
||||
|
||||
### Debugging Tips
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# Remove all NucleiScan resources
|
||||
kubectl delete nucleiscans --all --all-namespaces
|
||||
|
||||
# Undeploy the operator
|
||||
make undeploy
|
||||
|
||||
# Remove CRDs
|
||||
make uninstall
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
- [Architecture](ARCHITECTURE.md) - Detailed architecture documentation
|
||||
- [API Reference](docs/api.md) - Complete CRD API reference
|
||||
- [User Guide](docs/user-guide.md) - Detailed usage instructions
|
||||
- [Contributing](CONTRIBUTING.md) - Contribution guidelines
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please see [CONTRIBUTING.md](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](https://github.com/projectdiscovery/nuclei) - The vulnerability scanner powering this operator
|
||||
- [Kubebuilder](https://book.kubebuilder.io/) - Framework used to build this operator
|
||||
- [controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) - Kubernetes controller library
|
||||
Reference in New Issue
Block a user