A CLI tool that generates CiliumNetworkPolicies from Hubble flow data. This tool analyzes network traffic patterns captured by Hubble and automatically creates corresponding Cilium network policies.
- Automatic Policy Generation: Reads Hubble flow JSON files and generates CiliumNetworkPolicy YAML files
- Smart Label Filtering: Extracts only relevant app labels (
app.kubernetes.io/name,app.kubernetes.io/component,app.kubernetes.io/instance) with fallback toapplabel - Cross-Namespace Support: Automatically adds namespace labels for cross-namespace traffic
- FQDN Egress Support: Generates proper
toFQDNsrules with required DNS resolution rules for external traffic - Flow Aggregation: Combines multiple flows with the same source/destination into a single policy with multiple ports
- HTTP Server Mode: Run as a containerized service to generate policies via HTTP API
Note: This project was created with the help of AI. While I have extensive experience with Kubernetes and Cilium, I do not have the Go programming expertise to write this tool from scratch—AI assistance made it possible to bring this idea to life and share it with the community.
Caution: Please be careful when using this tool in production environments. Always review generated policies before applying them to your cluster.
Clone the repository and build the binary:
# Clone the repository
git clone <repository-url>
cd cf2cnp
# Build the binary
go build -o cf2cnp ./cmd/cf2cnp
# Or on Windows
go build -o cf2cnp.exe ./cmd/cf2cnpThe tool supports two modes of operation:
Generate policies from flow files in a directory:
cf2cnp generate --input <input-directory> --output <output-directory>| Flag | Short | Description | Required |
|---|---|---|---|
--input |
-i |
Directory containing Hubble flow JSON files | Yes |
--output |
-o |
Directory for generated CiliumNetworkPolicy YAML files | Yes |
# Generate policies from example flows
cf2cnp generate --input ./example-flows --output ./generated-policiesStart an HTTP server to generate policies via API:
cf2cnp serve --port 8080| Flag | Short | Description | Default |
|---|---|---|---|
--port |
-p |
Port to listen on | 8080 |
| Method | Endpoint | Description |
|---|---|---|
POST |
/generate |
Send Hubble flow JSON, receive CiliumNetworkPolicy YAML |
GET |
/health |
Health check endpoint |
GET |
/ |
Web UI for testing |
# Generate a policy from a flow file
curl -X POST http://localhost:8080/generate \
-H "Content-Type: application/json" \
-d @flow.json \
-o policy.yamlOpen http://localhost:8080 in your browser to access the web interface where you can paste flow JSON and download the generated policy.
docker build -t cf2cnp .docker run -p 8080:8080 cf2cnpThe server will be available at http://localhost:8080.
The tool expects Hubble flow data in JSON format. Each file should contain a single flow object with the following structure:
{
"flow": {
"traffic_direction": "INGRESS",
"source": {
"namespace": "source-namespace",
"labels": ["k8s:app.kubernetes.io/name=source-service", "k8s:app.kubernetes.io/component=source-component"]
},
"destination": {
"namespace": "destination-namespace",
"labels": ["k8s:app.kubernetes.io/name=source-service"]
},
"destination_names": ["onzack.com"],
"l4": {
"TCP": {
"destination_port": 80
}
}
}
}You can export flows from Hubble using the Hubble CLI:
# Observe flows and save to JSON
hubble observe --output json > flows.json
# Or filter for specific traffic
hubble observe --namespace my-namespace --output json > my-flows.jsonThe generated CiliumNetworkPolicy files follow the Cilium Network Policy specification.
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: destination-service
namespace: destination-namespace
spec:
description: Allow ingress traffic from source-namespace to destination-namespace for the destination-service
endpointSelector:
matchLabels:
app.kubernetes.io/component: destination-component
app.kubernetes.io/name: destination-service
ingress:
- fromEndpoints:
- matchLabels:
app.kubernetes.io/name: source-service
io.kubernetes.pod.namespace: source-namespace
toPorts:
- ports:
- port: "80"
protocol: TCPFor external traffic (to "world"), the tool automatically includes DNS resolution rules:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: source-service
namespace: source-namespace
spec:
description: Allow egress traffic from source-namespace to onzack.com for the source-service
endpointSelector:
matchLabels:
app.kubernetes.io/name: source-service
egress:
- toFQDNs:
- matchName: onzack.com
toPorts:
- ports:
- port: "443"
protocol: TCP
# DNS resolution rule (required for toFQDNs to work)
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
rules:
dns:
- matchPattern: '*'For those times when you just need to get things working in development, CF2CNP includes a YOLO mode that generates a policy allowing all traffic within a namespace.
# Generate a YOLO policy for the default namespace
cf2cnp yolo ns
# Generate a YOLO policy for a specific namespace
cf2cnp yolo ns --namespace my-dev-namespaceSend a POST request with the body yolo ns <namespace>:
# YOLO policy for the default namespace
curl -X POST http://localhost:8080/generate \
-d "yolo ns" \
-o yolo-policy.yaml
# YOLO policy for a specific namespace
curl -X POST http://localhost:8080/generate \
-d "yolo ns my-dev-namespace" \
-o yolo-policy.yamlThe YOLO policy allows all ingress and egress traffic within the specified namespace:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: yolo-allow-all-in-namespace
namespace: my-dev-namespace
spec:
description: YOLO! Allow all traffic within the my-dev-namespace namespace.
endpointSelector:
matchLabels: {}
ingress:
- fromEndpoints:
- matchLabels: {}
egress:
- toEndpoints:
- matchLabels: {}The tool filters labels to keep policies clean and maintainable:
-
Priority Labels (used if present):
app.kubernetes.io/nameapp.kubernetes.io/componentapp.kubernetes.io/instance
-
Fallback Label (used if no priority labels exist):
appk8s-appnamecomponentinstance
Apache License 2.0 - see LICENSE for details.