NGINX gilt seit langem als eine der besten Optionen für den Betrieb leistungsstarker Webserver und Lastenausgleichsmodule. Mit dem Aufkommen von Microservices-Architekturen und dem Bedarf an effizienter API-Verwaltung ist NGINX jedoch auch eine beliebte Wahl für den Aufbau von API-Gateways geworden.
In diesem Blog untersuchen wir, wie eine OpenAPI-Schemadefinition in eine voll funktionsfähige NGINX-Konfiguration umgewandelt wird, die als API-Gateway mit Web Application Firewall- Sicherheit und Entwicklerportal unter Verwendung eines deklarativen API-Ansatzes ausgeführt wird.
Wir bieten Ihnen Schritt-für-Schritt-Anleitungen und Einblicke, wie Sie NGINX Plus nutzen können, um Ihre API-Verwaltungsprozesse zu optimieren und eine optimale Leistung für Ihre Anwendungen sicherzustellen.
Ein API-Gateway dient als zentraler Hub zum Verwalten und Sichern der Kommunikation zwischen Clients und Backend-Diensten. Es fungiert als Reverse-Proxy, der zwischen dem Client und den Backend-Servern sitzt, eingehende Anfragen weiterleitet und an die entsprechenden Dienste verteilt. Dies ermöglicht eine effizientere Kommunikation zwischen dem Client und den Diensten und ermöglicht es dem API-Gateway, Aufgaben wie Authentifizierung , Autorisierung , Ratenbegrenzung und Caching zu übernehmen.
Darüber hinaus kann ein API-Gateway als Sicherheitsebene fungieren und die Backend-Dienste vor potenziellen Bedrohungen und Angriffen schützen. Es kann Sicherheitsmaßnahmen wie Verschlüsselung, tokenbasierte Authentifizierung und Zugriffskontrolle durchsetzen und so sicherstellen, dass nur autorisierte Benutzer auf die Dienste zugreifen können. Durch die Konsolidierung und Verwaltung dieser Sicherheitsfunktionen an einem einzigen Ort trägt das API-Gateway dazu bei, die allgemeine Sicherheitsarchitektur des Systems zu vereinfachen und die Komplexität der Implementierung von Sicherheitsmaßnahmen über mehrere Dienste hinweg zu verringern.
Das von der Community unterstützte NGINX Declarative API- Projekt bietet eine Reihe deklarativer REST-APIs für den NGINX Instance Manager .
Es kann verwendet werden, um NGINX Plus-Konfigurationslebenszyklen zu verwalten und NGINX Plus-Konfigurationen mithilfe von JSON-Dienstdefinitionen zu erstellen. Bei Verwendung mit NGINX Instance Manager wird die GitOps-Integration unterstützt: Die Quelle der Wahrheit wird auf Aktualisierungen referenzierter Objekte überprüft und NGINX-Konfigurationen werden automatisch synchronisiert.
OpenAPI-Schemas können verwendet werden, um NGINX automatisch als API-Gateway zu konfigurieren. Die Erstellung von Entwicklerportalen wird durch Redocly unterstützt.
Um die Inhalte dieses Blogs auszuführen, benötigen Sie:
declarativeAPITest-
Instanzgruppe zu seinNach der Installation und Ausführung aller Voraussetzungen zeigt der NGINX Instance Manager die NGINX Plus-Instanz mit NGINX App Protect WAF als online an.
Die NGINX Plus-Instanz ist Teil der declarativeAPITest
-Instanzgruppe
Das NGINX Declarative API-Projekt basiert auf der vom NGINX Instance Manager bereitgestellten REST-API und bietet die deklarative, JSON-basierte Abstraktion. Befolgen Sie diese Anweisungen, um das deklarative API-Projekt auszuführen:
1. Führen Sie „docker ps“ aus, um zu überprüfen, ob Docker ausgeführt wird:
f5@ubuntu:~$ docker ps
CONTAINER-ID IMAGE-BEFEHL ERSTELLT STATUS PORTS NAMEN
2. Klonen Sie auf dem Linux-Host das Github-Repository:
f5@ubuntu:~$ git clone https://github.com/f5devcentral/NGINX-Declarative-API/
Klonen in „NGINX-Declarative-API“...
remote: Objekte aufzählen: 4072, fertig.
Remote: Objekte zählen: 100 % (1982/1982), erledigt.
Fernbedienung: Komprimieren von Objekten: 100 % (1332/1332), fertig.
Remote: Gesamt 4072 (Delta 668), wiederverwendet 876 (Delta 609), Pack-wiederverwendet 2090
Empfangene Objekte: 100 % (4072/4072), 19,05 MiB | 4,88 MiB/s, fertig.
Auflösen von Deltas: 100 % (1154/1154), erledigt.
f5@ubuntu:~$
3. Wechseln Sie in das Docker-Compose-Verzeichnis:
f5@ubuntu:~$ cd NGINX-Declarative-API/contrib/docker-compose/
4. Verwenden Sie das Skript nginx-dapi.sh,
um alle Container über Docker-Compose zu starten. Beim ersten Start werden alle Docker-Images automatisch erstellt:
f5@ubuntu:~/NGINX-Declarative-API/contrib/docker-compose$ ./nginx-dapi.sh -c start
-> Docker-Images aktualisieren
[+] 11/11 abrufen
[...]
-> NGINX Declarative API bereitstellen
[+] 4/4 ausführen
✔ Netzwerk nginx-dapi_dapi-network erstellt 0,1 s
✔ Container redis gestartet 1,5 s
✔ Container devportal gestartet 1,5 s
✔ Container nginx-dapi gestartet
5. Überprüfen Sie laufende Docker-Container:
f5@ubuntu:~/NGINX-Declarative-API/contrib/docker-compose$ docker ps
CONTAINER-ID IMAGE BEFEHL ERSTELLT STATUS PORTS NAMEN
e29a2f783da2 nginx-declarative-api "/deployment/env/bin…" vor 5 Minuten Aktiv vor 5 Minuten 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp nginx-dapi
97142840eaf7 redis "docker-entrypoint.s…" vor 5 Minuten Aktiv vor 5 Minuten 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis
6b50c0426643 nginx-declarative-api-devportal "/deployment/src/sta…" vor 5 Minuten Aktiv seit 5 Minuten 0.0.0.0:5001->5000/tcp, :::5001->5000/tcp devportal
6. Führen Sie auf dem Client-Host Postman aus und importieren Sie die NGINX Declarative API-Sammlung unter https://raw.githubusercontent.com/f5devcentral/NGINX-Declarative-API/main/contrib/postman/NGINX%20Declarative%20API.postman_collection.json.
7. Bearbeiten Sie die Postman-Sammlungsvariablen, um sie an Ihre Umgebung anzupassen:
8. Legen Sie die folgenden Variablen fest:
ncg_host
- Hostname oder IP-Adresse des Linux-Hosts, auf dem die deklarative API Docker-Compose ausgeführt wirdncg_port
– TCP-Port für die NGINX Declarative API: 5000 ist der Standardwertnim_host
– Basis-URL des NGINX Instance Managers (z. B. https://nms.k8s.ie.ff.lan)nim_username
– NGINX Instance Manager-Authentifizierungsbenutzernamenim_password
- Authentifizierungskennwort für NGINX Instance Manager9. Alle Änderungen in Postman speichern
10. Navigieren Sie in der Postman-Sammlung zu Petstore API Gateway RateLimit + JWT AuthN/AuthZ + WAF
und öffnen Sie die Anfrage
Die JSON-Deklaration sieht wie folgt aus:
{
"Ausgabe": {
"Typ": "nms",
"nms": {
"URL": "{{nim_host}}",
"Benutzername": "{{nim_username}}",
"Passwort": "{{nim_password}}",
"Instanzgruppe": "{{nim_instancegroup}}",
"Synchronisierungszeit": 0,
„Module“: [
„ngx_http_app_protect_module“
],
„Zertifikate“: [
{
„Typ“: „Zertifikat“,
„Name“: „Testzertifikat“,
„Inhalt“: {
„Inhalt“: „{{github_gitops_root}}/v4.2/testcert.crt“
}
},
{
„Typ“: „Schlüssel“,
„Name“: „Testschlüssel“,
„Inhalt“: {
„Inhalt“: „{{github_gitops_root}}/v4.2/testcert.key“
}
}
],
„Richtlinien“: [
{
„Typ“: „App_protect“,
„Name“: „Produktionsrichtlinie“,
„Active_Tag“: „xss-blockiert“,
„Versionen“: [
{
„Tag“: „xss-blockiert“,
„Anzeigename“: „Produktionsrichtlinie – XSS blockiert“,
„Beschreibung“: „Dies ist eine produktionsreife Richtlinie – XSS blockiert“,
„contents“: {
„content“: „{{github_gitops_root}}/v4.2/nap-policy-xss-blocked-bot-allowed.json“
}
},
{
„tag“: „xss-allowed“,
„displayName“: „Produktionsrichtlinie – XSS erlaubt“,
„Beschreibung“: „Dies ist eine produktionsreife Richtlinie – XSS erlaubt“,
„contents“: {
„content“: „{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json“
}
}
]
}
]
}
},
„declaration“: {
„http“: {
„servers“: [
{
„name“: "Petstore API",
"Namen": [
"apigw.nginx.lab"
],
"Resolver": "8.8.8.8",
"hören": {
"Adresse": "0.0.0.0:443",
"http2": true,
"tls": {
"Zertifikat": "Testzertifikat",
"Schlüssel": "Testschlüssel",
"Chiffren": "STANDARD",
"Protokolle": [
"TLSv1.2",
"TLSv1.3"
]
}
},
"Protokoll": {
"Zugriff": "/var/log/nginx/apigw.nginx.lab-access_log",
"Fehler": "/var/log/nginx/apigw.nginx.lab-error_log"
},
"Standorte": [
{
"URI": "/petstore",
"URI-Match": "Präfix",
"Apigateway": {
"OpenAPI_Schema": {
"Inhalt": "http://petstore.swagger.io/v2/swagger.json"
},
"API_Gateway": {
"Aktiviert": wahr,
"Strip_URI": wahr,
"Server-URL": "https://petstore.swagger.io/v2"
},
"Entwicklerportal": {
"Aktiviert": true,
"uri": "/petstore-devportal.html"
},
"Authentifizierung": {
"Client": [
{
"Profil": "Petstore JWT-Authentifizierung"
}
],
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
},
"authorization": [
{
"profile": "Rollenbasierte JWT-Autorisierung",
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
}
],
"rate_limit": [
{
"profile": "petstore_ratelimit",
"httpcode": 429,
"platzen": 0,
"Verzögerung": 0,
„enforceOnPaths“: true,
„Pfade“: [
„/user/login“,
„/user/logout“
]
}
]
},
„log“: {
„Zugriff“: „/var/log/nginx/petstore-access_log“,
„Fehler“: „/var/log/nginx/petstore-error_log“
},
„app_protect“: {
„aktiviert“: true,
„Richtlinie“: „Produktionsrichtlinie“,
„log“: {
„Profilname“: „secops_dashboard“,
„aktiviert“: true,
„Ziel“: "127.0.0.1:514"
}
}
}
]
}
],
"Ratenlimit": [
{
"Name": "petstore_ratelimit",
"Schlüssel": "$binary_remote_addr",
"Größe": "10m",
"Bewerten": "2r/s"
}
],
"Authentifizierung": {
"Client": [
{
"Name": „Petstore JWT-Authentifizierung“,
„Typ“: „jwt“,
„jwt“: {
„Bereich“: "Petstore-Authentifizierung",
"Schlüssel": "{\"Schlüssel\": [{\"k\":\"ZmFudGFzdGljand0\",\"kty\":\"oct\",\"kid\":\"0001\"}]}",
"Cachezeit": 5
}
}
]
},
"Autorisierung": [
{
"Name": „Rollenbasierte JWT-Autorisierung“,
„Typ“: „jwt“,
„jwt“: {
„Ansprüche“: [
{
„Name“: „Rollen“,
„Wert“: [
„~(devops)“
],
„Fehlercode“: 403 } ] } } ] } } }
Der Ausgabeabschnitt
definiert:
Der Deklarationsabschnitt
beschreibt:
/petstore-
Basis-URI, unter der die API-Gateway-Konfiguration bereitgestellt und für Clients zugänglich gemacht wirdDer Abschnitt „API Gateway-Deklaration“ beschreibt, wie die deklarative API ihr Ergebnis liefert.
Auf das OpenAPI-Schema wird über seine vollständige URL verwiesen:
"apigateway": {
"openapi_schema": {
"content": "http://petstore.swagger.io/v2/swagger.json"
},
Die Erstellung der NGINX API Gateway-Konfiguration wird angefordert und der Upstream-Server wird definiert. Wenn NGINX Anfragen per Reverse-Proxy an den Upstream weiterleitet, wird die /petstore-
Basis-URI entfernt:
"api_gateway": {
"aktiviert": true,
"strip_uri": true,
"server_url": "https://petstore.swagger.io/v2"
},
Die Erstellung eines Entwicklerportals und die Bereitstellung unter einer bestimmten URI sind erforderlich:
"developer_portal": {
"enabled": true,
"uri": "/petstore-devportal.html"
},
Die Client-Authentifizierung basierend auf dem angegebenen Client-Authentifizierungsprofil wird für /user/login
und /user/logout
erzwungen:
"Authentifizierung": {
"Client": [
{
"Profil": "Petstore JWT-Authentifizierung"
}
],
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
},
Die Client-Autorisierung basierend auf dem angegebenen Client-Autorisierungsprofil wird für /user/logout
und /user/logout
erzwungen:
"Autorisierung": [
{
"Profil": "Rollenbasierte JWT-Autorisierung",
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
}
],
Die Ratenbegrenzung wird für /user
/logout
basierend auf dem angegebenen Profil angewendet:
"Ratenlimit": [
{
"Profil": "petstore_Ratenlimit",
"httpcode": 429,
"platzen": 0,
"Verzögerung": 0,
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
}
]
},
12. Verwenden Sie die Schaltfläche „Senden“
von Postman, um die Anforderung an die deklarative API zu veröffentlichen. Die Antwort sieht ungefähr so aus:
{
"Code": 200,
"Inhalt": {
"Erstellungszeit": "2024-04-26T17:09:10.419574328Z",
"Details": {
"Fehler": [],
"Ausstehend": [],
"Erfolg": [
{
"Name": "vm-test"
}
]
},
"ID": "1060ec49-120e-45ca-820b-5203c8b3538d",
"Nachricht": „Instanzgruppenkonfiguration erfolgreich in declarativeAPITest veröffentlicht“,
„status“: „erfolgreich“,
„updateTime“: "2024-04-26T17:09:10.881509913Z"
},
"configUid": "eecf1da6-9d8f-4e44-89cc-a470af79379d"
}
13. In dieser Phase wird die NGINX-Instanz als API-Gateway konfiguriert, die WAF-Sicherheit erzwungen und das Entwicklerportal veröffentlicht.
Hinweis: Es wird davon ausgegangen, dass der FQDN apigw.nginx.lab
in die IP-Adresse der virtuellen Maschine aufgelöst wird, auf der die NGINX-Instanz ausgeführt wird
1. Wechseln Sie in das jwt
-Verzeichnis:
f5@ubuntu:~$ cd ~/NGINX-Declarative-API/contrib/gitops-examples/jwt
2. Greifen Sie auf einen nicht authentifizierten REST-API-Endpunkt zu:
$ curl -w '\n' -ki https://apigw.nginx.lab/petstore/store/inventory
HTTP/2 200
Datum: Fr., 26. April 2024 17:13:54 GMT
Inhaltstyp: application/json
Zugriffskontroll-Allow-Origin: *
Zugriffskontroll-Allow-Methoden: GET, POST, DELETE, PUT
Zugriffssteuerungs-Allow-Header: Inhaltstyp, API-Schlüssel, Autorisierung
{"totvs":5,"aut":1,"FORsold":1,[...]
3. Ratenbegrenzung:
$ curl -w '\n' -ki https://apigw.nginx.lab/petstore/user/login;curl -w '\n' -ki
https://apigw.nginx.lab/petstore/user/login
HTTP/2 401
Datum: Fr, 26. April 2024 17:14:51 GMT
Inhaltstyp: Text/HTML
Inhaltslänge: 179
www-authentifizieren: Bearer realm="Petstore-Authentifizierung"
<html>
<head><title>401-Autorisierung erforderlich</title></head>
<body>
<center><h1>401-Autorisierung erforderlich</h1></center>
<hr><center>nginx/1.25.3</center>
</body>
</html>
HTTP/2 429
Datum: Fr, 26. April 2024 17:14:51 GMT
Inhaltstyp: Text/HTML
Inhaltslänge: 169
<html>
<head><title>429 Zu viele Anfragen</title></head>
<body>
<center><h1>429 Zu viele Anfragen</h1></center>
<hr><center>nginx/1.25.3</center>
</body>
</html>
4. Authentifizierung und gültige Autorisierung:
$ curl -w '\n' -ki https://apigw.nginx.lab/petstore/user/login -H "Autorisierung: Träger `cat jwt.devops`"
HTTP/2 200
Datum: Fr., 26. April 2024 17:15:41 GMT
Inhaltstyp: application/json
Zugriffskontroll-Allow-Origin: *
Zugriffskontroll-Allow-Methoden: GET, POST, DELETE, PUT
Zugriffssteuerungs-Allow-Header: Inhaltstyp, API-Schlüssel, Autorisierung
x-expires-after: Fr. 26. Apr. 18:15:41 UTC 2024
x-Ratenlimit: 5000
{"code":200,"type":"unbekannt","message":"angemeldeter Benutzer:1714151741883"}
5. Authentifizierung und ungültige Autorisierung:
$ curl -w '\n' -ki https://apigw.nginx.lab/petstore/user/login -H "Autorisierung: Träger `cat jwt.guest`"
HTTP/2 403
Datum: Fr, 26. April 2024 17:16:07 GMT
Inhaltstyp: Text/HTML
Inhaltslänge: 153
<html>
<head><title>403 Verboten</title></head>
<body>
<center><h1>403 Verboten</h1></center>
<hr><center>nginx/1.25.3</center>
</body>
</html>
6. Sicherheitsverletzung bei NGINX App Protect WAF und Cross-Site-Scripting:
$ curl -w '\n' -ki "https://apigw.nginx.lab/petstore/store/inventory?
"
HTTP/2 200 Inhaltstyp: Text/HTML; Zeichensatz = UTF-8 Cache-Steuerung: kein Cache Pragma: kein Cache Inhaltslänge: 246
<html><head><title>Anfrage abgelehnt</title></head><body>Die angeforderte URL wurde abgelehnt. Bitte wenden Sie sich an Ihren Administrator.Ihre Support-ID lautet: 7283327928460093545[Zurück]
7. Das Entwicklerportal erreichen Sie über
https://apigw.nginx.lab/petstore/petstore-devportal.html
Um die in diesem Beitrag besprochenen NGINX-Lösungen auszuprobieren, starten Sie noch heute eine 30-tägige kostenlose Testversion oder kontaktieren Sie uns , um Ihre Anwendungsfälle zu besprechen:
Laden Sie NGINX Agent herunter – es ist kostenlos und Open Source.
„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."