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
コンテナ ID イメージ コマンド 作成 ステータス ポート 名前
2. Linux ホストで Github リポジトリをクローンします。
f5@ubuntu:~$ git clone https://github.com/f5devcentral/NGINX-Declarative-API/
'NGINX-Declarative-API' にクローンしています...
リモート: オブジェクトの列挙: 4072、完了。
リモート: オブジェクトのカウント: 100% (1982/1982)、完了。
リモート: オブジェクトの圧縮: 100% (1332/1332)、完了。
リモート: 合計 4072 (差分 668)、再利用 876 (差分 609)、パック再利用 2090
受信オブジェクト: 100% (4072/4072)、19.05 MiB | 4.88 MiB/s、完了。
デルタの解決: 100% (1154/1154)、完了。
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
-> docker イメージを更新しています
[+] 11/11 をプルしています
[...]
-> NGINX Declarative API をデプロイしています
[+] 4/4 を実行しています
✔ ネットワーク nginx-dapi_dapi-network の作成に 0.1 秒かかりました
✔ コンテナ redis が開始しました 1.5 秒かかりました
✔ コンテナ devportal が開始しました 1.5 秒かかりました
✔ コンテナ nginx-dapi が開始しました
5. 実行中の Docker コンテナを確認します。
f5@ubuntu:~/NGINX-Declarative-API/contrib/docker-compose$ docker ps
コンテナ ID イメージ コマンド 作成日時 ステータス ポート 名前
e29a2f783da2 nginx-declarative-api "/deployment/env/bin…" 5 分前 5 分前に起動 0.0.0.0:5000->5000/tcp、:::5000->5000/tcp nginx-dapi
97142840eaf7 redis "docker-entrypoint.s…" 5 分前 5 分前に起動 0.0.0.0:6379->6379/tcp、:::6379->6379/tcp redis
6b50c0426643 nginx-declarative-api-devportal "/deployment/src/sta…" 5 分前 5 分前に起動 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 宣言は次のようになります。
{
"出力": {
"タイプ": "nms",
"nms": {
"url": "{{nim_host}}",
"ユーザー名": "{{nim_username}}",
"パスワード": "{{nim_password}}",
"インスタンスグループ": "{{nim_instancegroup}}",
"同期時間": 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": 「プロダクション ポリシー - XSS がブロックされました」
「説明」: 「これは本番環境対応のポリシーです - XSS はブロックされています」
「contents」: {
「content」: 「{{github_gitops_root}}/v4.2/nap-policy-xss-blocked-bot-allowed.json」
}
},
{
「tag」: 「xss-allowed」
「displayName」: 「プロダクション ポリシー - XSS が許可されています」、
「説明」: 「これは本番環境対応のポリシーです - XSS が許可されています」
「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": {
"アドレス": "0.0.0.0:443",
"http2": true,
"tls": {
"証明書": "test_cert",
"キー": "test_key",
"暗号": "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"
},
"認証": {
"クライアント": [
{
"プロファイル": 「Petstore JWT 認証」
}
],
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
},
"authorization": [
{
"profile": "JWT ロールベースの認証",
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
}
],
"rate_limit": [
{
"profile": "petstore_ratelimit",
"httpcode": 429,
「バースト」: 0,
「遅延」: 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」
「レート」: 「2r/s」
}
],
「認証」: {
「クライアント」: [
{
「名前」: 「Petstore JWT 認証」、
「type」:「jwt」、
「jwt」: {
「realm」: 「ペットストア認証」、
「キー」: 「{\"keys\": [{\"k\":\"ZmFudGFzdGljand0\",\"kty\":\"oct\",\"kid\":\"0001\"}]}",
「キャッシュ時間」: 5
}
}
]
},
"承認": [
{
"名前": 「JWT ロールベースの認証」、
「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
に適用されます。
"認証": {
"クライアント": [
{
"プロファイル": 「Petstore JWT 認証」
}
],
「enforceOnPaths」: true,
「paths」: [
「/user/login」
「/user/logout」
]
},
指定されたクライアント認証プロファイルに基づくクライアント認証が/user/login
および/user/logout
に適用されます。
「承認」: [
{
「プロファイル」: "JWT ロールベースの認証",
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
}
],
指定されたプロファイルに基づいて、 /user/login
および/user/logout
にレート制限が適用されます。
"rate_limit": [
{
"profile": "petstore_ratelimit",
"httpcode": 429,
「バースト」: 0,
「遅延」: 0,
"enforceOnPaths": true,
"paths": [
"/user/login",
"/user/logout"
]
}
]
},
12. Postman の送信
ボタンを使用して、宣言型 API にリクエストを公開します。応答は次のようになります。
{
「コード」: 200,
「コンテンツ」: {
「作成時間」: "2024-04-26T17:09:10.419574328Z",
"詳細": {
"失敗": [],
"保留中": [],
"成功": [
{
"名前": "vm-test"
}
]
},
"ID": "1060ec49-120e-45ca-820b-5203c8b3538d",
"メッセージ": 「インスタンス グループ構成が declarativeAPITest に正常に公開されました」、
「ステータス」: 「成功」、
「更新時間」: "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
日付: 2024 年 4 月 26 日金曜日 17:13:54 GMT
content-type: application/json
access-control-allow-origin: *
access-control-allow-methods: GET、POST、DELETE、PUT
アクセス制御許可ヘッダー: コンテンツ タイプ、api_key、認証
{"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
日付: 2024年4月26日(金)17:14:51 GMT
コンテンツタイプ: text/html
コンテンツの長さ: 179
www認証: ベアラーレルム="Petstore 認証"
<html>
<head><title>401 認証が必要です</title></head>
<body>
<center><h1>401 認証が必要です</h1></center>
<hr><center>nginx/1.25.3</center>
</body>
</html>
HTTP/2 429
日付: 2024年4月26日(金)17:14:51 GMT
コンテンツタイプ: text/html
コンテンツの長さ: 169
<html>
<head><title>429 リクエストが多すぎます</title></head>
<body>
<center><h1>429 リクエストが多すぎます</h1></center>
<hr><center>nginx/1.25.3</center>
</body>
</html>
4. 認証と有効な承認:
$ curl -w '\n' -ki https://apigw.nginx.lab/petstore/user/login -H "認証: ベアラー `cat jwt.devops`"
HTTP/2 200
日付: 2024 年 4 月 26 日金曜日 17:15:41 GMT
content-type: application/json
access-control-allow-origin: *
access-control-allow-methods: GET、POST、DELETE、PUT
アクセス制御許可ヘッダー: コンテンツ タイプ、api_key、認証
x-expires-after: 2024 年 4 月 26 日金曜日 18:15:41 UTC
x-rate-limit: 5000
{"code":200,"type":"unknown","message":"ログインしたユーザー セッション:1714151741883"}
5. 認証と無効な承認:
$ curl -w '\n' -ki https://apigw.nginx.lab/petstore/user/login -H "認証: ベアラー `cat jwt.guest`"
HTTP/2 403
日付: 2024年4月26日(金)17:16:07 GMT
コンテンツタイプ: text/html
コンテンツの長さ: 153
<html>
<head><title>403 禁止</title></head>
<body>
<center><h1>403 禁止</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 コンテンツタイプ: text/html; 文字セット=utf-8 キャッシュ制御: no-cache プラグマ: no-cache コンテンツ長: 246
<html><head><title>リクエストが拒否されました</title></head><body>要求された URL は拒否されました。 管理者にご相談ください。サポート ID は次のとおりです: 7283327928460093545[戻る]
7. 開発者ポータルには、次のURLからアクセスできます。
https://apigw.nginx.lab/petstore/petstore-devportal.html
この記事で紹介した NGINX ソリューションをお試しいただくには、今すぐ 30 日間の無料トライアルを開始するか、弊社までお問い合わせのうえ、ユースケースについてご相談ください。
NGINX Agentをダウンロードしてください。無料のオープンソースです。
「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"