Meistere Kubernetes mit Cilium: Traffic Filterung auf L7 Basis

Meistere Kubernetes mit Cilium: Traffic Filterung auf L7 Basis

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.

Aktualisierung von Ubuntu 20.04 auf 22.04 mit Nextcloud 26 und PHP 8.1

Aktualisierung von Ubuntu 20.04 auf 22.04 mit Nextcloud 26 und PHP 8.1

Alle paar Jahre bringt Ubuntu eine neue LTS-Version seines Betriebssystems heraus, und mit ihr kommt ein Bündel neuer Anwendungen und Abhängigkeiten. Dies kann sowohl aufregend als auch eine Herausforderung für Systemadministratoren sein, die dafür sorgen müssen, dass nach einem Upgrade alles funktioniert. Eine der aktualisierten Funktionen in Ubuntu 22.04 ist der Übergang von PHP7.x zu PHP8.x. Dies bringt einen Leistungsschub, tolle neue Funktionen und eine längere Unterstützung. Um Dir den Umstieg zu erleichtern, gehen wir die Schritte durch, die erforderlich sind, um deinen Ubuntu-Server auf 22.04 und deine Nextcloud auf Version 26 mit PHP8.x zu aktualisieren. Und los gehts!

Vorbereitung

Bevor wir irgendwelche irreversiblen Änderungen vornehmen, sollten wir unser System vorbereiten, damit wir eine gute Basis haben, auf die wir zurückgreifen können, falls irgendetwas schief gehen sollte (das wird nicht der Fall sein, aber man weiß ja nie). Wir beginnen damit, dass wir sicherstellen, dass unser aktueller Server auf dem neuesten Stand ist und alle Pakete installiert sind. 

sudo apt update
sudo apt upgrade
sudo apt autoremove

Hier wäre ein sehr guter Zeitpunkt, um ein Backup oder einen Snapshot deines Servers zu erstellen, da wir noch ein aktuelles, funktionierendes System haben. Sollte etwas passieren oder solltest Du einen Fehler machen, kannst Du jederzeit zu diesem Punkt der Datenwiederherstellung zurückkehren und neu beginnen. Außerdem solltest Du in Erwägung ziehen, Port 1022 für später zuzulassen, da Du diesen Prozess wahrscheinlich über SSH durchführen wirst. Nur als Randbemerkung: Wir übernehmen keine Verantwortung für verlorene Daten, daher empfehlen wir Dir dringend, ein Backup zu erstellen, von dem Du deine Datenwiederherstellen kannst, falls die Dinge schiefgehen. Im nächsten Schritt notieren wir uns die PHP-Module, die wir derzeit auf dem Server installiert haben. Diese benötigen wir, um später die entsprechenden Versionen zu installieren. Kleiner Tipp: Um php-json brauchst  Du Dich nicht zu kümmern, da es bereits in PHP8 enthalten ist. Als erstes werden wir die aktuellen Module auflisten, die wir auf unserer aktuellen PHP-Version haben. Dies kannst Du mit den folgenden zwei Befehlen tun: 

php -m

dpkg --get-selections | grep php

php -m
[PHP Modules]
apc
apcu
bcmath
calendar
Core
ctype
curl
date
dom
exif
…

Dies sind alle Module, die sich derzeit auf dem System befinden, und es ist eine gute Idee, diese Liste zu speichern, um später die richtigen Module installieren zu können. Wenn Du alle Module schon einmal manuell mit der älteren Version installiert hast, kannst Du diesen Befehl kopieren und nur die Versionsnummer ersetzen. Kopieren diesen in deinem Lieblingseditor und verwende die Funktion „Suchen und Ersetzen“, um „7.4“ zu finden und durch „8.1“ zu ersetzen. Dies kann bei zukünftigen Versionen wiederholt werden und erspart Dir Zeit, es jedes Mal abzutippen. Da wir nun wissen, welche Module wir für später installieren wollen, können wir uns nun dem Upgrade widmen.

Dist-Upgrade

Jetzt kommt der spaßige Teil, wir bereiten das Upgrade unserer Distribution auf die nächste Version vor, aber zuerst müssen wir ein paar Dinge bestätigen. Wir müssen sicherstellen, dass wir herausfinden, auf welcher Version der Distribution wir uns gerade befinden, damit wir keine Version übersprungen haben. Wenn Du aus irgendeinem Grund noch auf Ubuntu 18.04 bist, musst Du zuerst auf 20.04 aktualisieren, bevor Du auf 22.04 wechselst. Prüfen wir zunächst unsere Distribution: 

lsb_release -a
 
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal

Sehr gut, das ist unsere aktuelle Version und wir können direkt zum nächsten Schritt übergehen und das Upgrade starten. Bitte beachte, dass Du zwischendurch einen Kaffee trinken solltest, da ein Dist-Upgrade je nach System einige Zeit in Anspruch nimmt. Um den Prozess zu starten, geben wir diesen Befehl ein, der den Assistenten startet: 

sudo do-release-upgrade

Dabei wird Dir eine Reihe von Fragen zum Prozess gestellt, die wir jetzt durchgehen werden. Da wir dies wahrscheinlich über SSH machen werden, wird der Assistent Dich fragen, ob Du einen Daemon auf Port 1022 laufen lassen willst, falls während des Prozesses etwas abstürzt. Akzeptiere diese Frage immer mit ja, da Du dann die Instanz über diesen Port wiederherstellen und den Prozess fortsetzen kannst. Vergewissere Dich, dass dieser Port auf deinem Rechner oder deiner Firewall frei ist, falls Du dies nicht bereits getan haben. Danach drückst  Du einfach die Eingabetaste, um fortzufahren. In den nächsten Schritten wirst Du aufgefordert, die Installation aller neuen Pakete für die neue Distribution zu bestätigen. Natürlich wollen wir damit fortfahren, also stimmst Du einfach auch den nächsten beiden Bildschirmen zu. Der erste fragt, ob Neustarts erlaubt sind. Falls Du ein Dist-Upgrade durchführen, ist dein Server ohnehin nicht erreichbar. Es ist also irrelevant, ob Du neu startest oder nicht, drücke einfach die Eingabetaste, um den Prozess fortzusetzen.

Bei der folgenden Frage wirst Du gefragt, ob Du veraltete Pakete, die von dem Upgrade übrig geblieben sind, entfernen möchtest. Du kannst diese einfach loswerden, da sie nur Platz wegnehmen.

Abschließend wirst Du aufgefordert, dein System neu zu starten. Es ist immer eine gute Idee, das gleich zu tun, da es nur eine Minute dauert. Jetzt hat dein Server die neueste Version von Ubuntu und ist bereit, für PHP konfiguriert zu werden.

PHP konfigurieren

Wir sind nun bereit, unser PHP für die Version 8.1 einzurichten. Der Grund, warum wir zuerst 8.1 verwenden, ist, dass Nextcloud Version 25 nicht mit höheren Versionen kompatibel ist. Falls du direkt zu 8.2 wechseln, wird deine Nextcloud nicht wie vorgesehen funktionieren. Wenn Du ein Upgrade auf 8.2 durchführen willst, musst Du dies nach dem Upgrade deiner Nextcloud auf Version 26 tun. Da wir das Dist-upgrade bereits durchgeführt haben, könnten bereits einige Module installiert sein, die für PHP 8.1 vorbereitet sind. Wir müssen jedoch sicherstellen, dass wir alle zusätzlichen Module installieren, die für Nextcloud erforderlich sind. Wenn wir unsere Liste von vorhin vergleichen, müssen wir alle übrigen Module installieren. Im Allgemeinen benötigst Du die folgenden Befehle: 

sudo apt install php8.1-gd php8.1-mysql php8.1-curl php8.1-mbstring php8.1-intl php8.1-gmp php8.1-bcmath php-imagick php8.1-xml php8.1-zip

Jetzt können wir die alte PHP-Version deaktivieren (falls nicht schon geschehen) und sicherstellen, dass die neueste Version aktiviert ist. 

a2dismod php7.4
a2enmod php8.1

Mit diesem Befehl können wir auch die Standard-PHP-Version festlegen, die immer verwendet wird, wenn nichts anderes angegeben ist. Wir haben die Möglichkeit, sie entweder als Standard zu belassen oder zu erzwingen, dass sie immer die von uns ausgewählte Version bevorzugt. Dies wirkt sich jedoch nur auf die PHP-Befehle aus, die Sie in der CLI verwenden, und ist nicht anwendungsspezifisch. 

a2dismod php7.4
a2enmod php8.1

 

Das letzte, was wir mit PHP tun müssen, ist einige der Standardeinstellungen für Nextcloud zu ändern. Diese sind hier zu finden: 

vim /etc/php/8.1/apache2/php.ini
 
memory_limit = 512M
upload_max_filesize = 500M
post_max_size = 500M

Sei Dir sicher, dass Du deine Dienste neu startest, damit alle Konfigurationen wirksam werden und Du kannst loslegen mit: 

systemctl restart apache2

Von hier aus kannst Du Nextcloud 26 mit dem integrierten Installationsprogramm installieren und die Aktualisierung in wenigen Minuten abschließen.

Fazit

Und das war’s auch schon! Dein Server ist jetzt auf dem neuesten Stand und bereit, die Welt zu erobern. Es ist immer empfehlenswert, dein System auf dem neuesten Stand zu halten, um von Sicherheitsupdates, verbesserten Leistung und neuen Funktionen für Ihre Anwendungen zu profitieren. Nextcloud verfügt über zahlreiche Möglichkeiten, Dein System zu verbessern, nicht nur in Bezug auf PHP-Versionen. Die Erforschung der Nextcloud-Härtung ist ebenfalls ein lohnenswertes Unterfangen und wird in unserer kommenden Serie von Blogbeiträgen behandelt werden. Bleib also dran für das nächste Update von uns! Benötigst Du Hilfe zu diesem Thema? Schicke uns eine Nachricht oder abonniere unseren Newsletter für weitere Infos zu diesem Thema.