動的なアクセス制御が必要な場合、Ingress ゲートウェイに Open Policy Agent (OPA) エンジンを統合することで、ユーザー ID やリクエスト内容に基づいて認可ポリシーをカスタマイズし、Service Mesh (ASM) インスタンス内のサービス間通信をリアルタイムで制御できます。これにより、不正なアクセスを効果的に防止し、データ侵害のリスクを軽減し、アプリケーションのセキュリティを強化します。このトピックでは、OPA エンジンを使用して、Ingress ゲートウェイが受信したリクエストを認証および認可する方法について説明します。この例では、リクエストが Ingress ゲートウェイを経由して httpbin アプリケーションにアクセスします。
前提条件
Kubernetes マネージドクラスターは、バージョン 1.15.3.25 以降の ASM インスタンスに追加されます。詳細については、「ASM インスタンスへのクラスターの追加」および「ASM インスタンスの更新」をご参照ください。
HTTPBin アプリケーションがデプロイされており、アクセスできます。詳細については、「HTTPBin アプリケーションのデプロイ」をご参照ください。
default ネームスペースで自動サイドカープロキシインジェクションが有効になっています。詳細については、「サイドカープロキシインジェクションポリシーの設定」をご参照ください。
ステップ 1: OPA エンジンをデプロイする
asm-opa.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。
YAML コードは、OPA サービス、OPA デプロイメント、およびシークレットをデプロイします。
種類
説明
デプロイメント
イメージ
registry-vpc.cn-hangzhou.aliyuncs.com/acs/opa:0.46.1-istio-3-static内のリージョン ID を、クラスターがデプロイされているリージョンの ID に置き換えます。デフォルトでは、OPA エンジン(
--set=decision_logs.console=true)のログ記録が有効になっています。これはデバッグに役立ちます。
シークレット
シークレットは、次の OPA ポリシーを定義します。
リクエストのパスが
healthの場合、リクエストは許可されます。リクエストのメソッドが
HEADの場合、リクエストは許可されます。リクエストのユーザー名が
aliceの場合、リクエストは許可されます。説明ユーザー名は、リクエストの
AuthorizationヘッダーにAuthorization: Basic ${user name: Base64-encoded password string}の形式で含まれています。
kubectl を使用して、kubeconfig ファイルの情報に基づいて Container Service for Kubernetes(ACK)クラスターに接続し、次のコマンドを実行して OPA をデプロイします。
kubectl apply -f asm-opa.yaml
ステップ 2: Ingress ゲートウェイの外部認可機能を使用して、OPA エンジンを Ingress ゲートウェイと統合する
ASM コンソール にログインします。左側のナビゲーションウィンドウで、 を選択します。
[メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションウィンドウで、 を選択します。
-
[Ingress Gateway] ページで、OPA と統合するゲートウェイを見つけ、[Gateway Security] をクリックします。
-
ゲートウェイの左側メニューで、 を選択します。
-
カスタム認可サービスを設定します。
-
[Custom Authorization Service Configuration] ウィザードで、OPA をゲートウェイのカスタム認可サービスとして設定し、[Next] をクリックします。
Enable Gateway Custom Authorization Service スイッチをオンにし、Custom authorization service based on envoy.ext_authz (HTTP or gRPC) タブを選択し、Protocol を GRPC、service address を
asm-opa.default.svc.cluster.local、service port を 9191、timeout を 10 秒に設定します。 -
[Matching Rules] ウィザードで、OPA 認可が必要なリクエストを指定するマッチングルールを設定し、[Submit] をクリックします。
Matching Mode を Selected requests must be authorized に設定し、Custom matching rules を選択し、HTTP Path (Path) をオンにして、
/status/*を入力します。「Gateway Custom Authorization Service was created successfully」というメッセージが表示され、作成された Istio ネイティブリソースが一覧表示されます。ASMExtensionProvider (リソース名:
grpcextauth-asmsecuritypolicy-ingressgateway-extauthz) と AuthorizationPolicy (リソース名:ingressgateway-extauthz-ap-wg-gateway-istio-system-gateway-ingressgateway) です。View YAML をクリックしてリソース設定を表示するか、Edit をクリックして認可サービスを変更できます。
-
ステップ 3:HTTPBin アプリケーションへのアクセスをテストする
次のコマンドを実行して、
/パスにアクセスします。curl ${IP address of the ASM gateway}/ -I -X GET予期される出力:
HTTP/1.1 200 OK server: istio-envoy date: Tue, 25 Jul 2023 08:30:58 GMT content-type: text/html; charset=utf-8 content-length: 9593 access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 2出力は、パスへのアクセスリクエストに認証が不要であることを示しています。
有効なパラメーターなしで次のコマンドを実行して、
/status/201パスにアクセスします。curl ${IP address of the ASM gateway}/status/201 -I -X GET予期される出力:
HTTP/1.1 403 Forbidden date: Tue, 25 Jul 2023 08:31:18 GMT server: istio-envoy content-length: 0 x-envoy-upstream-service-time: 1出力は、有効なパラメーターのないアクセスリクエストが拒否されたことを示しています。
有効なパラメーターを使用して次のコマンドを実行して、
/status/201パスにアクセスします。curl ${IP address of the ASM gateway}/status/201 -I -X GET --user alice:testpassword予期される出力:
HTTP/1.1 201 Created server: istio-envoy date: Tue, 25 Jul 2023 08:31:38 GMT content-type: text/html; charset=utf-8 access-control-allow-origin: * access-control-allow-credentials: true content-length: 0 x-envoy-upstream-service-time: 3出力は、有効なパラメーターを含むアクセスリクエストが許可されたことを示しています。
ステップ 4:OPA ポリシーを更新する
OPA エンジンの HTTP API を呼び出して、OPA ポリシーを更新します。
次のコマンドを実行して、bob という名前のユーザーのみが HTTP 経由で HTTPBin アプリケーションにアクセスできるようにし、alice という名前のユーザーが HTTP 経由で HTTPBin アプリケーションにアクセスできないようにします。
kubectl exec deployment/httpbin -c istio-proxy -- curl asm-opa:8181/v1/policies/policy/policy.rego -XPUT --data-binary 'package asm.authz import future.keywords import input.attributes.request.http as http_request import input.parsed_path default allow := false allow if { parsed_path[0] == "health" } allow if { http_request.method == "HEAD" } allow if { user_name == "bob" // ユーザー bob のみを許可します } user_name := parsed if { [_, encoded] := split(http_request.headers.authorization, " ") [parsed, _] := split(base64url.decode(encoded), ":") }'bob という名前のユーザーを使用して、次のコマンドを実行して HTTPBin アプリケーションにアクセスします。
curl ${IP address of the ASM gateway}/status/201 -I -X GET --user bob:testpassword予期される出力:
HTTP/1.1 201 Created server: istio-envoy date: Tue, 25 Jul 2023 08:32:16 GMT content-type: text/html; charset=utf-8 access-control-allow-origin: * access-control-allow-credentials: true content-length: 0 x-envoy-upstream-service-time: 3出力は、ユーザー bob のアクセスが成功したことを示しています。
alice という名前のユーザーを使用して、次のコマンドを実行して HTTPBin アプリケーションにアクセスします。
curl ${IP address of the ASM gateway}/status/201 -I -X GET --user alice:testpassword予期される出力:
HTTP/1.1 403 Forbidden date: Tue, 25 Jul 2023 08:32:49 GMT server: istio-envoy content-length: 0 x-envoy-upstream-service-time: 1出力は、ユーザー alice のアクセスが禁止されていることを示しています。