NGINX は、高性能 Web サーバーとロードバランサーを強化するための最優先の選択肢の 1 つとして長い間認識されてきました。 しかし、マイクロサービス アーキテクチャの台頭と効率的な API 管理の必要性により、NGINX も API ゲートウェイの構築に人気の選択肢になりました。
このブログでは、宣言型 API アプローチを使用して、OpenAPI スキーマ定義を、 Web アプリケーション ファイアウォールセキュリティと開発者ポータルを備えた API ゲートウェイとして実行される、完全に機能する NGINX 構成に変換する方法について説明します。
NGINX Plus を活用して API 管理プロセスを効率化し、アプリケーションのパフォーマンスを最適化する方法について、ステップバイステップの手順と洞察を提供します。
API ゲートウェイは、クライアントとバックエンド サービス間の通信を管理および保護するための中央ハブとして機能します。 これは、クライアントとバックエンド サーバーの間に位置し、受信した要求をルーティングして適切なサービスに配布するリバース プロキシとして機能します。 これにより、クライアントとサービス間の通信がより効率的になり、API ゲートウェイが認証、承認、レート制限、キャッシュなどのタスクを処理できるようになります。
さらに、API ゲートウェイはセキュリティ レイヤーとして機能し、バックエンド サービスを潜在的な脅威や攻撃から保護します。 暗号化、トークンベースの認証、アクセス制御などのセキュリティ対策を実施し、許可されたユーザーのみがサービスにアクセスできるようにします。 API ゲートウェイは、これらのセキュリティ機能を 1 か所に統合して管理することで、システムの全体的なセキュリティ アーキテクチャを簡素化し、複数のサービスにわたるセキュリティ対策の実装の複雑さを軽減します。
コミュニティがサポートするNGINX Declarative APIプロジェクトは、 NGINX Instance Manager用の宣言型 REST API のセットを提供します。
NGINX Plus 構成ライフサイクルを管理し、JSON サービス定義を使用して NGINX Plus 構成を作成するために使用できます。 NGINX インスタンス マネージャーと併用すると、GitOps 統合がサポートされます。参照オブジェクトの更新について真実のソースがチェックされ、NGINX 構成が自動的に同期されます。
OpenAPI スキーマを使用すると、NGINX を API ゲートウェイとして自動的に構成できます。 開発者ポータルの作成はRedoclyを通じてサポートされます。
このブログのコンテンツを実行するには、次のものが必要です。
宣言型APIテスト
インスタンスグループすべての前提条件をインストールして実行すると、NGINX インスタンス マネージャーは、NGINX App Protect WAF を使用して NGINX Plus インスタンスをオンラインとして表示します。
NGINX PlusインスタンスはdeclarativeAPITest
インスタンスグループの一部です。
NGINX 宣言型 API プロジェクトは、NGINX インスタンス マネージャーによって提供される REST API に依存し、宣言型の JSON ベースの抽象化を提供します。 宣言型 API プロジェクトを実行するには、次の手順に従ってください。
1. docker ps を実行して、Docker が実行されていることを確認します。
f5@ubuntu:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2. Linux ホストで Github リポジトリをクローンします。
f5@ubuntu:~$ git clone https://github.com/f5devcentral/NGINX-Declarative-API/
Cloning into 'NGINX-Declarative-API'...
remote: Enumerating objects: 4072, done.
remote: Counting objects: 100% (1982/1982), done.
remote: Compressing objects: 100% (1332/1332), done.
remote: Total 4072 (delta 668), reused 876 (delta 609), pack-reused 2090
Receiving objects: 100% (4072/4072), 19.05 MiB | 4.88 MiB/s, done.
Resolving deltas: 100% (1154/1154), done.
f5@ubuntu:~$
3. docker-compose ディレクトリに変更します。
f5@ubuntu:~$ cd NGINX-Declarative-API/contrib/docker-compose/
4. nginx-dapi.sh
スクリプトを使用して、docker-compose を通じてすべてのコンテナを起動します。 最初の起動時に、すべての Docker イメージが自動的に構築されます。
f5@ubuntu:~/NGINX-Declarative-API/contrib/docker-compose$ ./nginx-dapi.sh -c start
-> Updating docker images
[+] Pulling 11/11
[...]
-> Deploying NGINX Declarative API
[+] Running 4/4
✔ Network nginx-dapi_dapi-network Created 0.1s
✔ Container redis Started 1.5s
✔ Container devportal Started 1.5s
✔ Container nginx-dapi Started
5. 実行中の Docker コンテナを確認します。
f5@ubuntu:~/NGINX-Declarative-API/contrib/docker-compose$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e29a2f783da2 nginx-declarative-api "/deployment/env/bin…" 5 minutes ago Up 5 minutes 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp nginx-dapi
97142840eaf7 redis "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis
6b50c0426643 nginx-declarative-api-devportal "/deployment/src/sta…" 5 minutes ago Up 5 minutes 0.0.0.0:5001->5000/tcp, :::5001->5000/tcp devportal
6. クライアントホストで Postman を実行し、 https ://raw.githubusercontent.com/f5devcentral/NGINX-Declarative-API/main/contrib/postman/NGINX%20Declarative%20API.postman_collection.json にある NGINX Declarative API コレクションをインポートします。
7. Postman コレクション変数を編集して、環境に合わせて調整します。
8. 次の変数を設定します。
ncg_host
- 宣言型 API docker-compose が実行されている Linux ホストのホスト名または IP アドレスncg_port
- NGINX 宣言型 API の TCP ポート: 5000がデフォルトですnim_host
- NGINX インスタンス マネージャーのベース URL (例: https://nms.k8s.ie.ff.lan)nim_username
- NGINXインスタンスマネージャー認証ユーザー名nim_password
- NGINXインスタンスマネージャーの認証パスワード9. Postmanですべての変更を保存する
10. Postmanコレクションで、 Petstore API Gateway RateLimit + JWT AuthN/AuthZ + WAF
を参照してリクエストを開きます。
JSON 宣言は次のようになります。
{
"output": {
"type": "nms",
"nms": {
"url": "{{nim_host}}",
"username": "{{nim_username}}",
"password": "{{nim_password}}",
"instancegroup": "{{nim_instancegroup}}",
"synctime": 0,
"modules": [
"ngx_http_app_protect_module"
],
"certificates": [
{
"type": "certificate",
"name": "test_cert",
"contents": {
"content": "{{github_gitops_root}}/v4.2/testcert.crt"
}
},
{
"type": "key",
"name": "test_key",
"contents": {
"content": "{{github_gitops_root}}/v4.2/testcert.key"
}
}
],
"policies": [
{
"type": "app_protect",
"name": "production-policy",
"active_tag": "xss-blocked",
"versions": [
{
"tag": "xss-blocked",
"displayName": "Production Policy - XSS blocked",
"description": "This is a production-ready policy - XSS blocked",
"contents": {
"content": "{{github_gitops_root}}/v4.2/nap-policy-xss-blocked-bot-allowed.json"
}
},
{
"tag": "xss-allowed",
"displayName": "Production Policy - XSS allowed",
"description": "This is a production-ready policy - XSS allowed",
"contents": {
"content": "{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json"
}
}
]
}
]
}
},
"declaration": {
"http": {
"servers": [
{
"name": "Petstore API",
"names": [
"apigw.nginx.lab"
],
"resolver": "8.8.8.8",
"listen": {
"address": "0.0.0.0:443",
"http2": true,
"tls": {
"certificate": "test_cert",
"key": "test_key",
"ciphers": "DEFAULT",
"protocols": [
"TLSv1.2",
"TLSv1.3"
]
}
},
"log": {
"access": "/var/log/nginx/apigw.nginx.lab-access_log",
"error": "/var/log/nginx/apigw.nginx.lab-error_log"
},
"locations": [
{
"uri": "/petstore",
"urimatch": "prefix",
"apigateway": {
"openapi_schema": {
"content": "http://petstore.swagger.io/v2/swagger.json"
},
"api_gateway": {
"enabled": true,
"strip_uri": true,
"server_url": "https://petstore.swagger.io/v2"
},
"developer_portal": {
"enabled": true,
"uri": "/petstore-devportal.html"
},
"authentication": {
"client": [
{
"profile": "Petstore JWT Authentication"
}
],
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
},
"authorization": [
{
"profile": "JWT role based authorization",
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
}
],
"rate_limit": [
{
"profile": "petstore_ratelimit",
"httpcode": 429,
"burst": 0,
"delay": 0,
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
}
]
},
"log": {
"access": "/var/log/nginx/petstore-access_log",
"error": "/var/log/nginx/petstore-error_log"
},
"app_protect": {
"enabled": true,
"policy": "production-policy",
"log": {
"profile_name": "secops_dashboard",
"enabled": true,
"destination": "127.0.0.1:514"
}
}
}
]
}
],
"rate_limit": [
{
"name": "petstore_ratelimit",
"key": "$binary_remote_addr",
"size": "10m",
"rate": "2r/s"
}
],
"authentication": {
"client": [
{
"name": "Petstore JWT Authentication",
"type": "jwt",
"jwt": {
"realm": "Petstore Authentication",
"key": "{\"keys\": [{\"k\":\"ZmFudGFzdGljand0\",\"kty\":\"oct\",\"kid\":\"0001\"}]}",
"cachetime": 5
}
}
]
},
"authorization": [
{
"name": "JWT role based authorization",
"type": "jwt",
"jwt": {
"claims": [
{
"name": "roles",
"value": [
"~(devops)"
],
"errorcode": 403
}
]
}
}
]
}
}
}
出力
セクションでは以下を定義します。
宣言
セクションでは以下について説明します。
/petstore
ベース URIAPI Gateway 宣言セクションでは、宣言型 API が結果をどのように配信するかについて説明します。
OpenAPI スキーマは、完全な URL を通じて参照されます。
"apigateway": {
"openapi_schema": {
"content": "http://petstore.swagger.io/v2/swagger.json"
},
NGINX API ゲートウェイ構成の作成が要求され、アップストリーム サーバーが定義されます。 NGINX がリクエストをアップストリームにリバース プロキシすると、 /petstore
ベース URI が削除されます。
"api_gateway": {
"enabled": true,
"strip_uri": true,
"server_url": "https://petstore.swagger.io/v2"
},
特定の URI での開発者ポータルの作成とデプロイが要求されます。
"developer_portal": {
"enabled": true,
"uri": "/petstore-devportal.html"
},
指定されたクライアント認証プロファイルに基づくクライアント認証が/user/login
および/user/logout
に適用されます。
"authentication": {
"client": [
{
"profile": "Petstore JWT Authentication"
}
],
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
},
指定されたクライアント認証プロファイルに基づくクライアント認証が/user/login
および/user/logout
に適用されます。
"authorization": [
{
"profile": "JWT role based authorization",
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
}
],
指定されたプロファイルに基づいて、 /user/login
および/user/logout
にレート制限が適用されます。
"rate_limit": [
{
"profile": "petstore_ratelimit",
"httpcode": 429,
"burst": 0,
"delay": 0,
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
}
]
},
12. Postman の送信
ボタンを使用して、宣言型 API にリクエストを公開します。応答は次のようになります。
{
"code": 200,
"content": {
"createTime": "2024-04-26T17:09:10.419574328Z",
"details": {
"failure": [],
"pending": [],
"success": [
{
"name": "vm-test"
}
]
},
"id": "1060ec49-120e-45ca-820b-5203c8b3538d",
"message": "Instance Group config successfully published to declarativeAPITest",
"status": "successful",
"updateTime": "2024-04-26T17:09:10.881509913Z"
},
"configUid": "eecf1da6-9d8f-4e44-89cc-a470af79379d"
}
13. この段階では、NGINX インスタンスが API ゲートウェイとして構成され、WAF セキュリティが適用され、開発者ポータルが公開されます。
注: FQDN apigw.nginx.lab
は、NGINX インスタンスが実行されている仮想マシンの IP アドレスに解決されると想定されています。
1. jwt
ディレクトリに変更します。
f5@ubuntu:~$ cd ~/NGINX-Declarative-API/contrib/gitops-examples/jwt
2. 認証されていない REST API エンドポイントにアクセスします。
$ curl -w '\n' -ki https://apigw.nginx.lab/petstore/store/inventory
HTTP/2 200
date: Fri, 26 Apr 2024 17:13:54 GMT
content-type: application/json
access-control-allow-origin: *
access-control-allow-methods: GET, POST, DELETE, PUT
access-control-allow-headers: Content-Type, api_key, Authorization
{"totvs":5,"aut":1,"FORsold":1,[...]
3. レート制限:
$ 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
date: Fri, 26 Apr 2024 17:14:51 GMT
content-type: text/html
content-length: 179
www-authenticate: Bearer realm="Petstore Authentication"
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.25.3</center>
</body>
</html>
HTTP/2 429
date: Fri, 26 Apr 2024 17:14:51 GMT
content-type: text/html
content-length: 169
<html>
<head><title>429 Too Many Requests</title></head>
<body>
<center><h1>429 Too Many Requests</h1></center>
<hr><center>nginx/1.25.3</center>
</body>
</html>
4. 認証と有効な承認:
$ curl -w '\n' -ki https://apigw.nginx.lab/petstore/user/login -H "Authorization: Bearer `cat jwt.devops`"
HTTP/2 200
date: Fri, 26 Apr 2024 17:15:41 GMT
content-type: application/json
access-control-allow-origin: *
access-control-allow-methods: GET, POST, DELETE, PUT
access-control-allow-headers: Content-Type, api_key, Authorization
x-expires-after: Fri Apr 26 18:15:41 UTC 2024
x-rate-limit: 5000
{"code":200,"type":"unknown","message":"logged in user session:1714151741883"}
5. 認証と無効な承認:
$ curl -w '\n' -ki https://apigw.nginx.lab/petstore/user/login -H "Authorization: Bearer `cat jwt.guest`"
HTTP/2 403
date: Fri, 26 Apr 2024 17:16:07 GMT
content-type: text/html
content-length: 153
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.25.3</center>
</body>
</html>
6. NGINX App Protect WAF およびクロスサイト スクリプティングのセキュリティ違反:
$ curl -w '\n' -ki "https://apigw.nginx.lab/petstore/store/inventory?
"
HTTP/2 200
content-type: text/html; charset=utf-8
cache-control: no-cache
pragma: no-cache
content-length: 246
<html><head><title>Request Rejected</title></head><body>The requested URL was rejected. Please consult with your administrator.<br><br>Your support ID is: 7283327928460093545<br><br><a href='javascript:history.back();'>[Go Back]</a></body></html>
7. 開発者ポータルには、次のURLからアクセスできます。
https://apigw.nginx.lab/petstore/petstore-devportal.html
この記事で紹介した NGINX ソリューションをお試しいただくには、今すぐ 30 日間の無料トライアルを開始するか、弊社までお問い合わせのうえ、ユースケースについてご相談ください。
NGINX Agentをダウンロードしてください。無料のオープンソースです。
「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 q。"