認証と認可は、クラウドアーキテクトやDevOpsエンジニアによって解決されなければならない安全性のパズルの大きな部分です。このブログでは、特定のアクションが認証されたエンティティがIstioサービスメッシュで行うことができることについて、認可/アクセスコントロールを実現する方法を詳細に見ていきます。これにより、悪意のある行動を防ぐことでインフラの保護が可能です。
サービスメッシュ内の認可は、OPAポリシーを使用して定義できます。OPAは、Kubernetesのワークロードに対する認可ポリシーを定義し、適用するための機構です。この記事では、以下の点について見ます。
- OPAとは
- OPAをIstioサービスメッシュと統合する理由
- IstioとOPAがリクエストを認可する方法
- OPAをIstioに統合するための詳細な手順
OPAとは?
OPAは「Open Policy Agent」の略で、開源の一般用途のポリシー適用エンジンです。DevOps担当者は、Regoと呼ばれる高階の宣言型言語を使用してポリシーをコードとして定義することができます。OPAは、開発者がアプリケーションコードに認可ポリシーを書く必要をなくして、一貫したスタック上でポリシーを中央に定義し、適用することができます。OPAの動作方法は以下の通りです(図1をご参照ください)
- アプリケーション/サービスがリクエストを受け取ります。
- サービスはJSON形式の認可リクエストをOPAに送信します。
- OPAは定義された認可ポリシーに基づいてリクエストを確認します。
- OPAは決定を取り、JSON形式の認可応答(ALLOW/DENY)をサービスに返します。
図1:OPAを使用した認可要求の流れ
開発者が作成したアプリケーションが認可要求を送信する必要はないことに注意してください:それはArgo CD、Kubernetes Gateway APIリソース、Terraform、Prometheus、または他の何かであります。なぜなら、OPAは一般用途であるからです。(ここでは、Kubernetesクラスタ内のアプリケーションを提及し、描画していますが、便利さとより良い理解のためにだけです。)
IstioとOPAを統合する理由
Istioには健全な認可机制があります。しかし、Istioサービスメッシュと並行してデジタルなポリシー実行エンジンであるOPAを取り入れることには独自の利点があります:
- ポリシーの定義と適用を中央管理するシステム:OPAを使用すると、DevOpsが整个のスタックの認可ポリシーを中央管理することがより簡単になります。これには、マッシュされたワークロード、マッシュされていないスタック、および認可チェック(金曜日にデプロイを防ぐポリシーなど)も含まれます。
- ポリシーの定義によりフレキシブルで粒度を细かく:以下の表(図2)を見ると、Istio認可が多くのことを行い、異なるデータ源からの variety of fields に基づいて要求にマッチすることが明らかです。しかし、Istio AuthorizationPolicy CRDは、HTTP要求本文やコンテキストual data のフィールドの設定に限られています。これにOPAを使用できます。Istioとは異なり、OPAはポリシー評価に任何のデータを使用できます。
- AuthZ設定の簡略化:DevOpsがIstioで複雑な認可ルールを設定するのは時間がかかるかもしれません。OPAはRegoを使用して構成され、プログラミング言語に近いものです。Regoを使用することで、基本的から複雑なポリシールールの設定が比較的簡単になります。
図2:IstioとOPA認証の比較表(出典)
IstioとOPAがリクエストを認証する方法
DevOpsは、OPAを完全に独立したサービスとしてデプロイするか、Envoyプロキシーやアプリケーションコンテナと一緒にPod内のサイドカーコンテナとしてデプロイすることができます。サイドカーコンテナアプローチは、遅延を低減するのに最適です。
OPAのサイドカーコンテナは、IstioのEnvoyプロキシーサイドカーコンテナと同様に、アプリケーションPodに注入する必要があります。注入されたOPAコンテナにConfigMapsをマウントすることができます。これには認証ルールが含まれています。名前空間内のすべてのOPAサイドカーコンテナは、ConfigMapで定義された同じ設定とAuthZルールをマウントします。
OPAサイドカーが注入されると、Envoyプロキシーはサービスがリクエストを受信したときにOPAに認証リクエストを送信し、認証判断を行います:
図3:Istio-OPA認証ワークフロー
DevOpsの人々が同じ名前空間内のすべての注入されたOPAコンテナが同じ設定に従い、異なるルールを強制したくない場合、以下のいずれかを行う必要があります:
- 現在の注入ポリシーが特定のConfigMapを使用することを許すハードコーディングを削除する
- 変更Webhookを設定し、Podレベルでサイドカー注入を無効にする
- リモートHTTPサーバからポリシーバンドルを提供
- アプリケーションとサイドカーを異なる名前スペースに配置し、異なるConfigMapを使用する
OpaをIstioと統合するための手順: デモ
ここでの考え方は、Envoyプロキシサイドカーの代わりにOPAを外部の認可者にすることで、アクセス制御決定を行うことです。
デモでは、IstioのドキュメントからのBookinfoアプリケーションを使用します。OPAをIstioと一緒に構成してアクセス制御を行い、bookinfo/productpageに対してリクエストを送信して实施了しているかどうか確認します:
図4: Istio-OPA統合の教材図
注意してください、/productpageはUIであり、内部で他のサービスに内部呼び出しを行います。例えば、レビューや評価サービスなど(diagram)。私はbookinfo
名前スペース内のすべてのポッドにOPAを注入します。すべてのOPAコンテナは同じConfigMapをマウントし、そのために同じ認可ポリシーがあります。Bookinfo
アプリケーションのデフォルトの動作では、HTTP認証をすることはありません。したがって、内部の呼び出しは認証されず、認可されないでしょう。
次の手順に従って行います:
- OPAサイドカーの注入構成
- IstioプロxyとOPA間の通信を有効にしてください
- OPA構成をデプロイしてください
- Istio構成を適用してください
- アプリケーションをデプロイし、Istio-OPA認可設定をテストしてください
デモの前提条件は、クラスターにIstio v1.19+がインストールされていることです。ここではIstio v1.21.0を使用しています。
OPAはquickstart.yamlを提供して、簡単なインストールを提供しています。YAMLを3つに分割し、より簡単に理解するためにIMESH GitHub repoを使用しています。
ステップ1: OPAサイドカーの注入設定
opa_controller.yamlを適用してください:
kubectl apply -f opa_controller.yaml
opa_controller.yaml
は、TLS証明書、注入ポリシーを含むConfigMap、アドミッションコントローラーデプロイメント、変更するWebhook設定を全てopa-istio
名前空間にデプロイします(図5を参照してください):
- 変更するWebhookコントローラー(
opa-istio-admission-controller
)は、特定のラベル(opa-istio-injection
)に値を設定して有効にするのを待ちます。 - webhookコントローラーは、注入ポリシーを持つ
admission-controller
を呼び出します。 - 注入ポリシーは、
admission-controller
がPodにOPAサイドカートンを注入する方法を示します。
図5: OPAサイドカートン注入設定
今、Bookinfoアプリケーションをデプロイする前に、bookinfo
名前空間を作成し、以下の手順を従ってください。
bookinfo
名前空間をbookinfo-ns.yamlを適用して作成します。
kubectl apply -f bookinfo-ns.yaml
opa-istio-injection: enabled
, to auto-inject OPA sidecars.
手順2: IstioプロキシとOPA間の通信を有効にする
`istio-system`名前空間内のIstio ConfigMapを編集し、extensionProviders
(opa-ext-authz-grpc
)を追加して、メッシュ内で外部認証を有効にします。
- `opa_controller.yaml`のコメントから
extensionProviders
をコピーします。 - Istio ConfigMapを編集し、メッシュフィールドに
extensionProviders
を追加します。 - 缩進を正しくしてください。
- 設定を保存してください。
この手順は、istio-proxy
が認証要求についてPod内のopa-istio
コンテナと通信することができるようにします。
`extensionProviders`を見ると、EnvoyのExtAuthzGrpc
フィルタータイプが指定されたサービスエントリとポートであることがわかります。
...
extensionProviders:
- name: opa-ext-authz-grpc
envoyExtAuthzGrpc:
service: opa-ext-authz-grpc.local
port: "9191"
...
extensionProviders
の名前、サービスアドレス、およびポートは、opa_authz.yamlおよびopa_config.yamlの中で同じでなければならない。
ステップ3: OPA構成のデプロイ
opa_config.yamlは、オープンポリシーに関連した構成を定義しています。これには、opa-istio-config
とopa-policy ConfigMaps
が含まれています。これらは、envoy_ext_authz_grpc
のgRPCサービス実装を定義し、実際の認可ポリシーを定義することができます。
認可ポリシーは2つの部分に分けられます。第1部分は、認可が承认または拒否される条件を定義します。第2部分は、ユーザーのロールと各ロールに割り当てられる権限を定義します。
認可ポリシーには、Regoはここで许多なキーワードを使用していませんので、一度慣れるには時間がかかるかもしれません。Regoの新しいバージョンを有効にして、キーワード(例えば条件キーワードのallow if)を取得することができます。
bookinfo
名前空間にOPA構成を適用してください。これはアプリケーションとともに行われます。
kubectl apply -f opa_config.yaml -n bookinfo
ステップ4: Istio構成の適用
opa_authz.yamlファイルはIstioの設定を含んでいます。それにはAuthorizationPolicy
とServiceEntry
が含まれています。AuthorizationPolicy
の提供者がopa-ext-authz-grpc
であることに注意してください。これは第2步驟でConfigMapに設定したextensionProvider
です。
同様に、ServiceEntry
で定義されたホスト名はextensionProvider
に指定されたサービスアドレスと同じである(opa-ext-authz-grpc.local
)。gRPCサービスはlocalhost 127.0.0.1のポート9191で运行し、ServiceEntry
によりistio-proxy
コンテナによってopa-istio
サイドカーにアクセス可能になっています。
設定をデプロイします。
kubectl apply -f opa_authz.yaml -n bookinfo
ステップ5: アプリケーションをデプロイし、Istio-OPA認可設定をテストします。
Bookinfoアプリケーションとゲートウェイをデプロイします。
kubectl apply -f /your_Istio_directory/samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo
kubectl apply -f /your_Istio_directory/samples/bookinfo/networking/bookinfo-gateway.yaml -n bookinfo
bookinfo
名前空間のポッドを確認します。
kubectl get pods -n bookinfo
各ポッドに3つのコンテナが運行していることがわかります:アプリケーション、Envoyプロキシ(istio-proxy
)、OPA(opa-istio
)コンテナ。
IstioゲートウェイのIPを取得してサービスにアクセスするためにします。
kubectl get svc -n istio-system

今は設定完了で、認可ポリシーをテストする準備が整いました。opa_config.yamlで定義したポリシーは以下の通りです:
...
user_roles = {
"alice": ["guest"],
"bob": ["admin"]
}
role_perms = {
"guest": [
{"method": "GET", "path": "/productpage"},
],
"admin": [
{"method": "GET", "path": "/productpage"},
{"method": "GET", "path": "/api/v1/products"},
],
...
アリスはゲストユーザーで、/productpage
にのみアクセスすることができます。ボブは管理者で、/productpage
と/api/v1/products
のパスにアクセスすることができます。ポリシーを確認しましょう。
アリスから/api/v1/products
にのアクセスを試みます。
curl -vvv your_istio_gateway_ip/api/v1/products -u alice:password
Aliceはpathにアクセスすることができず、403 Forbidden
のレスポンスを見せています。Bobと同じパスを試してみましょう。
curl -vvv your_istio_gateway_ip/api/v1/products -u bob:password
HTTPステータス200 OK
を示し、レスポンスの末尾にページの内容が表示されています。
OPAを使用したアクセスコントロールの例のシナリオ
IstioのAuthorizationPolicy CRDを使用して、上でデモされたポリシーを実行することができます。OPAは必要ありません。しかし、Istioの認可が制限されることがあるときがあります。最初の表にあるように言っています。簡単な例をあげましょう。
BookReviewsアプリケーションがあり、それはGraphQLサービスであり、レビュー担当者がレビューを提出し、エディターがそれらを編集し発行者によって発行し、ユーザーが発行されたレビューを読むことができます。
レビュー担当者がサービスに本书レビューを追加するとき、そのリクエストにはレビュー担当者のJWTが含まれています。これにはレビュー担当者が属しているグループと役割(レビュー担当者やエディター)が含まれています。リクエストボディには新たに作成されたレビューのデータを含むGraphQL変更クエリも含まれています。
以下の条件を満たすことをしたいときがあるかもしれません。
- レビュー担当者のみがレビューを提出できる。
- エディターは同じグループに属しているレビュー担当者が書かれたレビューを編集することができる。
- 発行準備ができたレビューを「発行準備完了」にすることはエディターのみができます。
以下の Diagramには上記のポリシーが含まれています:
IstioのAuthorizationPolicyは上記の条件を実行することが難しいです。理由は、IstioはGraphQLのリクエストボディを認可チェックに使用できず、これはJWTと共にポリシー評価に必要なJSONオブジェクトである缘故です。
OPAにはそのような制約はない。ポリシーの確認には任意のデータを読み込むことができ、DevOpsはRegoを使用してこれらのルールをより優れた方法で書くことができます。
動画: デモの実行
デモを実行してみたい場合は、以下の動画をご確認ください:S
Istioの統合を Enterprise Support する
ほとんどの企業は、OPAを使用してスタック全体の認可ポリシーを定義して強制する。アクセスコントロールの中央机制を持っていることで、ITチームの全体的な安全性と敏捷性を向上させます。そうでない場合、開発者は特定の言語で書かれたアプリケーションコードに認可ポリシーを開発する時間を費やし、スケーラビリティとより速いビジネスロジックのロールアウトを阻んでしまいます。
Source:
https://dzone.com/articles/5-steps-to-integrate-istio-with-opa