認可ポリシーの概要
1 か所で実行できるモノリシック アプリケーションとは異なり、グローバルに分散されたマイクロサービス アプリはネットワーク境界を越えて呼び出しを行います。このため、アプリケーションのエントリ ポイントが増え、悪意のある攻撃を受ける可能性が高くなります。また、Kubernetes Pod には一時的な IP が割り振られるため、従来の IP ベースのファイアウォール ルールでは、ワークロード間のアクセスを十分に保護することはできません。マイクロサービス アーキテクチャでは、セキュリティに対する新しいアプローチが必要です。Kubernetes サービス アカウントや Istio セキュリティ ポリシーなどのセキュリティ機能を搭載している Cloud Service Mesh は、アプリケーションの保護に役立つ優れた機能を提供します。
このページでは、アプリケーション オペレーターに向けた AuthorizationPolicy
カスタム リソース(CR)の概要を説明します。認可ポリシーを使用すると、アプリケーション(L7)レイヤおよびトランスポート(L3 / 4)レイヤのワークロードに対するアクセス制御を有効にできます。認可ポリシーを構成して、サービスまたはユーザーが行える内容についての権限を指定します。
認可ポリシー
デフォルトでは、メッシュ内のサービス間(エンドユーザーとサービス間)のリクエストは許可されます。AuthorizationPolicy
CR を使用して、ワークロードにきめ細かいポリシーを定義します。認可ポリシーを適用すると、Cloud Service Mesh はこれらのポリシーをサイドカー プロキシに配布します。ワークロードがリクエストを受信すると、サイドカー プロキシは認可ポリシーをチェックし、リクエストを許可するかどうかを決定します。
プラットフォームでサポートされている AuthorizationPolicy
CR のフィールドの詳細については、サポートされている機能をご覧ください。
ポリシーの範囲
ポリシーは、サービス メッシュ全体、名前空間、または個々のワークロードに適用できます。
メッシュ全体のポリシーを適用するには、
metadata:namespace
フィールドでルート名前空間istio-system
を指定します。apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "mesh-wide" namespace: istio-system spec: ...
名前空間にポリシーを適用するには、
metadata:namespace
フィールドに名前空間を指定します。apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "currencyservice" namespace: currencyservice spec: ...
ポリシーを特定のワークロードに制限するには、
selector
フィールドを追加します。apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "frontend" namespace: demo spec: selector: matchLabels: app: frontend ...
基本構造
認可ポリシーには、ポリシーの範囲、action
、rules
のリストが含まれます。
前のセクションで説明したように、ポリシーの範囲は、メッシュ全体、名前空間、または特定のワークロードにすることが可能です。ポリシーの範囲を追加する場合は、
selector
フィールドにポリシーの対象を指定します。action
フィールドは、リクエストに対してALLOW
またはDENY
のどちらを使用するかを指定します。アクションを指定しない場合、アクションはデフォルトでALLOW
に設定されます。わかりやすくするため、アクションは常に指定することをおすすめします(認可ポリシーではAUDIT
アクションとCUSTOM
アクションを使用できます)。AUDIT
アクションは一部のプラットフォームでのみサポートされています(詳しくは、サポートされている機能をご覧ください)。rules
で、アクションをトリガーするタイミングを指定します。
下記の例で、
このポリシーは、
demo
名前空間内のfrontend
サービスに対するリクエストに適用されています。リクエスト ヘッダーに「hello:world」が含まれている場合、リクエストは許可されますが、含まれていない場合は拒否されます。
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "hello-world"
namespace: demo
spec:
selector:
matchLabels:
app: frontend
action: ALLOW
rules:
- when:
- key: request.headers[hello]
values: ["world"]
リクエスト オペレーションのアクセス制御
HTTP メソッドや TCP ポートなどの特定のリクエスト オペレーションへのアクセスを制御するには、rules
の下に to
セクションを追加します。次の例では、GET
と POST
の HTTP メソッドにのみ、demo
名前空間の currencyservice
が許可されています
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: currencyservice
namespace: demo
spec:
selector:
matchLabels:
app: currencyservice
action: ALLOW
rules:
- to:
- operation:
methods: ["GET", "POST"]
認証済み ID のアクセス制御
前の例では、ポリシーは未認証のワークロードからのリクエストを許可しています。STRICT
相互 TLS(mTLS)を有効にしている場合は、source
セクションのリクエスト元であるワークロードまたは Namespace の ID に基づいてアクセスを制限できます。
ワークロード レベルでアクセスを制御するには、
principals
フィールドまたはnotPrincipal
フィールドを使用します。名前空間レベルでアクセスを制御するには、
namespaces
フィールドまたはnotNamespaces
フィールドを使用します。
前述のすべてのフィールドで STRICT
mTLS を有効にする必要があります。STRICT
mTLS を設定できない場合は、平文リクエストを拒否で代わり解決策をご確認ください。
特定のワークロード
次の例では、frontend
サービスから currencyservice
へのリクエストのみが許可されます。他のワークロードから currencyservice
へのリクエストは拒否されます。
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "currencyservice"
namespace: demo
spec:
selector:
matchLabels:
app: currencyservice
action: ALLOW
rules:
- from:
- source:
principals: ["example-project-1234.svc.id.goog/ns/demo/sa/frontend-sa"]
サービス アカウントを指定するには、principals
を次の形式にする必要があります。
principals: ["PROJECT_ID.svc.id.goog/ns/NAMESPACE/sa/SERVICE_ACCOUNT_NAME"]
Citadel CA でクラスタ内 Cloud Service Mesh を使用している場合、cluster.local
は信頼できるドメインです。それ以外の場合、PROJECT_ID.svc.id.goog
はメッシュの信頼できるドメインです。
信頼ドメインはシステムのルート オブ トラストに対応し、ワークロード ID の一部です。Cloud Service Mesh は、信頼ドメインを使用してメッシュ内のすべての ID を作成します。たとえば、SPIFFE ID spiffe://mytrustdomain.com/ns/default/sa/myname
では、部分文字列 mytrustdomain.com
は、ワークロードが mytrustdomain.com
という信頼ドメインからのものであることを指定します。
Cloud Service Mesh 認証局を使用すると、信頼ドメインは Cloud Service Mesh によって自動的に生成されます。これは、クラスタのワークロード プールに基づいています。
クラスタが同じルート オブ トラストを共有している限り、マルチクラスタ メッシュ内に 1 つ以上の信頼ドメインを含めることができます。
特定の Namespace
次の例は、ソースが foo
名前空間でない場合に、リクエストを拒否するポリシーを示しています。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: httpbin-deny
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
version: v1
action: DENY
rules:
- from:
- source:
notNamespaces: ["foo"]
値の一致
認可ポリシーのほとんどのフィールドでは、次の一致スキーマがすべてサポートされています。
- 完全一致: 文字列の正確な一致。
- ワイルドカード文字
"*"
を使用したワイルドカードの一致。- 接頭辞の一致:
"*"
で終わる文字列。たとえば、"test.example.*"
は"test.example.com"
または"test.example.com.cn"
と一致します。 - 接尾辞の一致:
"*"
で始まる文字列。たとえば、"*.example.com"
は"eng.example.com"
または"test.eng.example.com"
と一致します。
- 接頭辞の一致:
- プレゼンスの一致: フィールドが存在し、空ではないことが必要であることを指定するには、
fieldname: ["*"]
形式を使用します。これは、フィールドを指定しないままにすることとは異なります。つまり、空の値を含むすべてのフィールドと一致します。
ただし、次のような例外があります。たとえば、次のフィールドでは完全一致のみがサポートされています。
when
セクションのkey
フィールドsource
セクションのipBlocks
to
セクションのports
フィールド
次のポリシーの例では、/test/*
接頭辞または */info
接尾辞を使用したパスでアクセスが許可されています。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: tester
namespace: default
spec:
selector:
matchLabels:
app: products
action: ALLOW
rules:
- to:
- operation:
paths: ["/test/*", "*/info"]
除外の一致
when
フィールドの notValues
、source
フィールドの notIpBlocks
、to
フィールドの notPorts
のような否定条件との一致のため、Cloud Service Mesh では除外の一致をサポートしています。次の例では、リクエストパスが /healthz
でない場合、JWT 認証から派生した有効なリクエスト principals
が必要になります。このポリシーでは /healthz
パスへのリクエストが JWT 認証から除外されます。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: disable-jwt-for-healthz
namespace: default
spec:
selector:
matchLabels:
app: products
action: ALLOW
rules:
- to:
- operation:
notPaths: ["/healthz"]
from:
- source:
requestPrincipals: ["*"]
平文のリクエストを拒否する
Cloud Service Mesh では、自動 mTLS がデフォルトで有効になっています。自動 mTLS の場合、クライアント サイドカー プロキシがサーバーにサイドカーがあるかどうかを自動的に検出します。クライアント サイドカーは、サイドカーを含むワークロードには mTLS を送信し、サイドカーを含まないワークロードには平文を送信します。最適なセキュリティのために、STRICT mTLS を有効にすることをおすすめします。
ワークロードまたは名前空間に対して STRICT
モードの mTLS を有効にできない場合は、次の操作を行います。
namespaces
またはprincipals
が空ではないトラフィックを明示的に許可する認可ポリシーを作成する。またはnamespaces
またはprincipals
が空であるトラフィックを明示的に拒否する認可ポリシーを作成する。
namespaces
と principals
は mTLS リクエストでのみ抽出できるため、これらのポリシーは平文のトラフィックを効果的に拒否します。
次のポリシーは、リクエスト内のプリンシパルが空の場合(平文のリクエストの場合)にリクエストを拒否します。プリンシパルが空でない場合は、ポリシーはリクエストを許可します。["*"]
は空でないことを意味します。notPrincipals
で使用する場合は、空のプリンシパルでの一致を意味します。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: require-mtls
namespace: NAMESPACE
spec:
action: DENY
rules:
- from:
- source:
notPrincipals: ["*"]
認可ポリシーの優先順位
ALLOW
と DENY
の認可ポリシーを個別に構成することもできますが、ポリシーが希望どおりに動作するように、ポリシーの優先順位とデフォルトの動作を理解しておく必要があります。次の図は、ポリシーの優先順位を示しています。
以降のセクションのポリシーの例では、デフォルトの動作の一部とそのポリシーが役立つ状況について説明します。
すべて許可しない
次の例は、何も一致しない ALLOW
ポリシーを示しています。デフォルトでは、他の ALLOW
ポリシーが存在しない場合、リクエストは常に拒否されます。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
spec:
action: ALLOW
最初は何も許可しないポリシーを適用し、段階的に ALLOW
ポリシーを追加して、ワークロードへのアクセスを増やすことは、良いセキュリティ対策です。
すべてのアクセスを拒否する
次の例は、すべてに一致する DENY
ポリシーを示しています。DENY
ポリシーは ALLOW
ポリシーよりも先に評価されるため、リクエストに一致する ALLOW
ポリシーがある場合でも、すべてのリクエストが拒否されます。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
spec:
action: DENY
rules:
- {}
すべてを拒否するポリシーは、ワークロードへのすべてのアクセスを一時的に無効にする場合に便利です。
すべてのアクセスを許可する
次の例は、すべてに一致し、ワークロードに対する完全アクセス権を許可する ALLOW
ポリシーを示しています。すべてを許可するポリシーは、常にリクエストを許可するため、他の ALLOW
ポリシーが無効になります。
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all
spec:
action: ALLOW
rules:
- {}
すべてを許可するポリシーは、ワークロードへの完全アクセス権を一時的に公開したい場合に便利です。DENY
ポリシーがある場合、DENY
ポリシーが ALLOW
ポリシーの前に評価されるため、リクエストは拒否される可能性があります。
ベスト プラクティス
サービスごとに Kubernetes サービス アカウントを作成し、Deployment でサービス アカウントを指定します。例:
apiVersion: v1 kind: ServiceAccount metadata: name: frontend-sa namespace: demo --- apiVersion: apps/v1 kind: Deployment metadata: name: frontend namespace:demo spec: selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: serviceAccountName: frontend-sa ...
すべて許可しないポリシーから始めて、
ALLOW
ポリシーを段階的に追加し、ワークロードへのアクセスを増やします。サービスで JWT を使用する場合:
認可されていないリクエストをブロックする
DENY
ポリシーを作成します。次に例を示します。apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: requireJWT namespace: admin spec: action: DENY rules: - from: - source: notRequestPrincipals: ["*"]
すべて許可しないポリシーを適用します。
ワークロードごとに
ALLOW
ポリシーを定義します。例については、JWT トークンをご覧ください。
次のステップ
Cloud Service Mesh のセキュリティ機能について学習します。
- Cloud Service Mesh のユーザー認証の構成
- サービスの監査ポリシーの構成
- トランスポートのセキュリティの構成
- Identity-Aware Proxy と Cloud Service Mesh の統合
- GKE クラスタで Cloud Service Mesh の Egress ゲートウェイを使用するためのベスト プラクティス
Istio ドキュメントの認可ポリシーの詳細については、以下をご覧ください。