Einleitung
Wir haben Kubernetes in der Hetzner Cloud installiert und dann den Cloud Load Balancer verwendet, um Traffic anzubinden. Nach ein paar Versuchen wollten wir die Dienste dann mit etwas Authentifizierung absichern. Die Einrichtung von basic auth funktionierte gut. Aber als wir versuchten einige Adressen ohne Authentifizierung durchzulassen, funktionierte das nicht.
Also will ich in diesem Tutorial zeigen, wie wir das konfiguriert haben. Unser Use-case ist wie folgt: wir haben ein paar Dienste im Kubernetes, die wir mit einem Passwortschutz (basic auth) versehen wollen. Trotzdem sollen einige Quelladressen z.B. unser Büro diese Passwortabfrage nicht erhalten, weil das sonst sehr nervig wäre.
Voraussetzungen
- Ein laufendes Kubernetes Cluster in der Hetzer Cloud. Zur Einrichtung kann dieses Tutorial genutzt werden.
- Ein paar Grundkenntnisse im Umgang mit Kubernetes.
Dieses Tutorial wurde getestet mit Ubuntu 20.04 Hetzner Cloud Servern und Kubernetes Version v1.21.0
Schritt 1 - Ingress Konfigurieren
Wir haben die offizielle Konfiguration genutzt, um unseren Ingress Dienst zu erstellen.
Als erstes muss die Konfigurationsdatei heruntergeladen werden:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.45.0/deploy/static/provider/cloud/deploy.yamlDann die Felder use-forwarded-headers, compute-full-forwarded-for und use-proxy-protocol zur data definition hinzufügen:
# Source: ingress-nginx/templates/controller-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
labels:
helm.sh/chart: ingress-nginx-3.27.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.45.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
data:
use-forwarded-headers: "true"
compute-full-forwarded-for: "true"
use-proxy-protocol: "true"Schritt 1.1 - Load Balancer erstellen und verbinden
Einen Load Balancer in der Hetzner Cloud Console erstellen. Dabei ist es wichtig, das richtige interne Netzwerk auszuwählen. Wir haben bei der Erstellung keine Dienste konfiguriert. Dies passierte automatisch, als wir den Ingress Dienst deployed haben.
Der Name des Load Balancers muss der Annotation entsprechen, so wie hier:
---
# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
annotations:
load-balancer.hetzner.cloud/name: "kubelb"Eine weitere Beschreibung wie der Load Balancer hinzugefügt werden kann, gibt es hier.
Nachdem die beschriebenen Anpassungen an der deploy.yaml gemacht wurden, kann diese angewendet werden mit:
kubectl -f deploy.yamlDas komplette Konfigurationsbeispiel ist hier zu finden.
Schritt 2 - Proxy Protocol für den Load Balancer aktivieren
Nun in die Hetzner Cloud Console wechseln, um den Load Balancer zu konfigurieren. Hierfür den Reiter Services öffnen. Es kann ein paar Minuten dauern, bis die Dienste in der Cloud Console angezeigt werden. Dann die Option Proxy Protocol aktivieren.
Bitte beachten: zu diesem Zeitpunkt kann es sein, dass die Dienste nicht mehr erreichbar sind, falls die Ingress Konfiguration nicht korrekt ist. Das ist aber nicht so schlimm. Falls das passiert, kann das jederzeit wieder deaktiviert werden.
Schritt 3 - Authentifizierung für die Dienste hinzufügen
Nun muss eine service.yaml für den Dienst erzeugt werden. Diese Beispielkonfiguration
kann als Ausgangspunkt verwendet werden.
Dann ist es an der Zeit die Authentifizierung hinzuzfügen. Hier sind die annotations, welche wir verwendeten, um unseren Dienst zu schützen. Diese konfigurieren eine basic auth mit ein paar Ausnahmen.
Dem Dienst müssen folgende annotations hinzugefügt werden. Insbesondere whitelist-source-range muss hier angepasst werden.
...
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/whitelist-source-range: 4.8.15.16/32,23.42.0.0/32
nginx.ingress.kubernetes.io/satisfy: "any"
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required - Registry"
...Halt stop. Wo sind denn die Zugangsdaten definiert? Nun, in diesem Beispiel kommen sie durch das secret basic-auth. Es wurde mittels htpasswd erstellt:
$ htpasswd -c ./auth userDiese Datei kann dann in Kubernetes als secret importiert werden. Bitte beachten, dass der name basic-auth genau dem Namen des auth-secret in der Service Definition entspricht.
kubectl create secret generic basic-auth --from-file=authAbschließend dann den Dienst deployen mit:
kubectl -f service.yamlProblembeschreibung
Quell IP Filter sind darauf angewiesen, dass im HTTP Header X-Forwared-For und X-Real-IP korrekt sind. Dies war für unser Setup zunächst nicht der Fall. Wir haben dies mit einem kleinen phpinfo Dienst ermittelt. Bitte die IP des privaten Netzes beachten. Keine Überraschung also, das das Whitelisting zunächst nicht klappen wolle. Die korrekte Adresse des Besuchers konnte nicht ermittelt werden.
Dies kann mit diesem Beispiel selbst überprüft werden.
Zusammenfassung
Nun können Sie Authentifizierung für Dienste im Kubernetes Cluster konfigurieren. Dabei handelt es sich um einen Standard Passwortschutz, von dem einige Quelladressen ausgenommen werden können.