19
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Istio での Authorization Policy を利用したワークロードのアクセス制御

Last updated at Posted at 2020-07-17

はじめに

この記事では Istio からワークロードのアクセス制御を行うための機能として提供されている Authorization Policy の仕組みや使い方を紹介していきます。

ここでいうアクセス制御というのはリクエスト元のワークロードのアクセス権限を確認した上でリクエストを 許可/拒否 する認可処理のことを指しています。

Istio における認可モデルの変遷

Istio 1.4 からアクセス制御を行うための認可モデルが Alpha 版として提供されていた RBAC Policy から、Beta 版としてシンプルさと柔軟性に重点を置いた Authorization Policy に変更されました。1

改善点としては RBAC Policy では ClusterRbacConfig, ServiceRole, ServiceRoleBinding というカスタムリソースを定義する必要があったのが、Authorization Policy では AuthorizationPolicy というカスタムリソースを定義するだけで済むようになり管理方法がシンプルになったことや、Ingress/Egress Gateway に対してポリシーが適用できるようになったことで Service Mesh 内だけではなく Service Mesh に出入りするトラフィックに対してもアクセス制御を行えるようになったことなどが挙げられています。2

なお、最新バージョン Istio 1.6 では istio/istio#22060 で RBAC Policy を廃止する作業が進められているため、RBAC Policy を利用していたユーザーが 1.6 にバージョンアップする際には Istio Blog で公開されている Introducing the Istio v1beta1 Authorization Policy を参考にして Authorization Policy への移行を行う必要があります。

Authorization Policy の仕組み

先述の通り Authorization Policy では AuthorizationPolicy リソースでポリシーを定義することでワークロードのアクセス制御を行うことができます。また、アクセス制御のスコープを Service Mesh 全体、特定 Namespace、特定 Workload など設定によって柔軟に定義することが可能です。

アーキテクチャとしては Control Plane である istiod が AuthorizationPolicy リソースで定義されたポリシーを Envoy の RBAC Filter の設定に変換3 して LDS 経由で Data Plane である istio-proxy(Envoy)に反映する仕組みとなっており、ポリシーのチェックは istio-proxy 内部で実行されるためパフォーマンスへの影響もありません。

スクリーンショット 2020-07-15 16.22.19.png

引用: https://istio.io/latest/docs/concepts/security/#authorization-architecture

AuthorizationPolicy リソースについて

以下は AuthorizationPolicy リソースの Spec についての説明を記載した図となります。
スクリーンショット 2020-07-16 17.19.17.png
上記のポリシーは ec-system ネームスペース内で app: backend というラベルを持つワークロード(Pod)に対して、cluster.local/ns/ec-system/sa/web という Workload Identity4 を持つワークロードから、8080 ポートの /data エンドポイントを GET するリクエストを ALLOW(許可) するものとなります。

基本的にポリシーは同じネームスペース内のワークロードに対して適用されますが、以下のように Istio の Root Namespace にポリシーを作成することで全てのネームスペース内のワークロードに対してポリシーを適用することができます。Root NamespaceMeshConfig で設定可能となっていて、デフォルトでは istio-system が使用されます。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: all-ns-policy
  namespace: istio-system
spec:
  ...

action について

Authorization Policy ではリクエストを許可する(ALLOW)ポリシーとリクエストを拒否する(DENY)ポリシーがサポートされており、どちらのポリシーにするかを action で指定する仕様になっています。

# リクエストを許可するポリシー
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-policy
  namespace: foo
spec:
  action: ALLOW
  selector:
  ...
  rules:
  ...

# リクエストを拒否するポリシー
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-policy
  namespace: foo
spec:
  action: DENY
  selector:
  ...
  rules:
  ...

ワークロードに両方のポリシーにマッチした場合には DENY ポリシーが先に評価される仕様なので注意してください。また、action のデフォルト値は ALLOW のため未定義の場合には ALLOW ポリシーとなりますが、わかりやすさの観点で明示的に定義することが推奨されています。

selector について

selector はポリシーを適用するワークロード(Pod)をラベルベースで指定するもので Gateway, Sidecar, EnvoyFilter の selector と同様の仕組みが利用されています。以下は foo ネームスペース内の app: bar というラベルを持つワークロードに適用されるポリシーの例となります。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: bar-policy
  namespace: foo
spec:
  action: ALLOW
  selector:
    matchLabels:
      app: bar
  rules:
  ...

selector を定義することでワークロードを指定できますが、以下のように selector が未定義の場合には同じネームスペース内の全てのワークロードにポリシーが適用される仕様です。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: foo-ns-policy
  namespace: foo
spec:
  action: ALLOW
  rules:
  ...

rules について

rules では from でリクエスト元を指定、to でリクエスト内容を指定、when でその他の条件を指定してポリシーのルールを定義することで、ルールにマッチしたリクエストに対して action で指定した判定を適用することができます。更に from, to, when の文字列型のフィールドではワイルドカード(*) を利用したマッチもサポートされています。5

以下は cluster.local/ns/foo/sa/hoge という Workload Identity4 を持つワークロードから 8080 ポートを GET するリクエストに対してのルールを定義したポリシーとなります。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: bar-policy
  namespace: foo
spec:
  action: ALLOW
  selector:
    matchLabels:
      app: bar
  rules:
  - from:
    - source:
      principals: ["cluster.local/ns/foo/sa/hoge"]
    to:
    - operation:
      methods: ["GET"]
    when:
    - key: destination.port
      values: ["8080"]

from について

from では以下のような値を元にリクエスト元を指定することができます。6

  • Principal(X.509 証明書に含まれる SPIFFE ID)
  • JWT の iss と sub
  • Namespace
  • IP や CIDR

to について

to では以下のような値を元にリクエスト内容を指定することができます。

  • ホスト名
  • ポート
  • HTTP メソッド
  • URL パス

when について

when で以下のような値をその他の条件として指定することができます。6

  • HTTP リクエストヘッダー
  • Principal(X.509 証明書に含まれる SPIFFE ID)
  • JWT クレーム
  • Namespace
  • IP や CIDR

fromto で指定可能な値と重複しているフィールドが多く存在しているので、ルールをわかりやすくするためにも when でしか指定できない条件のみを定義するのが良いかもしれません。

チュートリアル

Istio 1.6.5 をインストールした Kuberntes クラスタを作成します。

kind create cluster --name istio-dev --image kindest/node:v1.18.0
istioctl manifest apply --set profile=demo

セットアップが完了したかどうかを確認します。

$ istioctl version
client version: 1.6.5
control plane version: 1.6.5
data plane version: 1.6.5 (3 proxies)

サンプルアプリとして Bookinfo をデプロイします。

kubectl create ns bookinfo
kubectl label namespace bookinfo istio-injection=enabled
kubectl apply -n bookinfo -f https://raw.githubusercontent.com/istio/istio/1.6.5/samples/bookinfo/platform/kube/bookinfo.yaml

あとは Authorization for HTTP traffic を実施するだけです。チュートリアルの中で AuthorizationPolicy リソースの Spec を変更してみたり、ポリシーの適用後に Envoy に設定された RBAC Filter を Admin Interface から参照してみたりすると理解が深まるかもしれません。

さいごに

今回は Istio からワークロードのアクセス制御を行うための機能として提供されている Authorization Policy の仕組みや使い方を紹介しました。認可モデルの変遷でも言及したとおり、以前の RBAC Policy と比べて Authorization Policy はシンプルで使いやすいモデルになっています。

TCP トラフィックに対するアクセス制御、HTTP トラフィックに対するアクセス制御、Ingress Gateway 上でのアクセス制御など、各ユースケースに応じた Authorization Policy の利用方法が 公式ドキュメント で提供されているので、導入を検討している方はそちらを参考に作業を進めていくのが良いかと思います。

Authorization Policy がこのまま GA になるのか、servicemeshinterface/smi-adapter-istio を利用して SMI ベースでアクセス制御を行うのが推奨されていくのか、など気になることもあるので、引き続き Istio の Workload Identity とアクセス制御周りの動向に注目していきたいと思います。

参考資料

  1. Authorization policy model in beta - Announcing Istio 1.4

  2. Authorization Policy での改善点とデザインゴールで Istio Configuration Model について言及されていたが肝心の ドキュメント は非公開となっているのでこちらでは割愛。

  3. Istio 1.6 で RBAC Filter を生成しているソースコードは こちら

  4. Istio では SPIFFE がサポートされており mTLS が有効になっていると全てのワークロードに Workload Identity となる SPIFFE ID(spiffe://<Trust Domain>/ns/<Namespace>/sa/<Service Account>)が SAN URI にセットされた X.509 証明書が配布される。Istio では SPIFFE ID をワークロードの Namespace と Service Account から構成するため、foo という Namespace に bar という Service Account を使用してデプロイされた Pod には spiffe://cluster.local/ns/foo/sa/bar という SPIFFE ID を含む X.509 証明書が配布される仕様となっている。 2

  5. マッチ方法として Exact, Prefix, Suffix, Presence がサポートされている。詳細は こちら を参照

  6. 指定可能なフィールドの中には Principal や Namespace など mTLS 有効化が必須なものがあります。Security の観点から mTLS による相互認証とワークロード間の通信の暗号化はとても重要なので、それらのフィールドを使わない要件だったとしても基本的には mTLS を有効化した上でアクセス制御を行うのが良いかと思います。 2

19
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?