Seite wählen

Meistere Kubernetes mit Cilium: Traffic Filterung auf L7 Basis

von | Okt 18, 2023

Mit der neuen Version des Cilium CNI auf unserem Kubernetes-Service erhältst Du die Möglichkeit, den Datenverkehr anhand von L7-Eigenschaften zu filtern. Das ist normalerweise Service-Meshes vorbehalten und kann bei der Sicherheit deiner Dienste sehr hilfreich sein. In diesem Tutorial werden wir einen API-Endpunkt so absichern, dass unser Client nur auf bestimmte Routen zugreifen kann. Alle anderen Anfragen werden gar nicht erst an den Dienst weitergeleitet, um die Belastung der API so gering wie möglich zu halten.

Voraussetzungen

Bevor Du beginnst, benötigst Du Folgendes:

  1. Ein Kubernetes-Cluster, der mit Cilium in Betrieb ist.
  2. kubectl Befehlszeilentool installiert und für die Kommunikation mit deinem Cluster konfiguriert ist.
  3. Grundlegende Kenntnisse über Kubernetes Pods, Dienste und Namespaces.

Erstellen von API + API-Client

$ kubectl apply -f https://gist.github.com/modzilla99/0cbdd39cc838e752ae8cdb5ec3cdd03a/raw/adb7218bb1e9195c42192d71809f6f7043e50cd7/deploy.yaml
configmap/apiconfig created
deployment.apps/api created
service/api created
pod/api-client created

Wir haben nun einen Dienst namens „api“ erstellt, der an das Deployment „api“ gebunden ist. Er hat zwei Endpunkte. Die Route /secret sollte privat und /greetings sollte öffentlich zugänglich sein. Da wir keine NetworkPolicies definiert haben, sind beide Routen für jeden im Cluster laufenden Pod zugänglich.

Testen der API

Probieren wir also zunächst die API aus:

$ kubectl exec -it api-client -- curl -H 'X-Security-Header: mysecret' api/secret/mysecret
{
  "name": "mysecret",
  "secret": "syferghewg"
}
$ kubectl exec -it api-client -- curl api/greetings/World
Greetings, World!
$ kubectl exec -it api-client -- curl google.com
The document has moved

Wie Du siehst, ist die API ohne Einschränkungen zugänglich und der api-client pod hat zudem vollen/ungefilterten externen Zugriff.

Zugriff einschränken

Um den Zugriff zu minimieren, wollen wir den Zugriff der Pods ausschließlich auf unsere API und api.github.com beschränken. Mit der folgenden NetworkPolicy lässt sich dieses Ziel effektiv erreichen:

---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-client-egress
spec:
  endpointSelector:
    # Apply policy to api client
    matchLabels:
      app: client
      type: production
  ingress:
  # Drop all incoming traffic
  - {}
  egress:
  # Allow API acccess to GitHub only via HTTPs
  - toFQDNs:
    - matchName: api.github.com
    toPorts:
    - ports:
      - port: "443"
  # Allow access to our API
  - toEndpoints:
    - matchLabels:
        app: api
        type: production
    toPorts:
    - ports: 
      - port: "6090"
        protocol: TCP
  # Allow DNS queries
  - toEndpoints:
    - matchLabels:
        io.kubernetes.pod.namespace: kube-system
        k8s-app: kube-dns
    toPorts:
    - ports:
      - port: "53"
    rules:
      dns:
      - matchPattern: "*"

Jetzt kann der Pod nur noch mit unserer und der GitHub-API kommunizieren und den Kubernetes-DNS-Server abfragen. Jede Anfrage an andere Ressourcen wird jetzt fehlschlagen:

$ kubectl exec -it api-client -- curl -4 --connect-timeout 3 -v google.com
* processing: google.com
* Trying 142.250.184.238:80...
* ipv4 connect timeout after 2974ms, move on!
* Failed to connect to google.com port 80 after 3001 ms: Timeout was reached
* Closing connection
curl: (28) Failed to connect to google.com port 80 after 3001 ms: Timeout was reached
$ kubectl exec -it api-client -- curl -4 https://api.github.com/user
{
  "message": "Requires authentication",
  "documentation_url": "https://docs.github.com/rest/users/users#get-the-authenticated-user"
}

Als nächstes wollen wir unsere API absichern. Wir wollen nicht, dass der Pod nach außen kommunizieren kann und er soll nur den Zugang zu unseren beiden Routen erlauben. Da der /greetings Endpunkt öffentlich sein soll, öffnen wir den Zugang für jeden, während wir den Zugang zur /secret Route auf unseren API-Client beschränken.

---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-api-ingress
spec:
  endpointSelector:
    matchLabels:
      app: api
      type: production
  egress:
  # Deny any external traffic
  - {}
  ingress:
  # Allow access to /secret route from our api client 
  - fromEndpoints:
    - matchLabels:
        app: client
        type: production
    toPorts:
    - ports:
      - port: "6090"
        protocol: TCP
      rules:
        http:
        - method: "GET"
          path: "/secret/.*"
          # Require HTTP header for authorization
          headers:
          - 'X-Security-Header: mysecret'
  # Allow access to /greetings route from anyone
  - toPorts:
    - ports:
      - port: "6090"
        protocol: TCP
      rules:
        http:
        - method: "GET"
          path: "/greetings/.*"

Jetzt können wir nur auf die /secret-Route mit dem erforderlichen Header und vom Api-Client-Pod aus zugreifen:

$ kubectl exec -it api-client -- curl api/secret/mysecret
Access denied
$ kubectl exec -it api-client -- curl -H 'X-Security-Header: mysecret' api/secret/mysecret
{
  "name": "mysecret",
  "secret": "adasge53whbetn"
}

Fazit

Cilium NetworkPolicies sind eine leistungsstarke Methode zur Kontrolle des Netzwerkverkehrs innerhalb deines Clusters. Durch die Definition von Regeln für eingehenden und ausgehenden Traffic kannst Du deine Anwendungen sichern und bei Bedarf isolieren. In diesem Tutorial wurden die Grundlagen der Erstellung und Verwendung von NetworkPolicies behandelt, aber Du kannst auch komplexere Richtlinien erstellen, die deinen speziellen Anforderungen entsprechen.

Benötigst Du Hilfe zu diesem Thema? Schicke uns eine Nachricht oder abonniere unseren Newsletter, um weitere Infos zu diesem Thema zu erhalten.

Verpasse nicht unseren Newsletter
Mehr überKubernetes
ReadWriteMany (RWX) mit dem NFS Ganesha Provisioner

ReadWriteMany (RWX) mit dem NFS Ganesha Provisioner

Einführung Du hast die Anforderung, dass Deine Anwendung für eine Lastverteilung über mehrere Nodes skalieren muss, aber Zugriff auf ein gemeines PVC benötigt? Zu diesem Zweck benötigst Du ein PVC welches RWX-fähig ist. Im Rahmen unserer Managed Kubernetes Cluster ist...

Persistente Volumes in Kubernetes vergrößern

Persistente Volumes in Kubernetes vergrößern

Du willst ein PersistentVolume (PV) in Kubernetes vergrößern? In diesem Blogeintrag erfährst du wie das funktioniert. Was PVs sind und wie man diese anlegt wird im Tutorial Persistente Volumes in Kubernetes erstellen erklärt, auf welchem das vorliegende Tutorial...

Benutzerdefiniertes Verbindungslimit für Load Balancer

Benutzerdefiniertes Verbindungslimit für Load Balancer

Du würdest gerne ein eigenes Limit für eingehende Verbindungen an deinem Load Balancer festlegen? In diesem Tutorial lernst du wie das geht. Über das Verbindungslimit Das Verbindungslimit (engl. "connection limit") beschreibt die maximal zugelassene Anzahl an...

Automatische Fedora CoreOS Updates für Dein Kubernetes

Automatische Fedora CoreOS Updates für Dein Kubernetes

Du willst automatische Fedora CoresOS Updates für Dein Kubernetes? Und was haben Zincati und libostree damit zu tun? Hier bekommst Du schnell einen Überblick! Als Betriebssystem vieler Kubernetes Cluster kommt Fedora CoreOS zum Einsatz. Dieses auf Container...

X-Forwarded-For und Proxy-Protocol

X-Forwarded-For und Proxy-Protocol

Du willst wissen wie Du in Deinem Kubernetes Cluster an die IP-Adressen Deiner Clients kommst? In fünf Minuten hast Du den Überblick! Vom HTTP-Client zur Anwendung Im Tutorial zum nginx-Ingress-Controller zeigen wir wie man eine Anwendung öffentlich erreichbar macht....

Kubernetes Alerting mit Prometheus Alertmanager

Kubernetes Alerting mit Prometheus Alertmanager

In einem vorangegangenen Post erläuterte Sebastian, wie man mit dem Prometheus Operator sein Kubernetes Cluster monitoren kann. Dieser Beitrag baut darauf auf und zeigt, wie man Benachrichtigungen per E-Mail und als Push Notifications mit dem Alertmanager einrichten...

Logging mit Loki und Grafana in Kubernetes

Logging mit Loki und Grafana in Kubernetes

Die wichtigsten Bausteine zum Starten deiner Anwendung kennst du bereits aus unserer Tutorial-Serie. Für den Betrieb fehlen dir noch Metriken und Logs deiner Anwendungen? Nach diesem Blogpost kannst du letzteres abhaken. Logging mit Loki und Grafana in Kubernetes -...

Kubernetes Nodegroups verwalten

Kubernetes Nodegroups verwalten

Seit dieser Woche können unsere Kunden das "Nodegroup-Feature" für ihre NWS Managed Kubernetes Cluster nutzen. Was sind Nodegroups und was kann ich damit bewerkstelligen? Das und mehr erklärt unser siebter Blogpost der Serie. Was sind Nodegroups? Mit Nodegroups ist es...

Persistente Volumes in Kubernetes erstellen

Persistente Volumes in Kubernetes erstellen

Du willst ein persistentes Volume in Kubernetes erstellen? Hier erfährst du wie das mit Openstack Cinder im NWS Managed Kubernetes funktioniert. Pods und Container sind per Definition mehr oder weniger flüchtige Komponenten in einem Kubernetes Cluster und werden je...

Monitoring Kubernetes mit Prometheus

Monitoring Kubernetes mit Prometheus

Monitoring – für viele eine gewisse Hass-Liebe. Die einen mögen es, die anderen verteufeln es. Ich gehöre zu denen, die es meist eher verteufeln, dann aber meckern, wenn man gewisse Metriken und Informationen nicht einsehen kann. Unabhängig der persönlichen Neigungen...