BLOG | NGINX

NGINX-Tutorial: Schützen Sie Kubernetes-Apps vor SQL-Injection

NGINX-Teil-von-F5-horiz-schwarz-Typ-RGB
Daniele Polencic Miniaturbild
Daniele Polencic
Veröffentlicht am 22. März 2022

Dieses Tutorial ist eines von vier, die Konzepte aus „Microservices March 2022“ in die Praxis umsetzen: Kubernetes-Netzwerk :

Möchten Sie detaillierte Anleitungen zur Verwendung von NGINX für noch mehr Anwendungsfälle von Kubernetes-Netzwerken? Laden Sie unser kostenloses E-Book „Verwaltung des Kubernetes-Verkehrs mit NGINX“ herunter: Ein praktischer Leitfaden .

Sie arbeiten in der IT-Abteilung eines beliebten Ladens vor Ort, der verschiedene Waren verkauft, von Kissen bis zu Fahrrädern. Sie stehen kurz vor der Eröffnung ihres ersten Online-Shops, haben jedoch einen Sicherheitsexperten gebeten, die Site vor der Veröffentlichung einem Penetrationstest zu unterziehen. Leider hat der Sicherheitsexperte ein Problem gefunden! Der Online-Shop ist anfällig für SQL-Injection . Der Sicherheitsexperte konnte die Site ausnutzen, um vertrauliche Informationen aus Ihrer Datenbank zu erhalten, darunter Benutzernamen und Passwörter.

Ihr Team ist zu Ihnen – dem Kubernetes-Ingenieur – gekommen, um die Situation zu retten. Glücklicherweise wissen Sie, dass SQL-Injection (sowie andere Schwachstellen) mithilfe von Kubernetes-Verkehrsverwaltungstools gemindert werden können. Sie haben bereits einen Ingress-Controller bereitgestellt, um die App verfügbar zu machen, und können in einer einzigen Konfiguration sicherstellen, dass die Sicherheitsanfälligkeit nicht ausgenutzt werden kann. Nun kann der Online-Shop pünktlich an den Start gehen. Gut gemacht!

Übersicht über Labor und Tutorial

Dieser Blog begleitet das Labor für Einheit 3 von Microservices März 2022 – Microservices-Sicherheitsmuster in Kubernetes und zeigt, wie NGINX und NGINX Ingress Controller verwendet werden, um SQL-Injection zu blockieren.

Zum Ausführen des Lernprogramms benötigen Sie einen Computer mit:

  • 2 CPUs oder mehr
  • 2 GB freier Speicher
  • 20 GB freier Speicherplatz
  • Internetverbindung
  • Container- oder Virtual Machine Manager, wie etwa Docker, Hyperkit, Hyper-V, KVM, Parallels, Podman, VirtualBox oder VMware Fusion/Workstation
  • Minikube installiert
  • Helm installiert
  • Eine Konfiguration, die Ihnen das Öffnen eines Browserfensters ermöglicht. Ist dies nicht möglich, muss nach einer Möglichkeit gesucht werden, über einen Browser auf die entsprechenden Dienste zuzugreifen.

Um den größtmöglichen Nutzen aus dem Labor und dem Lernprogramm zu ziehen, empfehlen wir Ihnen, vor dem Beginn Folgendes zu tun:

In diesem Tutorial werden die folgenden Technologien verwendet:

Die Anweisungen für jede Herausforderung enthalten den vollständigen Text der YAML-Dateien, die zum Konfigurieren der Apps verwendet werden. Sie können den Text auch aus unserem GitHub-Repository kopieren. Zusammen mit dem Text jeder YAML-Datei wird ein Link zu GitHub bereitgestellt.

Dieses Tutorial umfasst vier Herausforderungen:

  1. Bereitstellen eines Clusters und einer anfälligen App
  2. Hacken Sie die App
  3. Verwenden Sie einen NGINX-Sidecar-Container, um bestimmte Anfragen zu blockieren
  4. Konfigurieren Sie den NGINX Ingress Controller zum Filtern von Anfragen

Herausforderung 1: Bereitstellen eines Clusters und einer anfälligen App

In dieser Herausforderung stellen Sie einen Minikube-Cluster bereit und installieren Podinfo als Beispiel-App, die Sicherheitslücken aufweist.

Erstellen eines Minikube-Clusters

Stellen Sie einen Minikube- Cluster bereit. Nach einigen Sekunden bestätigt eine Meldung, dass die Bereitstellung erfolgreich war.

$ minikube start 🏄 Fertig! kubectl ist jetzt so konfiguriert, dass es standardmäßig den Cluster „minikube“ und den Namespace „default“ verwendet 

Installieren Sie die anfällige App

Hier stellen Sie eine einfache E‑Commerce‑App bereit, die aus zwei Microservices besteht:

  • Eine MariaDB-Datenbank
  • Ein PHP-Mikroservice, der sich mit der Datenbank verbindet und Daten abruft

Führen Sie diese Schritte aus:

  1. Erstellen Sie mit einem Texteditor Ihrer Wahl eine YAML-Datei namens 1-app.yaml mit dem folgenden Inhalt (oder kopieren Sie sie von GitHub ).

    API-Version: Apps/v1 Art: Bereitstellung 
    Metadaten: 
    Name: App 
    Spezifikation: 
    Selektor: 
    MatchLabels: 
    App: App 
    Vorlage: 
    Metadaten: 
    Labels: 
    App: App 
    Spezifikation: 
    Container: 
    - Name: App 
    Image: f5devcentral/microservicesmarch:1.0.3 
    Ports: 
    - ContainerPort: 80 
    Umgebung: 
    - Name: MYSQL_USER 
    Wert: dan 
    - Name: MYSQL_PASSWORD 
    Wert: dan 
    - Name: MYSQL_DATABASE 
    Wert: sqlitraining 
    - Name: DATABASE_HOSTNAME 
    Wert: db.default.svc.cluster.local 
    --- 
    API-Version: v1 
    Art: Dienst 
    Metadaten: 
    Name: App 
    Spezifikation: 
    Ports: 
    - Port: 80 
    ZielPort: 80 
    KnotenPort: 30001 
    Selektor: 
    App: App 
    Typ: NodePort 
    --- 
    API-Version: Apps/v1 
    Art: Bereitstellung 
    Metadaten: 
    Name: db 
    Spezifikation: 
    Selektor: 
    MatchLabels: 
    App: db 
    Vorlage: 
    Metadaten: 
    Labels: 
    App: db 
    Spezifikation: 
    Container: 
    -Name: db 
    Image: mariadb:10.3.32-focal 
    Ports: 
    -ContainerPort: 3306 
    Umgebung: 
    - Name: MYSQL_ROOT_PASSWORD 
    Wert: root 
    - Name: MYSQL_USER 
    Wert: dan 
    - Name: MYSQL_PASSWORD 
    Wert: dan 
    - Name: MYSQL_DATABASE 
    Wert: sqlitraining 
    
    --- 
    API-Version: v1 
    Art: Dienst 
    Metadaten: 
    Name: db 
    Spezifikation: 
    Ports: 
    -Port: 3306 
    ZielPort: 3306 
    Selektor: 
    App: db 
    
  2. Stellen Sie die App und die API bereit:

    $ kubectl apply -f 1-app.yaml deployment.apps/app erstellt service/app erstellt deployment.apps/db erstellt service/db erstellt 
    
  3. Bestätigen Sie, dass die Podinfo-Pods bereitgestellt wurden, wie durch den Wert „Ausführen“ in der Spalte „STATUS“ angezeigt. Die vollständige Bereitstellung kann 30–40 Sekunden dauern. Warten Sie daher, bis der Status beider Pods „ Ausführen“ lautet, bevor Sie mit dem nächsten Schritt fortfahren (und den Befehl bei Bedarf erneut eingeben).

    $ kubectl get pods NAME BEREIT STATUS NEUSTART ALTER app-d65d9b879-b65f2 1/1 Läuft 0 37s db-7bbcdc75c-q2kt5 1/1 Läuft 0 37s 
    
  4. Öffnen Sie die App in Ihrem Browser:

    $ minikube service app |-----------|------|-------------|--------------| | NAMESPACE | NAME | ZIELPORT | URL | |-----------|------|-------------|--------------| | Standard | App | | Kein Knotenport | |--------------|------|-------------|--------------| 😿 Service Standard/App hat keinen Knotenport 🏃 Tunnel für Service-App wird gestartet. |-----------|------|-------------|------------------------| | NAMESPACE | NAME | ZIELPORT | URL | |-----------|------|-------------|------------------------| | Standard | App | | http://127.0.0.1:55446 | |-----------|------|-------------|-------------| 🎉 Service Standard/App wird im Standardbrowser geöffnet … 
    

Herausforderung 2: Hacken Sie die App

Die Beispielanwendung ist eher einfach. Es umfasst eine Homepage mit einer Artikelliste (z. B. Kissen) und eine Reihe von Produktseiten mit Details wie einer Beschreibung und dem Preis. Die Daten werden in der MariaDB-Datenbank gespeichert. Bei jeder Seitenanforderung wird eine SQL-Abfrage an die Datenbank gesendet.

  • Für die Homepage werden sämtliche Einträge aus der Datenbank abgefragt.
  • Bei einer Produktseite wird der Artikel anhand der ID abgerufen.

Wenn Sie die Produktseite der Kissen öffnen, bemerken Sie möglicherweise, dass die URL auf /product/1 endet. Der1 ist die ID des Produkts. Um das direkte Einfügen von Schadcode in die SQL-Abfrage zu verhindern, empfiehlt es sich, Benutzereingaben zu bereinigen, bevor Anfragen an Backend-Dienste weitergeleitet werden. Aber was passiert, wenn die App nicht richtig konfiguriert ist und die Eingabe nicht maskiert wird, bevor sie in die SQL-Abfrage an die Datenbank eingefügt wird?

Exploit 1

Um herauszufinden, ob die App Eingaben ordnungsgemäß maskiert, führen Sie ein einfaches Experiment durch, indem Sie die ID in eine ändern, die in der Datenbank nicht vorhanden ist.

Ändern Sie das letzte Element in der URL manuell von1 Zu-1 . Die Fehlermeldung „Ungültige Produkt -ID „-1““ zeigt an, dass die Produkt-ID nicht maskiert wird. Stattdessen wird die Zeichenfolge direkt in die Abfrage eingefügt. Das ist nicht gut, es sei denn, Sie sind ein Hacker!

Angenommen, die Datenbankabfrage lautet etwa:

WÄHLEN SIE * AUS EINER_TABELLE, WO ID = "1"

Um die Sicherheitslücke auszunutzen, die durch das Nicht-Entkommen der Eingabe entsteht, ersetzen Sie 1 mit -1" <böswillige_Abfrage> -- // so dass:

  • Das Anführungszeichen ( " ) nach-1 schließt die erste Abfrage ab.
  • Sie können nach dem Anführungszeichen Ihre eigene böswillige Abfrage hinzufügen.
  • Die Sequenz -- // verwirft den Rest der Abfrage.

Wenn Sie beispielsweise das letzte Element in der URL in -1" ändern oder 1-- // , die Abfrage wird wie folgt kompiliert:

SELECT * FROM some_table WHERE id = "-1" OR 1 -- //" -------------- ^ injiziert ^ 

Dadurch werden alle Zeilen aus der Datenbank ausgewählt, was bei einem Hack nützlich ist. Um herauszufinden, ob dies der Fall ist, ändern Sie die URL-Endung in ‑1" . Die resultierende Fehlermeldung gibt Ihnen weitere nützliche Informationen über die Datenbank:

Schwerwiegender Fehler: Nicht abgefangene mysqli_sql_exception: Sie haben einen Fehler in Ihrer SQL-Syntax. Überprüfen Sie das Handbuch, das Ihrer MariaDB-Serverversion entspricht, auf die richtige Syntax, die in der Nähe von „-1“ in Zeile 1 in /var/www/html/product.php:23 verwendet werden muss. Stacktrace: #0 /var/www/html/product.php(23): mysqli->query('SELECT * FROM p...') #1 {main} geworfen in /var/www/html/product.php in Zeile 23

Jetzt können Sie mit der Manipulation des eingefügten Codes beginnen, um zu versuchen, die Datenbankergebnisse nach ID zu sortieren:

-1" ODER 1 ORDER BY id DESC -- //

Das Ergebnis ist die Produktseite für den letzten Artikel in der Datenbank.

Exploit 2

Das Erzwingen einer Sortierung der Ergebnisse durch die Datenbank ist interessant, aber nicht besonders nützlich, wenn Ihr Ziel das Hacken ist. Der Versuch, Benutzernamen und Passwörter aus der Datenbank zu extrahieren, ist wesentlich lohnender.

Man kann davon ausgehen, dass in der Datenbank eine Benutzertabelle mit Benutzernamen und Passwörtern vorhanden ist. Aber wie erweitern Sie Ihren Zugriff von der Produkttabelle auf die Benutzertabelle?

Die Antwort besteht in der Einfügen von Code wie diesem:

-1" UNION SELECT * FROM Benutzer -- //

Wo

  • -1“ erzwingt die Rückgabe einer leeren Menge aus der ersten Abfrage.
  • UNION führt die Zusammenführung zweier Datenbanktabellen durch – in diesem Fall Produkte und Benutzer –, wodurch Sie Informationen (Passwörter) abrufen können, die in der ursprünglichen Tabelle ( Produkte ) nicht enthalten sind.
  • SELECT * FROM users wählt alle Zeilen in der Benutzertabelle aus.
  • Die Sequenz -- // verwirft alles nach der bösartigen Abfrage.

Wenn Sie die URL so ändern, dass sie mit dem eingefügten Code endet, erhalten Sie eine neue Fehlermeldung:

Schwerwiegender Fehler: Nicht abgefangene mysqli_sql_exception: Die verwendeten SELECT-Anweisungen haben eine unterschiedliche Anzahl von Spalten in /var/www/html/product.php:23. Stacktrace: #0 /var/www/html/product.php(23): mysqli->query('SELECT * FROM p...') #1 {main} geworfen in /var/www/html/product.php in Zeile 23.

Diese Meldung zeigt an, dass die Tabellen „Produkte“ und „Benutzer“ nicht die gleiche Anzahl Spalten haben und der UNION -Befehl daher nicht ausgeführt werden kann. Sie können die Anzahl der Spalten jedoch durch Ausprobieren ermitteln, indem Sie der SELECT- Anweisung nacheinander die Spalten (Feldnamen) als Parameter hinzufügen. Ein guter Tipp für den Feldnamen in einer Benutzertabelle ist password . Versuchen Sie also Folgendes:

# wähle 1 Spalte -1" UNION SELECT password FROM users; -- // # wähle 2 Spalten -1" UNION SELECT password,password FROM users; -- // # wähle 3 Spalten -1" UNION SELECT password,password,password FROM users; -- / # wähle 4 Spalten -1" UNION SELECT password,password,password,password FROM users; -- // # wähle 5 Spalten -1" UNION SELECT password,password,password,password,password FROM users; -- //

Die letzte Abfrage ist erfolgreich (und zeigt Ihnen an, dass die Benutzertabelle fünf Spalten enthält) und Sie sehen ein Benutzerkennwort:

Der zu diesem Passwort gehörende Benutzername ist Ihnen zu diesem Zeitpunkt noch nicht bekannt. Wenn Sie jedoch die Anzahl der Spalten in der Benutzertabelle kennen, können Sie dieselben Abfragetypen wie zuvor verwenden, um diese Informationen anzuzeigen. Nehmen Sie an, dass der relevante Feldname Benutzername ist. Und das stellt sich als richtig heraus – die folgende Abfrage legt sowohl den Benutzernamen als auch das Passwort aus der Benutzertabelle offen. Das ist großartig – es sei denn, diese App wird auf Ihrer Infrastruktur gehostet!

-1" UNION SELECT Benutzername,Benutzername,Passwort,Passwort,Benutzername FROM Benutzer, wobei ID=1 -- //

Herausforderung 3: Verwenden Sie einen NGINX-Sidecar-Container, um bestimmte Anfragen zu blockieren

Der Entwickler der Online-Shop-App muss natürlich mehr Wert auf die Bereinigung der Benutzereingaben legen (z. B. durch die Verwendung parametrisierter Abfragen), aber als Kubernetes-Ingenieur können Sie auch dazu beitragen, SQL-Injection zu verhindern, indem Sie den Angriff daran hindern, die App zu erreichen. Auf diese Weise fällt es nicht so sehr ins Gewicht, dass die App anfällig ist.

Es gibt viele Möglichkeiten, Ihre Apps zu schützen. Im weiteren Verlauf dieses Labors konzentrieren wir uns auf zwei Punkte:

Stellen Sie NGINX Open Source als Sidecar bereit

  1. Erstellen Sie eine YAML-Datei namens 2-app-sidecar.yaml mit dem folgenden Inhalt (oder kopieren Sie sie von GitHub ). Wichtige Aspekte der Konfiguration sind:

    • Ein Sidecar-Container mit NGINX Open Source wird auf Port 8080 gestartet.
    • NGINX leitet den gesamten Datenverkehr an die App weiter.
    • Jede Anforderung, die (unter anderem) SELECT oder UNION enthält, wird abgelehnt (siehe den ersten Standortblock im Abschnitt „ConfigMap“ ).
    • Der Dienst für die App leitet den gesamten Datenverkehr zuerst an den NGINX-Container weiter.
    API-Version: Apps/v1
    Art: Bereitstellung 
    Metadaten: 
    Name: App 
    Spezifikation: 
    Selektor: 
    MatchLabels: 
    App: App 
    Vorlage: 
    Metadaten: 
    Labels: 
    App: App 
    Spezifikation: 
    Container: 
    - Name: App 
    Image: f5devcentral/microservicesmarch:1.0.3 
    Ports: 
    - ContainerPort: 80 
    Umgebung: 
    - Name: MYSQL_USER 
    Wert: dan 
    - Name: MYSQL_PASSWORD 
    Wert: dan 
    - Name: MYSQL_DATABASE 
    Wert: sqlitraining 
    - Name: DATABASE_HOSTNAME 
    Wert: db.default.svc.cluster.local 
    - Name: Proxy # <-- Sidecar 
    Bild: „nginx“ 
    Ports: 
    - ContainerPort: 8080 
    volumeMounts: 
    - mountPath: /etc/nginx 
    Name: nginx-config 
    volumes: 
    - Name: nginx-config 
    configMap: 
    Name: sidecar 
    --- 
    apiVersion: v1 
    kind: Dienst 
    Metadaten: 
    Name: App 
    Spezifikation: 
    Ports: 
    - Port: 80 
    ZielPort: 8080 # <-- der Verkehr wird an den Proxy weitergeleitet 
    nodePort: 30001 
    Selektor: 
    App: App 
    Typ: NodePort 
    --- 
    API-Version: v1 
    Art: ConfigMap 
    metadata: 
    name: sidecar 
    data: 
    nginx.conf: |- 
    events {} 
    http { 
    server { 
    listen 8080 default_server; 
    listen [::]:8080 default_server; 
    
    location ~* "(\'|\")(.*)(drop|insert|md5|select|union)" { 
    deny all; 
    } 
    
    location / { 
    proxy_pass http://localhost:80/; 
    } 
    } 
    } 
    --- 
    apiVersion: apps/v1 
    kind: Bereitstellung 
    Metadaten: 
    Name: db 
    Spezifikation: 
    Selektor: 
    MatchLabels: 
    App: db 
    Vorlage: 
    Metadaten: 
    Labels: 
    App: db 
    Spezifikation: 
    Container: 
    -Name: db 
    Image: mariadb:10.3.32-focal 
    Ports: 
    -ContainerPort: 3306 
    Umgebung: 
    - Name: MYSQL_ROOT_PASSWORD 
    Wert: root 
    - Name: MYSQL_USER 
    Wert: dan 
    - Name: MYSQL_PASSWORD 
    Wert: dan 
    - Name: MYSQL_DATABASE 
    Wert: sqlitraining 
    
    --- 
    API-Version: v1 
    Art: Dienst 
    Metadaten: 
    Name: db 
    Spezifikation: 
    Ports: 
    -Port: 3306 
    ZielPort: 3306 
    Selektor: 
    App: db
    
  2. Den Beiwagen einsetzen:

    $ kubectl apply -f 2-app-sidecar.yaml deployment.apps/app konfiguriert service/app konfiguriert configmap/sidecar erstellt deployment.apps/db unverändert service/db unverändert 
    

Testen Sie den Sidecar als Filter

Testen Sie, ob der Sidecar den Datenverkehr filtert, indem Sie zur App zurückkehren und die SQL-Injection erneut versuchen. NGINX blockiert die Anfrage, bevor sie die App erreicht!

-1" UNION SELECT Benutzername,Benutzername,Passwort,Passwort,Benutzername FROM Benutzer, wobei ID=1 -- //

Herausforderung 4: Konfigurieren Sie den NGINX Ingress Controller zum Filtern von Anfragen

Das Schützen Ihrer App wie in Herausforderung 3 ist aus pädagogischen Gründen interessant, für die Produktion empfehlen wir es jedoch aus folgenden Gründen nicht:

  • Es ist keine vollständige Sicherheitslösung.
  • Es ist nicht skalierbar (Sie können diesen Schutz nicht einfach auf mehrere Apps anwenden).
  • Die Aktualisierung ist kompliziert und ineffizient.

Eine viel bessere Lösung ist die Verwendung des NGINX Ingress Controllers, um den gleichen Schutz auf alle Ihre Apps auszuweiten! Mit Ingress-Controllern können alle Arten von Sicherheitsfunktionen zentralisiert werden, vom Blockieren von Anfragen wie bei einer Web Application Firewall (WAF) bis hin zur Authentifizierung und Autorisierung.

Bei dieser Herausforderung stellen Sie den NGINX Ingress Controller bereit , konfigurieren die Verkehrsweiterleitung und überprüfen, ob der Filter die SQL-Injection blockiert .

Bereitstellen des NGINX Ingress Controllers 

Am schnellsten lässt sich NGINX Ingress Controller mit Helm installieren.  

  1. Fügen Sie das NGINX-Repository zu Helm hinzu: 

    $ helm repo add nginx-stable https://helm.nginx.com/stable  
    
  2. Laden Sie den auf Open Source basierenden NGINX Ingress Controller herunter und installieren Sie ihn, der von F5 NGINX verwaltet wird. Beachten Sie den Parameter enableSnippets=true : Snippets werden verwendet, um NGINX so zu konfigurieren, dass die SQL-Injection blockiert wird. Die letzte Ausgabezeile bestätigt die erfolgreiche Installation.

    $ helm install main nginx-stable/nginx-ingress \ --set controller.watchIngressWithoutClass=true --set controller.service.type=NodePort \ --set controller.service.httpPort.nodePort=30005 \ --set controller.enableSnippets=true NAME: main LETZTE BEREITSTELLUNG: Tag Mo TT hh:mm:ss JJJJ NAMESPACE: Standard STATUS: bereitgestellt REVISION: 1 TESTSUITE: Keine ANMERKUNGEN: Der NGINX Ingress Controller wurde installiert.  
    
  3. Bestätigen Sie, dass der NGINX Ingress Controller-Pod bereitgestellt wurde, wie durch den Wert „Running“ in der Spalte „STATUS“ angezeigt. 

    $ kubectl get pods NAME BEREIT STATUS ... main-nginx-ingress-779b74bb8b-mtdkr 1/1 Wird ausgeführt ... ... STARTET DAS ALTER NEU ... 0 18 Sek.
    

Leiten Sie den Datenverkehr an Ihre App weiter

  1. Erstellen Sie eine YAML-Datei namens 3-ingress.yaml mit dem folgenden Inhalt (oder kopieren Sie sie von GitHub ). Es definiert das Ingress-Manifest, das zum Weiterleiten des Datenverkehrs an die App erforderlich ist (diesmal nicht über den Sidecar-Proxy). Beachten Sie den Block „Annotationen:“ , in dem ein Snippet verwendet wird, um die Konfiguration des NGINX Ingress Controllers mit demselben Standortblock anzupassen wie in der ConfigMap-Definition in Herausforderung 3: Er lehnt alle Anfragen ab, die (neben anderen Zeichenfolgen) SELECT oder UNION enthalten.

    API-Version: v1 Art: Dienst 
    Metadaten: 
    Name: App ohne Sidecar 
    Spezifikation: 
    Ports: 
    -Port: 80 
    ZielPort: 80 
    Selektor: 
    App: App 
    --- 
    API-Version: networking.k8s.io/v1 
    Art: Ingress 
    metadata: 
    name: entry 
    annotations: 
    nginx.org/server-snippets: | 
    location ~* "(\'|\")(.*)(drop|insert|md5|select|union)" { 
    deny all; 
    } 
    spec: 
    ingressClassName: nginx 
    rules: 
    - host: "example.com" 
    http: 
    paths: 
    - backend: 
    service: 
    name: app-without-sidecar 
    port: 
    number: 80 
    Pfad: / 
    Pfadtyp: Präfix 
    
  2. Stellen Sie die Ingress-Ressource bereit: 
  3. $ kubectl apply -f 3-ingress.yaml service/app-without-sidecar erstellt ingress.networking.k8s.io/entry erstellt 
    

Filterbetrieb überprüfen

  1. Starten Sie einen verfügbaren BusyBox -Container, um eine Anforderung mit dem richtigen Hostnamen an den NGINX Ingress Controller-Pod zu senden.

    $ kubectl run -ti --rm=true busybox --image=busybox $ wget --header="Host: example.com" -qO- main-nginx-ingress    # …
    
  2. Versuchen Sie die SQL-Injection. Der403 Der Statuscode „Verboten“ bestätigt, dass NGINX den Angriff blockiert!

     

    $ wget --header="Host: example.com" -qO- 'main-nginx-ingress/product/-1"%20UNION%20SELECT%20username,username,password,password,username%20FROM%20users%20where%2 0id=1%20--%20//' wget: Server hat Fehler zurückgegeben: HTTP/1.1 403 Verboten 
    

Nächste Schritte

Kubernetes ist standardmäßig nicht sicher. Ein Ingress-Controller kann SQL-Injection-Schwachstellen (und viele andere) abschwächen. Bedenken Sie jedoch, dass die Art von WAF-ähnlicher Funktionalität, die Sie gerade mit NGINX Ingress Controller implementiert haben, weder ein echtes WAF noch die sichere Architektur von Apps ersetzt. Ein versierter Hacker kann den UNION- Hack mit einigen kleinen Änderungen am Code dennoch zum Laufen bringen. Weitere Informationen zu diesem Thema finden Sie im A Pentester's Guide to SQL Injection (SQLi) .

Dennoch ist ein Ingress-Controller immer noch ein leistungsstarkes Tool zur Zentralisierung des Großteils Ihrer Sicherheit und führt zu mehr Effizienz und Sicherheit, einschließlich zentralisierter Authentifizierungs- und Autorisierungsanwendungsfälle (mTLS, Single Sign-On) und sogar eines robusten WAF wie F5 NGINX App Protect WAF .

Aufgrund der Komplexität Ihrer Apps und Architektur ist möglicherweise eine genauere Steuerung erforderlich. Wenn Ihre Organisation Zero Trust und End-to-End -Verschlüsselung benötigt, sollten Sie ein Service Mesh wie das immer kostenlose F5 NGINX Service Mesh in Betracht ziehen, um die Kommunikation zwischen Diensten im Kubernetes-Cluster (Ost-West-Verkehr) zu steuern. Wir untersuchen Service-Meshes in Einheit 4, Erweiterte Bereitstellungsstrategien für Kubernetes .

Ausführliche Informationen zum Bezug und zur Bereitstellung von NGINX Open Source finden Sie unter nginx.org .

Um den auf NGINX Plus basierenden NGINX Ingress Controller mit NGINX App Protect auszuprobieren, starten Sie noch heute Ihre kostenlose 30-Tage-Testversion oder kontaktieren Sie uns, um Ihre Anwendungsfälle zu besprechen . 

Um den auf NGINX Open Source basierenden NGINX Ingress Controller auszuprobieren, sehen Sie sich die NGINX Ingress Controller Releases in unserem GitHub-Repo an oder laden Sie einen vorgefertigten Container von DockerHub herunter. 


„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."