メッシュ内のサービスが通信する場合、単純な許可/拒否ルールを超えた権限付与ロジック (カスタムヘッダーのチェック、トークンの検証、ビジネス固有のポリシーの適用など) が必要になることがよくあります。Alibaba Cloud Service Mesh (ASM) は、Envoy ext_authz フィルターを介したカスタム権限付与をサポートしており、ワークロードに到達する前にすべてのリクエストを評価する外部 gRPC サービスをデプロイできます。
このチュートリアルでは、サンプル gRPC 権限付与サービスをデプロイし、ASM に登録し、権限付与ポリシーを作成し、承認されたリクエストのみが通過することを確認する手順を説明します。
仕組み
カスタム権限付与によって保護されたサービスにリクエストが到着すると、次のようになります。
サイドカープロキシはリクエストをインターセプトし、gRPC を介して外部権限付与サービスに権限付与チェックを送信します。
権限付与サービスは、リクエスト属性 (ヘッダー、パス、本文) をポリシーロジックと照合して評価します。
権限付与サービスがリクエストを承認した場合、プロキシはそれをターゲットサービスに転送します。そうでない場合、プロキシはリクエストを直ちに拒否します。
このアーキテクチャは、権限付与ロジックをアプリケーションコードから分離し、メッシュ内のすべてのサービスで一貫したアクセス制御を可能にします。
前提条件
開始する前に、以下があることを確認してください。
Container Service for Kubernetes (ACK) クラスターが追加された ASM インスタンス。詳細については、「ASM インスタンスへのクラスターの追加」をご参照ください。
ACK クラスターに接続するように構成された kubectl。詳細については、「クラスターの kubeconfig ファイルを取得し、kubectl を使用してクラスターに接続する」をご参照ください。
カスタム権限付与サービスのデプロイ
ACK クラスターに外部権限付与サービスをデプロイします。このサービスは、カスタム権限付与に関する Istio の API 仕様に準拠し、HTTP および gRPC プロトコルの両方をサポートする必要があります。
サンプル権限付与サービスは、x-ext-authz: allow ヘッダーを含むリクエストのみを承認します。独自の権限付与ロジックを構築するには、GitHub のソースコードをご参照ください。
ext-authz.yaml という名前のファイルを次の内容で作成します。
マニフェストは、
istio/ext-authz:0.6イメージを実行する Deployment と、ポート 8000 で HTTP を、ポート 9000 で gRPC を公開する Service を作成します。サービスをデプロイします。
kubectl apply -f ext-authz.yaml期待される出力:
service/ext-authz created deployment.apps/ext-authz created権限付与サービスが正常に開始されたことを確認します。
kubectl logs "$(kubectl get pod -l app=ext-authz -n default -o jsonpath={.items..metadata.name})" -n default -c ext-authz期待される出力:
2023/12/20 08:15:39 Starting gRPC server at [::]:9000 2023/12/20 08:15:39 Starting HTTP server at [::]:8000gRPC サーバーと HTTP サーバーの両方が実行されている必要があります。
ext-authz サービスの gRPC ポート (この例では 9000) をメモします。コンソールで確認するには、次の手順を実行します。
「ACK コンソール」にログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスター] ページで、目的のクラスターを見つけ、その名前をクリックします。 左側のペインで、[ネットワーク] > [サービス] を選択します。
[サービス] ページで [ext-authz] をクリックすると、[エンドポイント] セクションに gRPC ポートが表示されます。
サンプルアプリケーションのデプロイ
httpbin および sleep アプリケーションをデプロイします。httpbin は権限付与を必要とするターゲットサービスとして機能し、sleep はテストリクエストを送信するクライアントとして機能します。
httpbin.yaml という名前のファイルを次の内容で作成します。
httpbin アプリケーションをデプロイします。
kubectl apply -f httpbin.yamlsleep.yaml という名前のファイルを次の内容で作成します。
sleep アプリケーションをデプロイします。
kubectl apply -f sleep.yaml
ASM での権限付与サービスの登録
メッシュが gRPC を介して権限付与リクエストをルーティングできるように、ext-authz サービスを ASM インスタンスに登録します。
ASM コンソールにログインします。左側のナビゲーションウィンドウで、[Service Mesh] > [メッシュ管理] を選択します。
[メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションウィンドウで、[メッシュセキュリティセンター] > [カスタム承認サービス] を選択します。[カスタム承認サービスの定義] をクリックします。
[カスタム権限付与サービスの登録] ページで、[envoy.ext_authz に基づいて実装されたカスタム権限付与サービス (HTTP または GRPC プロトコル)] タブをクリックし、次の表の説明に従ってパラメーターを設定し、次に [作成] をクリックします。
必須パラメーター
パラメーター 説明 例 プロトコル 権限付与サービスで使用されるプロトコルです。 GRPC 名前 権限付与サービス登録の名前です。 testサービスアドレス エンドポイントは、 <Service name>.<Namespace>.svc.<Cluster domain>のフォーマットで指定します。ext-authz.default.svc.cluster.localポート (1 - 65535) 権限付与サービスの gRPC ポートです。 9000タイムアウト (秒) 権限付与応答を待機する最大秒数です。この期間内にサービスが応答しない場合、サービスは利用不可とみなされます。 10オプションパラメーター
パラメーター 説明 権限付与サービスが利用できない場合の認証スキップ 有効にすると、権限付与サービスに到達不能な場合でもリクエストを許可します。無効にすると、リクエストは拒否されます。 Auth-Service が利用できない場合に ASM プロキシが返すエラーコード 権限付与サービスが利用できない場合に呼び出し元に返される HTTP エラーコードです。権限付与サービスが利用できない場合の認証スキップが無効になっている場合にのみ利用可能です。 認可リクエストへのオリジンリクエストボディの付加 有効にすると、認可リクエストにリクエストボディが含まれます。最大ボディ長を指定してください。不完全なメッセージを Auth-Service へ送信することを許可も有効になっている場合、最大長を超えるボディは転送前に切り捨てられます。
権限付与ポリシーの作成
権限付与が必要なリクエストを定義するには、一致するリクエストを ext-authz サービスを経由してルーティングする権限付与ポリシーを作成します。
ASM コンソール にログインします。左側のナビゲーションウィンドウで、Service Mesh > Mesh Management を選択します。
Mesh Management ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションウィンドウで、Mesh Security Center > AuthorizationPolicy を選択し、[作成] をクリックします。
[作成] ページで、以下の表に示すパラメーターを設定し、その後 [作成] をクリックします。
パラメーター 説明 例の値 [名前] 権限付与ポリシーの名前です。 test1ポリシータイプ ポリシーの種類です。[カスタム権限付与サービス] を選択すると、前のステップで登録した ext-authz サービスが使用されます。 カスタム認可サービス カスタム承認サービス 登録済みの権限付与サービスです。 grpcextauth-test(GRPC) [名前空間] ポリシーが適用される名前空間です。[ワークロード範囲] タブで設定します。 default[適用範囲] ポリシーが特定のサービスに適用されるか、または名前空間全体に適用されるかを指定します。 サービス ワークロード 保護対象のワークロードです。 httpbin[リクエスト一致ルール] 権限付与をトリガーするリクエストパスです。[リクエストターゲットの追加] セクションで、[パス] を有効化し、パスを指定します。 /headersこの構成により、
/headersパスへの httpbin サービスに対するリクエストのみが、権限付与サービスへ送信され評価されます。他のパスへのリクエストは権限付与をバイパスします。
権限付与設定の検証
権限付与ポリシーが期待どおりに機能することを確認するために、3 つのテストを実行します。
テスト 1: 権限付与なしのパスへのリクエスト
権限付与ポリシーの対象外である /ip へのリクエストを送信します。
kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -n default -- curl "http://httpbin.default:8000/ip" -s -o /dev/null -w "%{http_code}\n"期待される出力: 200
/ip パスが権限付与ポリシーと一致しないため、リクエストは成功します。
テスト 2: 権限付与サービスによって拒否されたリクエスト
ヘッダー x-ext-authz: deny を付けて /headers へのリクエストを送信します。
kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -n default -- curl "http://httpbin.default:8000/headers" -H "x-ext-authz: deny" -s期待される出力:
denied by ext_authz for not found header `x-ext-authz: allow` in the request必要な x-ext-authz: allow ヘッダーがないため、権限付与サービスはリクエストを拒否します。
テスト 3: 権限付与サービスによって承認されたリクエスト
ヘッダー x-ext-authz: allow を付けて /headers へのリクエストを送信します。
kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -n default -- curl "http://httpbin.default:8000/headers" -H "x-ext-authz: allow" -s期待される出力:
{
"headers": {
"Accept": "*/*",
"Host": "httpbin.default:8000",
"User-Agent": "curl/8.5.0",
"X-Envoy-Attempt-Count": "1",
"X-Ext-Authz": "allow",
"X-Ext-Authz-Check-Result": "allowed",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=c3e5364e87add0f4f69e6b0d029f5961b404c8f209bf9004b3d21a82cf67****;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep"
}
}X-Ext-Authz-Check-Result: allowed ヘッダーは、権限付与サービスがリクエストを承認したことを確認します。応答には、クライアント (sleep) とサーバー (httpbin) の両方の SPIFFE ID も含まれており、サービス間の Mutual TLS を検証します。
これら 3 つのテストにより、以下が確認されます。
保護されていないパスへのリクエストは、権限付与チェックなしで通過します。
必要なヘッダーがない保護されたパスへのリクエストは拒否されます。
正しいヘッダーがある保護されたパスへのリクエストは承認されます。
本番環境での考慮事項
本番環境でカスタム権限付与をデプロイする際は、次の点に留意してください。
| 項目 | 推奨事項 |
|---|---|
| 障害モード | 権限付与サービスが利用できない場合にリクエストを許可するか拒否するかを決定します。リクエストを許可する (フェイルオープン) と可用性は維持されますが、セキュリティは低下します。リクエストを拒否する (フェイルクローズ) とより安全ですが、権限付与サービスが停止した場合に停止を引き起こす可能性があります。 |
| タイムアウト | 権限付与サービスのレスポンスレイテンシーに基づいてタイムアウト値を設定します。値が低すぎると誤った拒否が発生し、高すぎるとリクエストレイテンシーが増加します。 |
| 高可用性 | 権限付与サービスの複数のレプリカを実行し、適切なリソースリクエストと制限を構成します。 |
| スコープ | パフォーマンスオーバーヘッドを最小限に抑えるために、権限付与ポリシーを名前空間全体ではなく、特定のパスとワークロードに適用します。 |
| 監視 | 権限付与サービスのログとレイテンシーを監視して、トラフィックに影響を与える前に問題を検出します。 |
クリーンアップ
このチュートリアルで作成したリソースを削除します。
kubectl delete -f ext-authz.yaml
kubectl delete -f httpbin.yaml
kubectl delete -f sleep.yamlASM コンソールから権限付与ポリシーとカスタム権限付与サービス登録を削除します。
ASM コンソールで、[メッシュ セキュリティセンター] > [AuthorizationPolicy] を選択します。
test1ポリシーを削除します。[メッシュセキュリティセンター] > [カスタム権限付与サービス] を選択します。
test権限付与サービスを削除します。