Contents
Istio のサービスメッシュ概念とセキュリティ層の位置付け
Istio は、マイクロサービス同士の通信を データプレーン と コントロールプレーン に分離して管理することで、アプリケーションコードに手を加えることなく高度な認証・認可機能を提供します。このセクションでは、各プレーンが担う役割と、サービスメッシュ全体で実現できる統一的なセキュリティ基盤について解説します。
データプレーンの概要
データプレーンは各 Pod にサイドカーとして注入される Envoy が中心です。Envoy はトラフィックをプロキシし、暗号化・レートリミット・ヘッダー操作などの処理をリアルタイムで実行します。
- 暗号化:相互 TLS(mTLS)により通信路を保護
- レートリミット:サービス単位でリクエスト数を制御
- アクセスログ:標準出力へ詳細なトラフィック情報を出力
コントロールプレーンの概要
コントロールプレーンは istiod が中心となり、サービスディスカバリやポリシー配布、証明書管理などを一元的に行います。
- サービスディスカバリ:Kubernetes の Service と Endpoint を自動取得
- ポリシー配信:PeerAuthentication・RequestAuthentication・AuthorizationPolicy などの CRD を Envoy にプッシュ
- 証明書管理:SPIFFE ID に基づく短期証明書を自動発行
結論:Istio の認証機能はコントロールプレーンで定義され、データプレーンの Envoy が実際にトラフィックを保護するため、開発者はコード変更なしでゼロトラストを適用できます。
PeerAuthentication による mTLS の設定方法と通信暗号化の流れ
この章では、クラスター全体に対して mTLS を有効化する手順と、実際にハンドシェイクがどのように行われてデータが暗号化されるかを具体的に示します。まずは設定対象のスコープについて理解し、その後ハンドシェイクの内部フローを確認しましょう。
グローバル・ネームスペース単位での PeerAuthentication 設定手順
以下の手順では、クラスター全体(istio-system 名前空間)に対して STRICT モードの mTLS を適用します。設定を反映させるだけで、同一クラスタ内のすべてのサイドカーが相互認証を必須とし、暗号化されていない接続は自動的に切断されます。
|
1 2 3 4 5 6 7 8 9 |
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: istio-system # グローバル設定はこの名前空間に置く spec: mtls: mode: STRICT |
- ポイント:
STRICTに変更した瞬間、全サイドカーが mTLS ハンドシェイクを要求し、失敗した接続は403 Forbidden相当でリジェクトされます。 - 留意点:既存の非 TLS 通信がある場合は、先に対象サービスを段階的に移行するか、一時的に
PERMISSIVEに設定して安全確認を行うことが推奨されます。
mTLS ハンドシェイクとデータ暗号化の実装フロー
mTLS の内部動作は「相互認証」+「通信路暗号化」の二段階で構成されています。ここでは、Envoy が istiod から取得した証明書を用いてどのようにハンドシェイクと鍵交換が行われるかを時系列で示します。
-
証明書取得
istiodは各 Envoy に対して SPIFFE ID を含む短期証明書(有効期限は数時間)を自動配布します。 -
ハンドシェイク開始
クライアント側 Envoy がサーバー側 Envoy の証明書を受信し、tls_contextに基づいて検証を行います。 -
相互認証完了
証明書が有効かつ信頼できる場合に限り、TLS 1.3 の ECDHE アルゴリズムで共通鍵(セッションキー)を生成します。 -
データ暗号化
以降の HTTP/2 フレームは AES‑GCM などの対称鍵暗号で保護され、ネットワーク上に平文が流れることはありません。 -
ポイント:
STRICTモードでは証明書検証に失敗した接続を即座にリジェクトするため、設定ミスや証明書の期限切れが早期に検知できます。
RequestAuthentication と JWT 検証による外部 IdP 連携(Keycloak 例)
このセクションでは、外部認可サーバーとして Keycloak を利用し、Istio が JWT の署名を検証するまでの手順を示します。まずは Keycloak 側で必要なレルムとクライアントを作成し、次に Istio 側で RequestAuthentication リソースを設定します。
Keycloak 側のクライアント・レルム設定概要
Keycloak において「レルム」と「クライアント」を正しく構築すれば、Istio が JWT の署名と有効期限を検証できるようになります。以下は最小構成の要点です。
- レルム作成
-
例:
microservice-realm(テナント単位で分離) -
クライアント登録
- タイプ:
confidential -
アクセストークン署名アルゴリズム:
RS256(デフォルト推奨) -
公開鍵取得
-
レルム設定 →
Keysタブ →Public Key (PEM)をコピー、または JWKS エンドポイントを利用 -
ポイント:JWKS エンドポイント(例:
https://keycloak.example.com/realms/microservice-realm/protocol/openid-connect/certs)を指定すれば、鍵ローテーションが自動的に反映されます。
Istio の RequestAuthentication リソースで JWT 公開鍵を指定する方法
Istio 側では RequestAuthentication に JWKS URI を設定し、Envoy が受信したリクエストヘッダーのトークンを自動的に検証します。以下は frontend 名前空間のフロントエンドアプリケーション向け設定例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: keycloak-jwt namespace: frontend spec: selector: matchLabels: app: my-frontend jwtRules: - issuer: "https://keycloak.example.com/realms/microservice-realm" jwksUri: "https://keycloak.example.com/realms/microservice-realm/protocol/openid-connect/certs" forwardOriginalToken: true # 必要に応じてバックエンドへトークン転送 |
- ポイント:
RequestAuthenticationが有効になると、同一名前空間内のAuthorizationPolicyと組み合わせて RBAC を実装でき、認証済みユーザーだけが特定 API にアクセス可能となります。
AuthorizationPolicy の基本構文とマイクロサービス単位でのアクセス制御例
ここでは、Istio が提供する AuthorizationPolicy の書き方と、実際にマイクロサービスごとに細かいアクセス権限を設定する方法を紹介します。まずはポリシー適用範囲(スコープ)の決め方を説明し、その後 allow/deny ルールの具体例を示します。
ポリシーのスコープ(ネームスペース・サービス単位)
AuthorizationPolicy は ネームスペースレベル と Pod ラベルベース(サービス単位) のいずれかで適用できます。スコープを意図的に絞ることで、最小特権の原則を実装しやすくなります。
- ネームスペース全体:
namespace: ordersに対してポリシーを設定すると、その名前空間内のすべてのサービスが対象になります。 - ラベル指定:
selector.matchLabels.app: orders-serviceのように特定の Pod にだけ適用可能です。
以下は orders 名前空間で読み取りは全ユーザー、書き込みは管理者のみ許可する例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: orders-read-only namespace: orders spec: selector: matchLabels: app: orders-service rules: - from: - source: requestPrincipals: ["*"] # 任意の認証済みユーザー to: - operation: methods: ["GET"] |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: orders-admin-write namespace: orders spec: selector: matchLabels: app: orders-service rules: - from: - source: requestPrincipals: ["admin@microservice-realm"] # Keycloak の admin ユーザー to: - operation: methods: ["POST","PUT","DELETE"] |
- ポイント:
requestPrincipalsはRequestAuthenticationが検証した JWT のsubやaudとマッチさせられるため、外部 IdP とシームレスに連携できます。
allow/deny ルールの実装サンプル
Istio のデフォルトは「ポリシーが無ければ許可」になるため、安全なベースラインを作るには 明示的な deny を先に設定し、その上で allow ポリシーを追加します。以下は外部 IP からの全アクセスを遮断する例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-external-ip namespace: istio-system # クラスタ全体に適用 spec: action: DENY rules: - from: - source: ipBlocks: ["0.0.0.0/0"] # 全IP アドレス when: - key: request.headers[":authority"] notValues: ["internal.example.com"] |
- ポイント:
action: DENYが最優先で評価され、後続の allow ルールがあっても上書きできません。これにより意図しない外部アクセスを確実に防げます。
NIST SP 800‑204 に基づくゼロトラストモデルと Istio の役割
NIST が示す Zero Trust Architecture(ZTA)は、常に認証・認可を行い、最小特権でアクセスする ことを基本原則としています。この章では、Istio が ZTA の主要要素にどのようにマッピングできるかを具体的に示します。
ZTA と Istio 機能の対応表
以下の表は NIST SP 800‑204 の要素と、それに該当する Istio の機能・実装例をまとめたものです。各項目は実際のマニフェスト例と併せて示しています。
| ZTA 要素 | 対応する Istio 機能 | 実装例 |
|---|---|---|
| アイデンティティ検証 | RequestAuthentication + JWT |
Keycloak と連携し、JWT 署名を検証 |
| データ保護(暗号化) | PeerAuthentication (STRICT mTLS) |
全サービス間の通信を TLS で暗号化 |
| ポリシー駆動アクセス制御 | AuthorizationPolicy |
allow/deny ルールで RBAC を実装 |
| ログ・監査 | Envoy アクセスログ + Telemetry (Prometheus) | トラフィックメトリクスを可視化 |
- ポイント:Istio を導入するだけで、ZTA が要求する「認証」「暗号化」「ポリシー制御」の三本柱が自動的に満たされます。追加のセキュリティツールは最小限に抑えられ、運用コストを削減できます。
実装手順・デバッグ方法と次のアクション
この章では、Istio のインストールからポリシー適用、トラブルシューティングまでの一連のフローを具体的に示します。実際に手を動かす際の注意点や、問題が発生した場合の確認ポイントも併せて解説します。
istiod のインストールと基本設定
まずは istioctl を用いてコントロールプレーン(istiod)をデプロイし、サイドカー自動注入を有効化します。以下の手順でデフォルトプロファイルをインストールすると、認証関連の CRD がすべて作成されます。
|
1 2 3 4 5 6 7 8 9 10 11 |
# Istio バイナリ取得(例: 1.20.0) curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.20.0 sh - cd istio-1.20.0 export PATH=$PWD/bin:$PATH # デフォルトプロファイルでインストール istioctl install --set profile=default -y # default 名前空間へ自動サイドカー注入ラベル付与 kubectl label namespace default istio-injection=enabled |
- ポイント:インストール後は
kubectl get pods -n istio-systemでistiodとistio-proxyが正常に起動していることを必ず確認してください。
ポリシー適用フロー(kubectl apply → istioctl proxy‑status)
ポリシーは Kubernetes の標準コマンドで作成し、istioctl proxy-status で各サイドカーへの反映状況を即座にチェックできます。以下は先ほどの PeerAuthentication・RequestAuthentication・AuthorizationPolicy を適用する例です。
|
1 2 3 4 5 6 7 8 |
# CRD 適用 kubectl apply -f peer-authentication.yaml kubectl apply -f request-authentication.yaml kubectl apply -f authorization-policy.yaml # 反映確認 istioctl proxy-status |
- ポイント:
proxy-statusの出力にSYNCEDと表示されていれば、Envoy に設定が正しくプッシュされています。NOT_SYNCEDが出た場合は、対象 Pod のラベルや名前空間がポリシーと合致しているかを再確認してください。
トラブルシューティングとログ確認ポイント
認証エラーは主に 証明書期限切れ、JWKS 取得失敗、Namespace/Label 不一致 が原因です。下記チェックリストに沿って順番に検証すると、問題箇所を迅速に特定できます。
| 確認項目 | 実行コマンド例 | 主な判定ポイント |
|---|---|---|
| Envoy ログで JWT エラー検索 | kubectl logs <pod>-istio-proxy -c istio-proxy | grep jwt_authn |
jwt verification failed が出ていないか |
| Istiod のイベント確認 | kubectl describe pod istiod-xxxxx -n istio-system |
CRD 更新時の Warning が無いか |
| mTLS ステータスチェック | istioctl authn tls-check <pod>.<ns> |
MTLS: ENABLED と表示されるか |
| JWKS エンドポイントの可達性 | curl -v https://keycloak.example.com/realms/microservice-realm/protocol/openid-connect/certs |
HTTP 200 と正しい JSON が返ってくるか |
- ポイント:問題が判明したら該当リソース(例:
PeerAuthenticationのmode)を修正し、再度kubectl applyで上書きすれば即座に反映されます。
以上が、Istio を用いたサービスメッシュの認証・認可基盤構築手順とデバッグ方法です。各セクションで示したマニフェスト例やコマンドを参考に、自組織の要件に合わせて Zero Trust アーキテクチャを実装してください。