Improve NetworkPolicy to isolate Grafana
LeoFVO opened this issue · comments
Looking at the cluster internal communication, I found that Grafana isn't isolate at all from others resources (network scoped).
This leads me to ask, "Why should Grafana have ingress fully open ?" Because as we all know, Grafana is pull-based, so it pull metrics from others but no one is pushing to him (by default) except the dashboard frontend.
What is missing?
We could improve the isolation of Grafana by allowing only dashboard/ingress to ingress.
Not necessary to put it by default in the helm charts, but maybe community search for this configuration, so I propose it here.
Why do we need it?
Improve cluster security overall.
Actual network policies in the Helm Charts only allow ingress from Prometheus (isn't really useful as we pull from and not receiving)
Example
I built a network policy more restrictive allowing only my ingress to ingress on Grafana, and egress is only allowed for Grafana dependencies or pulling Prometheus/AlertManager.
Here is the YAML if you want to do the same:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: grafana-isolation-ingress-egress
namespace: monitoring
spec:
podSelector:
matchLabels:
app.kubernetes.io/instance: kube-prometheus-stack
app.kubernetes.io/name: grafana
policyTypes:
- Ingress
- Egress
ingress:
# Allow access to grafana only from the ingress
# We don't need to reach grafana from the cluster as it's pull-based metrics
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
podSelector:
matchLabels:
app.kubernetes.io/instance: ingress-nginx
ports:
- protocol: TCP
port: 80 # Grafana dashboard
- protocol: TCP
port: 3000 # Grafana needed port
egress:
# Allow egress to all IP addresses (for DNS)
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
# Allow egress to specific IP (e.g., 10.100.0.1)
# This is kubernetes apiserver endpoint (dependencies)
- to:
- ipBlock:
cidr: 10.100.0.1/32
ports:
- protocol: TCP
port: 443
- protocol: TCP
port: 80
# Allow egress to pull prometheus
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: prometheus
operator.prometheus.io/name: kube-prometheus-stack-prometheus
ports:
- port: 9090
protocol: TCP
# Allow egress to pull alertmanager
- to:
- podSelector:
matchLabels:
alertmanager: kube-prometheus-stack-alertmanager
app.kubernetes.io/name: alertmanager
ports:
- port: 9093
protocol: TCP
```
If you have some improvements, I will be glad to update the issues :)