
Ich habe eine mehr oder weniger komplexe Microservice-Architektur, in der Apache Ignite als zustandslose Datenbank/Cache verwendet wird. Ignite Pod
ist das einzige Pod
seiner Art Namespace
und die Architektur muss ein Sicherheitsaudit bestehen, das sie nicht bestehen wird, wenn ich nicht die größtmögliche Einschränkung NetworkPolicy
für egress
den Datenverkehr anwende. Sie muss allen möglichen Datenverkehr einschränken, der von Ignite selbst nicht benötigt wird.
Zuerst dachte ich:Gut, Ignite leitet keinen Datenverkehr an andere Pod
Pods weiter (es gibt darin keine anderen Pods Namespace
), daher lässt sich dies problemlos erreichen, indem der gesamte egress
Datenverkehr dort eingeschränkt wird Namespace
, wo Ignite der einzige ist Pod
!...
Nun, das hat nicht wirklich gut funktioniert:
Jede egress
Regel, selbst wenn ich den Verkehr zu allen in der Ignite-Dokumentation genannten Ports zulasse, führt dazu, dass der Start mit einer Fehlermeldung fehlschlägt, IgniteSpiException
die besagt:Abrufen der IP-Adressen der Ignite-Pods fehlgeschlagen, Caused by: java.net.ConnectException: Operation timed out (Connection timed out)
.
Das Problem scheint zu sein,TcpDiscoveryKubernetsIpFinder
, insbesondere die Methode getRegisteredAddresses(...)
, die offensichtlich etwas ausgehenden Datenverkehr innerhalb der durchführt, Namespace
um IP-Adressen von Ignite-Knoten zu registrieren. Der Discovery-Port 47500 ist natürlich erlaubt, aber das ändert nichts an der Situation. Die Funktionalität von Ignite mit den anderen Pod
s von anderen Namespace
s funktioniert ohne egress
angewendete Regeln, was (für mich) bedeutet, dass die Konfiguration bezüglich ClusterRole
, ClusterRoleBinding
, a Service
in der Namespace
und die XML-Konfiguration von Ignite selbst usw. korrekt zu sein scheint. Sogar ingress
Regeln, die Datenverkehr aus anderen Namespaces einschränken, funktionieren wie erwartet und lassen genau den gewünschten Datenverkehr zu.
Dies sind die Richtlinien, die ich angewendet habe:
[FUNKTIONIERT, blockiert nur unerwünschten Verkehr]:
## Denies all Ingress traffic to all Pods in the Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress-in-cache-ns
namespace: cache-ns
spec:
# selecting nothing here will deny all traffic between pods in the namespace
podSelector:
matchLabels: {}
# traffic routes to be considered, here: incoming exclusively
policyTypes:
- Ingress
## Allows necessary ingress traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: netpol-cache-ns
namespace: cache-ns
# defines the pod(s) that this policy is targeting
spec:
policyTypes:
- Ingress
podSelector:
matchLabels:
app: ignite
# <----incoming traffic----
ingress:
- from:
- namespaceSelector:
matchLabels:
zone: somewhere-else
podSelector:
matchExpressions:
- key: app
operator: In
values: [some-pod, another-pod] # dummy names, these Pods don't matter at all
ports:
- port: 11211 # JDBC
protocol: TCP
- port: 47100 # SPI communication
protocol: TCP
- port: 47500 # SPI discovery (CRITICAL, most likely...)
protocol: TCP
- port: 10800 # SQL
protocol: TCP
# ----outgoing traffic---->
# NONE AT ALL
Wenn diese beiden angewendet werden, funktioniert alles einwandfrei, aber das Sicherheitsaudit wird etwas wie
Wo sind die Einschränkungen dafür egress
? Was passiert, wenn dieser Knoten über die zulässigen Routen gehackt wird, weil einer der Pods, die diese Routen verwenden, zuvor gehackt wurde? Dann kann es sein, dass er einen C&C-Server aufruft! Diese Konfiguration ist nicht zulässig, härten Sie Ihre Architektur!
[BLOCKIEREN des gewünschten/notwendigen Verkehrs]:
Generell sämtlichen Datenverkehr ablehnen...
## Denies all traffic to all Pods in the Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-traffic-in-cache-ns
namespace: cache-ns
spec:
# selecting nothing here will deny all traffic between pods in the namespace
podSelector:
matchLabels: {}
# traffic routes to be considered, here: incoming exclusively
policyTypes:
- Ingress
- Egress # <------ THIS IS THE DIFFERENCE TO THE WORKING ONE ABOVE
... und anschließend bestimmte Routen zulassen
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: netpol-cache-ns-egress
namespace: cache-ns
# defines the pod(s) that this policy is targeting
spec:
policyTypes:
- Egress
podSelector:
matchLabels:
app: ignite
----outgoing traffic---->
egress:
# [NOT SUFFICIENT]
# allow egress to this namespace at specific ports
- to:
- namespaceSelector:
matchLabels:
zone: cache-zone
ports:
- protocol: TCP
port: 10800
- protocol: TCP
port: 47100 # SPI communication
- protocol: TCP
port: 47500
# [NOT SUFFICIENT]
# allow dns resolution in general (no namespace or pod restriction)
- ports:
- protocol: TCP
port: 53
- protocol: UDP
port: 53
# [NOT SUFFICIENT]
# allow egress to the kube-system (label is present!)
- to:
- namespaceSelector:
matchLabels:
zone: kube-system
# [NOT SUFFICIENT]
# allow egress in this namespace and for the ignite pod
- to:
- namespaceSelector:
matchLabels:
zone: cache-zone
podSelector:
matchLabels:
app: ignite
# [NOT SUFFICIENT]
# allow traffic to the IP address of the ignite pod
- to:
- ipBlock:
cidr: 172.21.70.49/32 # won't work well since those addresses are dynamic
ports:
- port: 11211 # JDBC
protocol: TCP
- port: 47100 # SPI communication
protocol: TCP
- port: 47500 # SPI discovery (CRITICAL, most likely...)
protocol: TCP
- port: 49112 # JMX
protocol: TCP
- port: 10800 # SQL
protocol: TCP
- port: 8080 # REST
protocol: TCP
- port: 10900 # thin clients
protocol: TCP
Die verwendete Apache Ignite-Version ist 2.10.0
Nun lautet die Frage an alle Leser:
Wie kann ich Egress
innerhalb des Clusters auf ein absolutes Minimum beschränken Namespace
, damit Ignite startet und ordnungsgemäß funktioniert? Wäre es ausreichend, den Egress
Zugriff außerhalb des Clusters einfach zu verweigern?
Wenn Sie weitere yaml
S für eine fundierte Vermutung oder einen Hinweis benötigen, können Sie diese gerne in einem Kommentar anfordern.
Und entschuldigen Sie die Markierung, falls sie unangemessen erscheint, ich konnte das Tag nicht finden, kubernetes-networkpolicy
da es auf Stackoverflow vorhanden ist.
AKTUALISIEREN:
Ausführen nslookup -debug kubernetes.default.svc.cluster.local
aus dem Ignite-Pod heraus, ohne dass Richtlinien egress
die Shows einschränken
BusyBox v1.29.3 (2019-01-24 07:45:07 UTC) multi-call binary.
Usage: nslookup HOST [DNS_SERVER]
Query DNS about HOST
Sobald (any) NetworkPolicy
angewendet wird, das Egress
auf bestimmte Ports, Pods und Namespaces beschränkt, verweigert der Ignite-Pod den Start und die Suche erreicht ihn nicht kubernetes.default.svc.cluster.local
mehr.
Egress
zu DNS war erlaubt (UDP 53 zu k8s-app: kube-dns) ⇒ weiterhin kein IP-Lookup möglich