Kubernetes Network Policy Security: 6 Defense Patterns from Default Deny to Zero Trust
Is Your K8s Cluster Running Naked on the Network?
A default Kubernetes cluster allows all Pods to communicate freely—frontend Pods can directly access database Pods, test namespaces can reach production namespaces, and a compromised Pod can laterally move to any service in the cluster. In 2025, a financial company suffered a breach through a Pod with no network policy; the attacker moved laterally to the payment system within 30 minutes and stole 2 million user records. This isn't a movie plot—it's a real security incident.
Kubernetes NetworkPolicy is the cornerstone of cluster network security. From default deny to micro-segmentation, from Cilium eBPF to zero trust architecture, this article covers 6 defense patterns to ensure your cluster network is no longer exposed.
Core Concepts at a Glance
| Concept | Description | Keywords |
|---|---|---|
| NetworkPolicy | K8s native network policy resource, controls inter-Pod traffic | ingress/egress, selector |
| Default Deny | Deny all traffic by default, explicitly allow legitimate traffic | whitelist, zero trust foundation |
| Micro-segmentation | Fine-grained network isolation based on labels | label selectors, namespace isolation |
| Cilium | eBPF-based CNI plugin supporting L3-L7 policies | eBPF, L7 policies, observability |
| eBPF | Kernel-level programmable technology for high-performance network filtering | kernel-space, zero-copy, XDP |
| mTLS | Mutual TLS authentication for encrypted service-to-service communication | cert rotation, identity verification |
| Zero Trust | Zero trust network architecture: never trust, always verify | continuous verification, least privilege |
Deep Analysis: 5 Major K8s Network Security Challenges
| Challenge | Current State | Risk Level | Root Cause |
|---|---|---|---|
| Default allow-all | No network restrictions between Pods in cluster | 🔴 Critical | K8s doesn't set NetworkPolicy by default |
| Lateral movement | Attacker can access all services after breaching one Pod | 🔴 Critical | Lack of micro-segmentation policies |
| Policy explosion | NetworkPolicy count spirals out of control in large clusters | 🟡 Medium | Poor label design |
| DNS dependency | Service discovery relies on CoreDNS, DNS policies missing | 🟡 Medium | Overlooking DNS-layer security |
| Poor observability | Network policy effectiveness hard to verify and audit | 🟠 High | Lack of policy audit tools |
Pattern 1: Default Deny All Traffic
Default deny is the first step toward zero trust networking. In any namespace without NetworkPolicy, all Pods can communicate freely—this is the most dangerous state.
Namespace-Level Default Deny
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Allow DNS Resolution (Required for Egress)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Batch Default Deny for All Namespaces
#!/bin/bash
NAMESPACES=$(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}')
for ns in $NAMESPACES; do
if [ "$ns" = "kube-system" ] || [ "$ns" = "kube-public" ]; then
echo "Skipping system namespace: $ns"
continue
fi
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: $ns
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
EOF
echo "Applied default-deny-all to namespace: $ns"
done
Verify Default Deny Policies
kubectl get networkpolicy -n production
kubectl describe networkpolicy default-deny-all -n production
kubectl run test-client --image=busybox:1.36 -n production --rm -it -- \
wget -qO- --timeout=2 http://api-service.production.svc.cluster.local:8080
Pattern 2: Label-Based Micro-Segmentation
Micro-segmentation uses label selectors for fine-grained Pod access control—the core capability of NetworkPolicy.
Three-Tier Application Micro-Segmentation
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-policy
namespace: production
spec:
podSelector:
matchLabels:
app: web
tier: frontend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
env: production
podSelector:
matchLabels:
app: ingress-nginx
ports:
- protocol: TCP
port: 8080
- protocol: TCP
port: 8443
egress:
- to:
- podSelector:
matchLabels:
app: api
tier: backend
ports:
- protocol: TCP
port: 8080
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: production
spec:
podSelector:
matchLabels:
app: api
tier: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: web
tier: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: postgres
tier: database
ports:
- protocol: TCP
port: 5432
- to:
- podSelector:
matchLabels:
app: redis
tier: cache
ports:
- protocol: TCP
port: 6379
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-policy
namespace: production
spec:
podSelector:
matchLabels:
tier: database
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: api
tier: backend
ports:
- protocol: TCP
port: 5432
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
Cross-Namespace Policies
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-monitoring
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
purpose: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 9090
Namespace Label Management
kubectl label namespace monitoring purpose=monitoring
kubectl label namespace staging env=staging
kubectl label namespace production env=production
kubectl label namespace kube-system kubernetes.io/metadata.name=kube-system
kubectl get namespaces --show-labels
Pattern 3: Cilium eBPF Advanced Network Policy
Cilium leverages eBPF to break through K8s native NetworkPolicy L3/L4 limitations, supporting L7 HTTP/gRPC/Kafka protocol policies.
Install Cilium
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium \
--namespace kube-system \
--set kubeProxyReplacement=strict \
--set hubble.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true \
--set operator.prometheus.enabled=true
L7 HTTP Policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: l7-http-policy
namespace: production
spec:
endpointSelector:
matchLabels:
app: api
tier: backend
ingress:
- fromEndpoints:
- matchLabels:
app: web
tier: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET
path: "/api/v1/.*"
- method: POST
path: "/api/v1/orders"
- method: PUT
path: "/api/v1/orders/.*"
Kafka Protocol Policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: kafka-policy
namespace: production
spec:
endpointSelector:
matchLabels:
app: kafka
ingress:
- fromEndpoints:
- matchLabels:
app: order-service
toPorts:
- ports:
- port: "9092"
protocol: TCP
rules:
kafka:
- role: produce
topic: orders
- role: consume
topic: orders
- fromEndpoints:
- matchLabels:
app: payment-service
toPorts:
- ports:
- port: "9092"
protocol: TCP
rules:
kafka:
- role: produce
topic: payments
- role: consume
topic: payments
DNS-Based Egress Policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: external-api-egress
namespace: production
spec:
endpointSelector:
matchLabels:
app: api
tier: backend
egress:
- toFQDNs:
- matchName: "api.stripe.com"
- matchName: "api.sendgrid.com"
- matchPattern: "*.amazonaws.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
rules:
dns:
- matchPattern: "*"
Hubble Observability
cilium hubble port-forward &
hubble observe --namespace production --since 1m
hubble observe --namespace production --label app=api --verdict DROPPED
hubble observe --namespace production --http-path "/api/v1/.*" --method GET
Pattern 4: DNS-Based Network Policies
Native NetworkPolicy doesn't support domain-based policies, but Cilium and Calico extend this capability for more flexible egress control.
Cilium FQDN Policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-external-services
namespace: production
spec:
endpointSelector:
matchLabels:
app: payment-service
egress:
- toFQDNs:
- matchName: "api.stripe.com"
- matchName: "api.paypal.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
- toFQDNs:
- matchName: "s3.amazonaws.com"
- matchPattern: "*.s3.amazonaws.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
rules:
dns:
- matchPattern: "*"
Calico GlobalNetworkPolicy DNS Policy
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: allow-external-dns
spec:
selector: app == "payment-service"
order: 100
types:
- Egress
egress:
- action: Allow
protocol: TCP
destination:
domains:
- "api.stripe.com"
- "api.paypal.com"
ports:
- 443
- action: Allow
protocol: UDP
destination:
selector: k8s-app == "kube-dns"
ports:
- 53
DNS Policy Monitoring
cilium hubble observe --dns --namespace production
cilium hubble observe --fqdn "api.stripe.com" --namespace production
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=100
kubectl get endpoints kube-dns -n kube-system
Pattern 5: Service Mesh mTLS
Service mesh implements automatic mTLS through sidecar proxies, providing encryption and identity verification for service-to-service communication.
Istio Strict mTLS Mode
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mtls:
mode: STRICT
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: backend-mtls
namespace: production
spec:
selector:
matchLabels:
tier: backend
mtls:
mode: STRICT
portLevelMtls:
8080:
mode: STRICT
Istio AuthorizationPolicy
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: backend-authz
namespace: production
spec:
selector:
matchLabels:
app: api
tier: backend
rules:
- from:
- source:
principals:
- "cluster.local/ns/production/sa/frontend"
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/v1/*"]
- from:
- source:
namespaces: ["monitoring"]
principals:
- "cluster.local/ns/monitoring/sa/prometheus"
to:
- operation:
methods: ["GET"]
paths: ["/metrics"]
Cilium Cluster Mesh mTLS
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: allow-mtls-traffic
spec:
endpointSelector: {}
ingress:
- fromRequires:
- matchLabels:
io.cilium.k8s.policy.serviceaccount: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
ingress:
- fromEndpoints:
- matchLabels:
io.cilium.k8s.policy.serviceaccount: monitoring
toPorts:
- ports:
- port: "9090"
protocol: TCP
Certificate Management
istioctl analyze -n production
istioctl proxy-config secret deploy/frontend.production
kubectl get certificates -n production
kubectl describe certificate backend-cert -n production
kubectl logs -n istio-system -l app=citadel --tail=50
Pattern 6: Zero Trust Network Architecture Blueprint
Zero trust isn't a single technology—it's a security architecture philosophy: never trust, always verify, least privilege.
Zero Trust Network Architecture Layering
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: zero-trust-foundation
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector: {}
ports: []
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Zero Trust Identity Layer
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: identity-based-policy
namespace: production
spec:
endpointSelector:
matchLabels:
app: api
tier: backend
env: production
ingress:
- fromRequires:
- matchLabels:
app: web
tier: frontend
env: production
io.cilium.k8s.policy.serviceaccount: frontend-sa
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET
path: "/api/v1/.*"
- method: POST
path: "/api/v1/orders"
Zero Trust Audit Layer
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
resources:
- group: networking.k8s.io
resources: ["networkpolicies"]
verbs: ["create", "update", "delete"]
- level: Metadata
resources:
- group: cilium.io
resources: ["ciliumnetworkpolicies", "ciliumclusterwidenetworkpolicies"]
verbs: ["create", "update", "delete"]
Zero Trust Observability
cilium hubble observe --namespace production --type trace --type drop
cilium hubble observe --verdict DROPPED --since 5m --namespace production
kubectl get ciliumnetworkpolicies -A
kubectl get ciliumclusterwidenetworkpolicies
kubectl get networkpolicies -A
cilium connectivity test --namespace production
Zero Trust Architecture Verification Script
#!/bin/bash
echo "=== Zero Trust Network Audit ==="
echo "[1] Checking default deny policies..."
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
count=$(kubectl get networkpolicy -n "$ns" 2>/dev/null | grep -c "default-deny" || true)
if [ "$count" -eq 0 ] && [ "$ns" != "kube-system" ]; then
echo " WARNING: No default-deny policy in namespace: $ns"
fi
done
echo "[2] Checking mTLS status..."
istioctl proxy-config secret -n production 2>/dev/null || echo " Istio not installed or no proxies found"
echo "[3] Checking Cilium policy status..."
cilium policy get 2>/dev/null || echo " Cilium not available"
echo "[4] Checking for overly permissive policies..."
kubectl get networkpolicies -A -o json | \
python3 -c "
import json, sys
policies = json.load(sys.stdin)
for p in policies.get('items', []):
ns = p['metadata']['namespace']
name = p['metadata']['name']
ingress = p.get('spec', {}).get('ingress', [])
for i in ingress:
if not i.get('from') and not i.get('ports'):
print(f' WARNING: {ns}/{name} has empty ingress from selector')
egress = p.get('spec', {}).get('egress', [])
for e in egress:
if not e.get('to') and not e.get('ports'):
print(f' WARNING: {ns}/{name} has empty egress to selector')
"
echo "=== Audit Complete ==="
5 Common Pitfalls
Pitfall 1: Forgetting to Allow DNS Traffic
# ❌ Wrong: After denying all egress, DNS resolution also fails
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
# ✅ Correct: Must explicitly allow DNS egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Pitfall 2: Missing Namespace Labels
# ❌ Wrong: namespaceSelector matches no namespaces
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring
spec:
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
purpose: monitoring
# ✅ Correct: Label the namespace first
# kubectl label namespace monitoring purpose=monitoring
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring
spec:
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
purpose: monitoring
podSelector:
matchLabels:
app: prometheus
Pitfall 3: CNI Doesn't Support NetworkPolicy
# ❌ Wrong: Flannel doesn't support NetworkPolicy, policies won't take effect
# Using flannel as CNI
# ✅ Correct: Use a NetworkPolicy-capable CNI
# kubectl get pods -n kube-system -l k8s-app=calico-node
# kubectl get pods -n kube-system -l k8s-app=cilium
# kubectl get pods -n kube-system -l app=antrea
Pitfall 4: Policy Ordering Causes Override
# ❌ Wrong: Allow policy first then deny policy—deny doesn't override allow
# NetworkPolicy is additive with no priority concept
# ✅ Correct: NetworkPolicy uses a whitelist model, all policies are additive
# For priority, use Calico GlobalNetworkPolicy or Cilium policies
# Calico supports the order field for priority control
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: deny-suspicious
spec:
order: 50
selector: all()
types:
- Ingress
ingress:
- action: Deny
source:
selector: app == "compromised-service"
Pitfall 5: Ignoring the kube-system Namespace
# ❌ Wrong: Applying default deny to kube-system breaks cluster functionality
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: kube-system
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
# ✅ Correct: kube-system needs special handling—allow necessary traffic
# Skip default deny for kube-system namespace
# Or set precise allow policies for critical components in kube-system
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: kube-system-allow
namespace: kube-system
spec:
podSelector:
matchLabels:
k8s-app: kube-dns
policyTypes:
- Ingress
ingress:
- from: []
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Error Troubleshooting Table
| Error Symptom | Possible Cause | Diagnostic Command | Solution |
|---|---|---|---|
| Pods can't communicate | Default deny policy too restrictive | kubectl get networkpolicy -A |
Add precise ingress/egress rules |
| Service discovery fails | DNS egress blocked | kubectl exec -it <pod> -- nslookup api-service |
Add DNS egress allow rule |
| NetworkPolicy not taking effect | CNI doesn't support it | kubectl get pods -n kube-system -l k8s-app |
Switch to Calico/Cilium/Antrea |
| Cross-namespace access denied | Namespace missing labels | kubectl get ns --show-labels |
Add required labels to namespace |
| Hubble can't observe | Cilium Hubble not enabled | cilium status |
Enable Hubble during Helm install |
| mTLS connection fails | Certificate expired or not issued | istioctl proxy-config secret <pod> |
Check Certificate resource status |
| L7 policy not working | Cilium version too low | cilium version |
Upgrade to Cilium 1.14+ |
| DNS policy not working | CoreDNS version too low | kubectl get deploy coredns -n kube-system -o yaml |
Upgrade CoreDNS |
| Policy count explosion | Poor label design | kubectl get networkpolicy -A | wc -l |
Redesign label taxonomy |
| Calico policy conflicts | GlobalNetworkPolicy priority issues | calicoctl get globalnetworkpolicy -o yaml |
Adjust order field |
Advanced Optimization
Policy as Code (PaC)
Manage NetworkPolicy with GitOps to ensure policy changes go through code review:
git checkout -b feature/add-network-policy
mkdir -p k8s/network-policies/production
cat > k8s/network-policies/production/default-deny.yaml << 'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
EOF
git add . && git commit -m "feat: add default deny policy for production"
git push origin feature/add-network-policy
Automated Policy Testing
cilium connectivity test \
--test "echo-ingress-l7" \
--namespace production \
--force-deploy
kubectl run policy-test \
--image=busybox:1.36 \
-n production \
--rm -it -- \
wget -qO- --timeout=2 http://api-service:8080/healthz
kubectl run dns-test \
--image=busybox:1.36 \
-n production \
--rm -it -- \
nslookup api-service.production.svc.cluster.local
Policy Performance Optimization
cilium config | grep policy
cilium bpf policy list
kubectl get ciliumnetworkpolicies -A -o json | \
python3 -c "
import json, sys
policies = json.load(sys.stdin)
print(f'Total CiliumNetworkPolicies: {len(policies.get(\"items\", []))}')
for p in policies.get('items', []):
ns = p['metadata']['namespace']
name = p['metadata']['name']
ingress = len(p.get('spec', {}).get('ingress', []))
egress = len(p.get('spec', {}).get('egress', []))
print(f' {ns}/{name}: ingress={ingress}, egress={egress}')
"
CNI Plugin Comparison
| Feature | Calico | Cilium | Antrea | Weave Net |
|---|---|---|---|---|
| NetworkPolicy support | ✅ Full | ✅ Full+L7 | ✅ Full | ⚠️ Basic |
| L7 policies | ❌ | ✅ HTTP/gRPC/Kafka | ❌ | ❌ |
| FQDN policies | ✅ | ✅ | ❌ | ❌ |
| eBPF dataplane | ✅ Optional | ✅ Default | ✅ Optional | ❌ |
| Observability | ❌ | ✅ Hubble | ⚠️ Flow Exporter | ❌ |
| Encryption | ✅ WireGuard | ✅ WireGuard/IPsec | ✅ IPsec | ✅ IPsec |
| Performance | High | Very High | High | Medium |
| Multi-cluster | ✅ | ✅ Cluster Mesh | ✅ | ❌ |
| Service Mesh | ❌ | ✅ Built-in | ❌ | ❌ |
| Community activity | High | Very High | High | Low |
| Use case | General production | High perf + L7 | vSphere environments | Dev/test |
Summary
Kubernetes network security isn't built overnight—it's a progressive hardening process. Start with default deny, implement micro-segmentation step by step, introduce Cilium eBPF for L7 capabilities, control external access through DNS policies, leverage service mesh for mTLS, and ultimately build a zero trust network architecture. Each step shrinks the attack surface; each layer adds defense depth. Remember: a K8s cluster without NetworkPolicy is an attacker's playground.
Recommended Tools
- JSON Formatter — Format NetworkPolicy YAML/JSON configurations
- Base64 Encode — Encode certificates and key data
- Hash Calculator — Calculate config file hashes for integrity verification
Try these browser-local tools — no sign-up required →