A Kubernetes webhook service that automatically updates FortiWeb WAF server policies when Ingress resources are modified. This webhook integrates with the FortiWeb ingress controller to maintain synchronized certificate configurations.
This webhook listens for Kubernetes Ingress Updated
events and automatically configures FortiWeb server policies with the appropriate intermediate certificate groups based on Ingress annotations. It provides seamless integration between Kubernetes certificate management and FortiWeb WAF security policies.
- Automatic Policy Updates: Updates FortiWeb server policies when Ingress resources change
- Certificate Integration: Synchronizes intermediate certificate groups from Ingress annotations
- Retry Logic: Robust error handling with exponential backoff for API calls
- Kubernetes Native: Uses kubectl and Kubernetes APIs for resource access
- High Availability: Deployed with 2 replicas for reliability
- Kubernetes cluster with RBAC enabled
- FortiWeb WAF with REST API access
- Kubernetes secrets containing FortiWeb credentials
- Ingress resources with required annotations
# Add the Helm repository
helm repo add webhook https://amerintlxperts.github.io/webhook/
helm repo update
# Install the webhook
helm install webhook webhook/webhook
# Or install from local charts
helm install webhook ./charts/webhook
# Apply Kubernetes manifests
kubectl apply -f charts/webhook/templates/
# Verify deployment
kubectl get pods -l app.kubernetes.io/name=webhook-instance
For the webhook to process an Ingress resource, it must include these annotations:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# Certificate group to assign to server policy
server-policy-intermediate-certificate-group: "intermediate-cert-group-1"
# FortiWeb management interface details
fortiweb-ip: "10.0.1.100"
fortiweb-port: "8443"
# Kubernetes secret containing FortiWeb credentials
fortiweb-login: "fortiweb-admin-secret"
spec:
# ... ingress configuration
Create a Kubernetes secret with FortiWeb authentication credentials:
kubectl create secret generic fortiweb-admin-secret \
--from-literal=username='admin' \
--from-literal=password='your-password'
Customize the deployment using Helm values:
# values.yaml
image:
repository: ghcr.io/amerintlxperts/webhook
tag: "latest"
pullPolicy: Always
replicaCount: 2
service:
type: ClusterIP
port: 8080
# Deploy to system node pool
nodeSelector:
system-pool: "true"
tolerations:
- key: "CriticalAddonsOnly"
operator: "Equal"
value: "true"
effect: "NoSchedule"
- Event Reception: Webhook receives HTTP POST with Ingress event metadata
- Annotation Extraction: Fetches Ingress annotations using kubectl
- Credential Retrieval: Reads FortiWeb credentials from Kubernetes secret
- Policy Verification: Checks if server policy exists in FortiWeb
- Policy Update: Updates server policy with certificate group configuration
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Kubernetes │───▶│ Webhook │───▶│ FortiWeb │
│ Ingress │ │ Handler │ │ Server Policy │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
│ │ │
Annotations kubectl API REST API
- cert-group - Get ingress - Check policy
- fortiweb-ip - Get secret - Update policy
- fortiweb-port - Extract creds - Retry logic
- fortiweb-login
# Run the webhook server
node server.js
# Test webhook endpoint
curl -X POST http://localhost:8080 \
-H "Content-Type: application/json" \
-d '{
"eventmeta": {
"kind": "Ingress",
"reason": "Updated",
"namespace": "default",
"name": "test-ingress"
}
}'
# Build container image
docker build -t webhook:latest .
# Run containerized webhook
docker run -p 8080:8080 webhook:latest
# Validate Helm templates
helm template webhook ./charts/webhook
# Package chart for distribution
helm package ./charts/webhook -d docs/
# Update repository index
helm repo index docs/ --url https://amerintlxperts.github.io/webhook/
# Publish to GitHub Pages
./doit.sh
POST /
- Process Ingress webhook events
Request Body:
{
"eventmeta": {
"kind": "Ingress",
"reason": "Updated",
"namespace": "example-namespace",
"name": "example-ingress"
}
}
Response:
{
"status": "ok",
"received": "..."
}
The webhook uses FortiWeb's REST API v2.0:
- Authentication: Base64 encoded JSON with username/password/vdom
- Policy Check:
GET /api/v2.0/cmdb/server-policy/policy?mkey={name}_{namespace}
- Policy Update:
PUT /api/v2.0/cmdb/server-policy/policy?mkey={name}_{namespace}
- RBAC Required: Webhook needs permissions to read Ingress resources and secrets
- Secure Credentials: FortiWeb credentials stored in Kubernetes secrets
- API Authentication: Uses FortiWeb's token-based authentication
- TLS Considerations: FortiWeb API calls use
--insecure
for self-signed certificates - Internal Traffic: Webhook runs as ClusterIP service for internal access only
- Container Security: Based on Alpine Linux for minimal attack surface
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: webhook-reader
rules:
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
# Check webhook pods
kubectl get pods -l app.kubernetes.io/name=webhook-instance
# View webhook logs
kubectl logs -l app.kubernetes.io/name=webhook-instance
# Test webhook endpoint
kubectl port-forward svc/webhook 8080:8080
curl -X POST http://localhost:8080 -d '{"test": "data"}'
Missing Annotations
- Ensure all required annotations are present on Ingress resources
- Verify annotation names match expected values
FortiWeb API Errors
- Check FortiWeb credentials in Kubernetes secret
- Verify FortiWeb IP and port accessibility
- Confirm server policy exists in FortiWeb
Permission Errors
- Validate webhook ServiceAccount has required RBAC permissions
- Check kubectl can access Ingress resources and secrets
- Modify chart version in
charts/webhook/Chart.yaml
- Update values or templates as needed
- Test changes with
helm template
- Package and publish with
./doit.sh
- Modify
server.js
for functionality changes - Update
Dockerfile
if needed - Build and test container image
- Update image tag in Helm values
This project is part of the 40docs platform ecosystem for documentation automation and Kubernetes security integration.