これまで取り上げてきたように、Istioには大きく分けて3つの特徴があります。今回は3つ目の特徴として「Security」について紹介します。

  • Traffic Management:ルーティング制御、ゲートウェイ、サーキットブレーカー、カオスエンジニアリング
  • Observability:メトリクス、分散トレーシング、アクセスログ管理
  • Security:鍵や証明書の管理、認証(Authentication)、認可(Authorization)
  • Istio

    Istioの3つの特徴/出典:公式サイト

特徴3:Security

マイクロサービスの流行以前、セキュリティに関しては「システム境界において担保する」というのが基本的な考え方でした。しかし近年、モノリスなシステムがマイクロサービスに分割され、それぞれのマイクロサービスがAPI公開されるようになっています。こうした状況を踏まえ、「仮にシステム内であっても安易に信用しない」というゼロトラストの考え方が広まってきました。

Istioは、システムの外部につながるサービスメッシュの境界(下図の点線枠)だけではなく、システム内部のマイクロサービス間(下図ServiceAとB間)においてもセキュリティ担保の仕組みを提供しています。鍵や証明書の管理をIstioにより簡易に実現でき、ポリシーベースの細やかな認証・認可の設定が可能です。

認証方式としては、JWTやmTLSなどを利用することができます。また、認可については、リクエスト先・元に応じてルールを設定したり、アプリケーション単位でルールを設定したりします。

  • セキュリティアーキテクチャ

    セキュリティアーキテクチャ(公式サイト)

以降では、Istioのセキュリティについて次の3つの観点から順に説明していきます。

  • 特徴3-1:鍵や証明書の管理
  • 特徴3-2:Authentication(認証)
  • 特徴3-3:Authorization(認可)

それぞれの説明において登場するCRD(Custom Resource Definition)の位置付けを、ざっくり以下のような構造で理解しておくと良いでしょう。鍵や証明書の管理を行うためのCRDがあり、また認証認可の要件に応じたCRDが活用できます。

  • CRD

    CRDの位置付け(特徴3-1、3-2、3-3)

特徴3-1:鍵や証明書の管理

TLS通信をする際は、公開鍵暗号方式で秘密鍵と公開鍵のペアを用いて通信します。 その際、公開鍵がサーバのものであることを証明するのが「証明書」です。

証明書はルート証明書を起点とした証明書チェーンの構造になります(下図左)。証明書チェーンにおける各証明書はCSRに基づいて認証局により署名されます。ルート証明書については自己署名となります(下図右)。

※ 図中では表現していませんが、TLSではなく、m-TLS(相互TLS)を行う場合においては、TLSハンドシェイクの際に、クライアント証明書もやり取りします。

サービスメッシュを構成する各Podに1つずつ鍵配布を行うことは、工数がかかるのみならず、作業ミスの温床になり得ます。CNCF(Cloud Native Computing Foundation)のSandboxプロジェクトである「cert-manager」と連動することで、X.509証明書による鍵や証明書管理を自動化できます。

それではCRDの設定イメージを具体的に見ていきましょう。Issuerリソースは、認証局のCertificateリソースにおいて、X.509証明書の役割を果たします。

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: ca-issuer
  namespace: cert-manager
spec:
  ca:
    secretName: ca-key-pair

issueRefにおいて、Issuerへの参照を指定します。なお、Certificateリソースを作成すると、関連するCertificateRequestリソース(CSR)などが従属して作成されます。

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: acme-crt
spec:
  secretName: acme-crt-secret
  dnsNames:
  - example.com
  - foo.example.com
  issuerRef:
    name: ca-issuer
    kind: Issuer
    group: cert-manager.io

特徴3-2:Authentication(認証)

従来のモノリス・Web3層モデルのセキュリティと言えば、ファイアウォールなどに代表される「境界型セキュリティ」が一般的でした。つまり、システムの内部の通信は信頼できることを前提としていました。

一方、マイクロサービス間の通信の世界では、たとえ同じシステム内のマイクロサービス間でも信頼できないことを前提とするゼロトラストネットワークが採用されることが多くなっています。

そのため、例えばmTLSによりクライアントサイドの証明書も要求しつつHTTPSの通信を実現したり、OAuth 2.0やOpen ID Connectなどで利用されるJWT(JSON Web Token)による、トークンを用いた認証を実現したりします。

Istioでは、以下の2つの認証方式を提供しています。

  • ピア認証(Peer authentication):mTLS(mutual TLS, 相互TLS)認証を用いたサービス間の相互認証
  • リクエスト認証(Request authentication):JWTを用いたアクセストークンベースの認証

以下はピア認証の例です。httpbinアプリケーションに対して、「STRICT」を指定することでTLSのトラフィックのみ受け付けるように設定しています。

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: "example-policy"
  namespace: "abc"
spec:
  selector:
    matchLabels:
      app: httpbin
  mtls:
    mode: STRICT

また、要件に合わせてTLSのトラフィックを適用する範囲を検討すると良いでしょう。詳細については、Istioの公式サイト(Authentication Policy)をご確認ください。

  • ルートnamespaceを指定し、全体に適用
  • 特定のnamespaceに絞る
  • 特定のnamespaceに絞り、かつ特定のアプリケーション → 今回設定したのはココ

次に、リクエスト認証の例を紹介します。以下は、httpbinワークロードが「testing@secure.istio.io」により発行されたJWTを受け付けるポリシーです。

apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: "jwt-example"
  namespace: abc
spec:
  selector:
    matchLabels:
      app: httpbin
  jwtRules:
  - issuer: "testing@secure.istio.io"
    jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.11/security/tools/jwt/samples/jwks.json"

また、要件に合わせて、リクエスト認証を設定する対象を指定すると良いでしょう。詳細については、公式サイト(Authentication Policy)をご確認ください。

  • システム境界の認証:IngressGatewayを指定
  • 個別のマイクロサービスの認証 → 今回設定したのはココ

特徴3-3:Authorization(認可)

Istioを使うことで、特定のアプリケーションや特定バージョンに対して、通信を許可・拒否するような認可をポリシーベースで実現することができます。その際には、通信元、通信方法(HTTPメソッドタイプ)など、認可の条件を細やかに設定可能です。

具体的な設定例は、以下のYAMLに示す通りです。YAML内のspec以下の各項目で、通信元のnamespaceを限定したり、HTTPメソッドにGETをしたりしています。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin
 namespace: abc
spec:
 selector:
   matchLabels:
     app: httpbin
     version: v1
 action: ALLOW
 rules:
 - from:
   - source:
       principals: ["cluster.local/ns/default/sa/sleep"]
   - source:
       namespaces: ["dev"]
   to:
   - operation:
       methods: ["GET"]
   when:
   - key: request.auth.claims[iss]
     values: ["https://accounts.google.com"]

上記YAMLにおける各設定内容は以下の通りです。

階層1 階層2 内容
selector matchLabels httpbinアプリケーションのv1に対して
action - 通信をALLOW(許可)する
rules from、to、when/td> ただし、適用条件は
・namespaceのsleepアプリケーションからの通信で
・HTTPメソッドがGETで
・JWTでのissuerクレームがvalues値に一致する場合に限る

* * *

今回はIstioの3つの特徴のうち、Securityについて解説しました。システム境界やシステム内のマイクロサービス間の認証認可の仕組みを、アプリケーションロジックに手を入れることなく、設定できることがおわかりいただけたかと思います。ぜひ、お手元の環境でIstioを試してみてください。

また、今回で5回にわたるIstioシリーズは終了となります。全体を改めて復習したい方は概要編を、手を動かしてみたい方はイントールと実行編を、それぞれの特徴を深掘りしたい方は各特徴編を復習してみてはいかがでしょうか。

  • 第26回 概要
  • 第27回 インストールと実行
  • 第28回 特徴1:Traffic Management
  • 第29回 特徴2:Observability
  • 第30回 特徴3:Security(今回)

もちろん、Kubernetes連載はまだまだ続いていきますので、今後の内容もお楽しみに!