セキュリティのベストプラクティス

Istio のセキュリティ機能は、強力な ID、強力なポリシー、透過的な TLS 暗号化、およびサービスとデータを保護するための認証、認可、監査 (AAA) ツールを提供します。ただし、これらの機能を安全に最大限に活用するには、ベストプラクティスに従うように注意する必要があります。続行する前に、セキュリティの概要を確認することをお勧めします。

相互TLS

Istio は、可能な限り 相互 TLS を使用してトラフィックを自動的に暗号化します。ただし、プロキシはデフォルトで許可モードで構成されているため、相互 TLS とプレーンテキストトラフィックの両方を受け入れます。

これは、段階的な導入や Istio サイドカーのないクライアントからのトラフィックを許可するために必要ですが、セキュリティ体制を弱めることにもなります。可能な場合は、相互 TLS の使用を強制するために厳格モードに移行することをお勧めします。

相互 TLS は認証のみを提供し、認可は提供しないため、トラフィックを完全に保護するには必ずしも十分ではありません。つまり、有効な証明書を持っている人は誰でもサービスにアクセスできます。

トラフィックを完全にロックダウンするには、認可ポリシーを構成することをお勧めします。これにより、トラフィックを許可または拒否するためのきめ細かいポリシーを作成できます。たとえば、app 名前空間からのリクエストのみが hello-world サービスにアクセスできるようにすることができます。

認可ポリシー

Istio 認可は、Istio セキュリティにおいて重要な役割を果たします。クラスターを最適に保護するために適切な認可ポリシーを構成するには、努力が必要です。Istio はすべてのユーザーに適切な認可を決定できないため、これらの構成の意味を理解することが重要です。このセクション全体に目を通してください。

より安全な認可ポリシーパターン

default-denyパターンの使用

クラスターのセキュリティ体制を強化するために、デフォルト拒否パターンに従って Istio 認可ポリシーを定義することをお勧めします。デフォルト拒否認可パターンとは、システムがデフォルトですべてのリクエストを拒否し、リクエストが許可される条件を定義することを意味します。いくつかの条件を見逃した場合、トラフィックは予期せず許可されるのではなく、予期せず拒否されます。後者は通常、セキュリティインシデントであり、前者はユーザーエクスペリエンスの低下、サービス停止、または SLO/SLA に一致しない可能性があります。

たとえば、HTTP トラフィックの認可タスクでは、allow-nothing という名前の認可ポリシーにより、すべてのトラフィックがデフォルトで拒否されます。そこから、他の認可ポリシーは特定の条件に基づいてトラフィックを許可します。

ALLOW-with-positive-matchingおよびDENY-with-negative-matchパターンの使用

可能な限り、ALLOW-with-positive-matching または DENY-with-negative-matching パターンを使用してください。これらの認可ポリシーパターンは、ポリシーの不一致の場合の最悪の結果が認可ポリシーのバイパスではなく、予期しない 403 拒否であるため、より安全です。

ALLOW-with-positive-matching パターンは、ポジティブマッチングフィールド(例:pathsvalues)のみで ALLOW アクションを使用し、ネガティブマッチングフィールド(例:notPathsnotValues)を使用しないことです。

DENY-with-negative-matching パターンは、ネガティブマッチングフィールド(例:notPathsnotValues)のみで DENY アクションを使用し、ポジティブマッチングフィールド(例:pathsvalues)を使用しないことです。

たとえば、以下の認可ポリシーは、/public パスへのリクエストを許可するために ALLOW-with-positive-matching パターンを使用しています

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: foo
spec:
  action: ALLOW
  rules:
  - to:
    - operation:
        paths: ["/public"]

上記のポリシーは、許可されるパス(/public)を明示的にリストしています。つまり、リクエストを許可するには、リクエストパスが /public と完全に同じである必要があります。他のリクエストはデフォルトで拒否され、不明な正規化動作がポリシーバイパスを引き起こすリスクを排除します。

以下は、同じ結果を達成するために DENY-with-negative-matching パターンを使用した例です

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: foo
spec:
  action: DENY
  rules:
  - to:
    - operation:
        notPaths: ["/public"]

認可ポリシーにおけるパス正規化の理解

認可ポリシーの適用ポイントは、バックエンドアプリケーションの通常のリソースアクセスポイントではなく、Envoy プロキシです。Envoy プロキシとバックエンドアプリケーションがリクエストを異なる方法で解釈する場合、ポリシーの不一致が発生します。

不一致は、予期しない拒否またはポリシーバイパスにつながる可能性があります。後者は通常、直ちに修正する必要があるセキュリティインシデントであり、認可ポリシーでパスの正規化が必要な理由でもあります。

たとえば、/data/secret パスのリクエストを拒否する認可ポリシーを考えてみましょう。パスに余分なスラッシュ / があるため、パス /data//secret のリクエストは、認可ポリシーで定義されたパスと一致しないため、拒否されません。

リクエストは通過し、後でバックエンドアプリケーションは、バックエンドアプリケーションがダブルスラッシュ // を単一のスラッシュ / と同等と見なすため、パス /data//secret/data/secret に正規化するため、パス /data/secret で返すものと同じ応答を返します。

この例では、ポリシーの適用ポイント(Envoy プロキシ)は、リソースアクセスポイント(バックエンドアプリケーション)とは異なるパスの解釈をしていました。この異なる解釈が不一致を引き起こし、結果として認可ポリシーのバイパスを引き起こしました。

次の要因により、これは複雑な問題になります

  • 正規化の明確な標準がない。

  • 異なるレイヤーのバックエンドとフレームワークには、独自の特別な正規化があります。

  • アプリケーションは、独自のユースケースに合わせて任意の正規化を行うこともできます。

Istio 認可ポリシーは、問題をより適切に対処できるように、さまざまな基本的な正規化オプションの組み込みサポートを実装しています

パス正規化オプションの構成に関するガイドライン

ケース1:正規化が全く不要な場合

正規化の構成の詳細に入る前に、まず正規化が必要であることを確認する必要があります。

認可ポリシーを使用しない場合、または認可ポリシーが path フィールドを使用しない場合は、正規化は必要ありません。

すべての認可ポリシーがより安全な認可パターンに従っている場合、最悪の場合、ポリシーバイパスではなく予期しない拒否が発生するため、正規化は必要ない場合があります。

ケース2:正規化が必要だが、どの正規化オプションを使用すればよいかわからない場合

正規化は必要だが、どのオプションを使用すればよいかわからない場合。最も安全な選択肢は、認可ポリシーで最大レベルの正規化を提供する最も厳格な正規化オプションです。

これは、複雑な多層システムにより、適用ポイントを超えてリクエストに実際にどのような正規化が行われているかを把握することが事実上不可能になることが多いためです。

要件をすでに満たしており、その影響を確信している場合は、それほど厳密でない正規化オプションを使用できます。

どちらのオプションでも、正規化が期待どおりに機能していることを確認するために、要件に合わせて正と負の両方のテストを記述してください。これらのテストは、リクエストに対して行われている正規化の誤解または不完全な知識によって引き起こされる可能性のあるバイパスの問題をキャッチするのに役立ちます。

正規化オプションの構成の詳細については、パス正規化に関するシステムのカスタマイズを参照してください。

ケース3:サポートされていない正規化オプションが必要な場合

Istio でまだサポートされていない特定の正規化オプションが必要な場合は、カスタマイズされた正規化サポートについてはサポートされていない正規化に対する緩和策に従うか、Istio コミュニティに機能リクエストを作成してください。

パスの正規化に関するシステムをカスタマイズする

Istio 認可ポリシーは、HTTP リクエストの URL パスに基づいています。パス正規化(別名、URI 正規化)は、受信リクエストのパスを変更および標準化して、正規化されたパスを標準的な方法で処理できるようにします。構文的に異なるパスは、パス正規化後に同等になる場合があります。

Istio は、認可ポリシーに対して評価し、リクエストをルーティングする前に、リクエストパスに対して次の正規化スキームをサポートしています

オプション説明
NONE正規化は実行されません。Envoy が受信したものはすべて、そのままバックエンドサービスに転送されます。../%2Fa../b は認可ポリシーによって評価され、サービスに送信されます。
BASEこれは現在、Istio のデフォルトインストールで使用されているオプションです。これは、Envoy プロキシでnormalize_pathオプションを適用します。このオプションは、バックスラッシュをスラッシュに変換する追加の正規化を備えたRFC 3986に従います。/a/../b/b に正規化されます。\da/da に正規化されます。
MERGE_SLASHESスラッシュはBASE正規化後にマージされます。/a//b/a/b に正規化されます。
DECODE_AND_MERGE_SLASHESデフォルトですべてのトラフィックを許可する場合の最も厳格な設定。この設定をお勧めしますが、認可ポリシーのルートを徹底的にテストする必要があるという注意点があります。パーセントエンコードされたスラッシュおよびバックスラッシュ文字(%2F%2f%5C、および %5c)は、MERGE_SLASHES 正規化の前に / または \ にデコードされます。/a%2fb/a/b に正規化されます。

強調すると、正規化アルゴリズムは次の順序で実行されます

  1. %2F%2f%5C および %5c をパーセントデコードします。
  2. RFC 3986と、Envoy のnormalize_pathオプションで実装されているその他の正規化。
  3. スラッシュのマージ

サポートされている正規化の完全なリストについては、認証ポリシーの正規化を参照してください。

構成例

Envoyがリクエストパスをバックエンドサービスの期待に一致するように正規化することは、システムのセキュリティにとって非常に重要です。以下の例は、システムを構成する際の参考として使用できます。正規化されたURLパス、またはNONEが選択されている場合は元のURLパスが使用されます。

  1. 認証ポリシーに対してチェックされます
  2. バックエンドアプリケーションに転送されます
アプリケーション…選択…
プロキシが正規化を実行することを信頼するBASEMERGE_SLASHES、またはDECODE_AND_MERGE_SLASHES
RFC 3986に基づいてリクエストパスを正規化し、スラッシュをマージしませんBASE
RFC 3986に基づいてリクエストパスを正規化し、スラッシュをマージしますが、パーセントエンコードされたスラッシュをデコードしませんMERGE_SLASHES
RFC 3986に基づいてリクエストパスを正規化し、パーセントエンコードされたスラッシュをデコードし、スラッシュをマージしますDECODE_AND_MERGE_SLASHES
RFC 3986と互換性のない方法でリクエストパスを処理しますNONE

構成方法

istioctlを使用してメッシュ構成を更新できます

$ istioctl upgrade --set meshConfig.pathNormalization.normalization=DECODE_AND_MERGE_SLASHES

または、オペレーターのオーバーライドファイルを変更することによって

$ cat <<EOF > iop.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    pathNormalization:
      normalization: DECODE_AND_MERGE_SLASHES
EOF
$ istioctl install -f iop.yaml

または、メッシュ構成を直接編集する場合は、pathNormalizationメッシュ構成に追加できます。これは、istio-system名前空間のistio-<REVISION_ID> configmapです。たとえば、DECODE_AND_MERGE_SLASHESオプションを選択する場合は、次のようにメッシュ構成を変更します。

apiVersion: v1
  data:
    mesh: |-
      ...
      pathNormalization:
        normalization: DECODE_AND_MERGE_SLASHES
      ...

サポートされていない正規化に対する緩和策

このセクションでは、サポートされていない正規化に対するさまざまな軽減策について説明します。これらは、Istioでサポートされていない特定の正規化が必要な場合に役立ちます。

軽減策を十分に理解し、一部の軽減策はIstioの範囲外であり、Istioでもサポートされていないものに依存するため、慎重に使用してください。

カスタム正規化ロジック

WASMまたはLuaフィルターを使用して、カスタム正規化ロジックを適用できます。WASMフィルターは公式にサポートされており、Istioでも使用されているため、WASMフィルターを使用することをお勧めします。Luaフィルターは、概念実証デモをすばやく行うために使用できますが、Istioでサポートされていないため、実稼働環境でLuaフィルターを使用することはお勧めしません。

カスタム正規化の例(ケース正規化)

一部の環境では、認証ポリシーのパスを大文字と小文字を区別しない方法で比較すると便利な場合があります。たとえば、https://myurl/gethttps://myurl/GeTを同等に扱うなどです。

このような場合、以下に示すEnvoyFilterを使用して、パスを小文字に正規化するLuaフィルターを挿入できます。このフィルターは、比較に使用されるパスとアプリケーションに提示されるパスの両方を変更します。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: ingress-case-insensitive
  namespace: istio-system
spec:
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
    patch:
      operation: INSERT_FIRST
      value:
        name: envoy.lua
        typed_config:
            "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
            inlineCode: |
              function envoy_on_request(request_handle)
                local path = request_handle:headers():get(":path")
                request_handle:headers():replace(":path", string.lower(path))
              end

ホスト一致ポリシーの記述

Istioは、ホスト名自体と一致するすべてのポートの両方に対してホスト名を生成します。たとえば、example.comのホストの仮想サービスまたはゲートウェイは、example.comおよびexample.com:*に一致する構成を生成します。ただし、完全一致の認証ポリシーは、hostsまたはnotHostsフィールドに指定された正確な文字列のみに一致します。

ホストに一致する認証ポリシーのルールは、完全一致ではなくプレフィックス一致を使用して記述する必要があります。たとえば、example.comのホスト名に対して生成されたEnvoy構成に一致するAuthorizationPolicyの場合、以下のAuthorizationPolicyに示すように、hosts: ["example.com", "example.com:*"]を使用します。

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: ingress-host
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: istio-ingressgateway
  action: DENY
  rules:
  - to:
    - operation:
        hosts: ["example.com", "example.com:*"]

さらに、hostおよびnotHostsフィールドは、一般的に、メッシュに入る外部トラフィックのゲートウェイでのみ使用し、メッシュ内のトラフィックのサイドカーでは使用しないでください。これは、サーバー側のサイドカー(認証ポリシーが適用される場所)が、リクエストをアプリケーションにリダイレクトするときにHostヘッダーを使用しないためです。これにより、クライアントがサービス名ではなく、明示的なIPアドレスと任意のHostヘッダーを使用してアプリケーションにアクセスできるため、サイドカーのhostnotHostは意味がなくなります。

何らかの理由でサイドカーのHostヘッダーに基づいてアクセス制御を強制する必要がある場合は、クライアントが任意のHostヘッダーを使用した場合にリクエストを拒否するデフォルト拒否パターンに従ってください。

特化した Web アプリケーションファイアウォール(WAF)

多くの特殊なWebアプリケーションファイアウォール(WAF)製品は、追加の正規化オプションを提供します。これらは、メッシュに入るリクエストを正規化するために、Istioイングレスゲートウェイの前にデプロイできます。認証ポリシーは、正規化されたリクエストに適用されます。正規化オプションの構成については、特定のWAF製品を参照してください。

Istio への機能リクエスト

Istioが特定の正規化を公式にサポートする必要があると思われる場合は、脆弱性の報告ページに従って、特定の正規化に関する機能リクエストをIstio製品セキュリティ作業グループに送信して、最初の評価を受けることができます。

問題が非公開で修正する必要があるセキュリティ脆弱性と見なされる可能性があるため、最初にIstio製品セキュリティ作業グループに連絡せずに、公開で問題を開かないでください。

Istio製品セキュリティ作業グループが機能リクエストをセキュリティ脆弱性ではないと評価した場合、機能リクエストに関するさらなる議論のために公開で問題が開かれます。

既知の制限事項

このセクションでは、認証ポリシーの既知の制限事項を示します。

サーバーファースト TCP プロトコルはサポートされていません

サーバーファーストのTCPプロトコルは、サーバーアプリケーションがクライアントからデータを受信する前に、TCP接続を受け入れた直後に最初のバイトを送信することを意味します。

現在、認証ポリシーはインバウンドトラフィックでのアクセス制御の強制のみをサポートしており、アウトバウンドトラフィックはサポートしていません。

また、サーバーファーストのTCPプロトコルはサポートされていません。これは、最初のバイトがクライアントからデータを受信する前でもサーバーアプリケーションによって送信されるためです。この場合、サーバーによって送信された最初の最初のバイトは、認証ポリシーのアクセス制御チェックを経由せずに、クライアントに直接返されます。

サーバーファーストのTCPプロトコルによって送信される最初のバイトに、適切な認証によって保護する必要がある機密データが含まれている場合は、認証ポリシーを使用しないでください。

たとえば、最初のバイトがクライアントがアクセスできるデータを伴う接続をネゴシエートするために使用されているなど、最初のバイトに機密データが含まれていない場合は、この場合でも認証ポリシーを使用できます。認証ポリシーは、最初のバイトの後にクライアントによって送信された後続のリクエストに対して通常どおりに機能します。

トラフィックキャプチャの制限を理解する

Istioサイドカーは、インバウンドトラフィックとアウトバウンドトラフィックの両方をキャプチャし、サイドカープロキシを介してそれらを誘導することによって機能します。

ただし、すべてのトラフィックがキャプチャされるわけではありません

  • リダイレクトは、TCPベースのトラフィックのみを処理します。UDPまたはICMPパケットはキャプチャまたは変更されません。
  • インバウンドキャプチャは、多くのサイドカーで使用されるポートとポート22で無効になっています。このリストは、traffic.sidecar.istio.io/excludeInboundPortsのようなオプションで拡張できます。
  • アウトバウンドキャプチャも、traffic.sidecar.istio.io/excludeOutboundPortsやその他の手段によって同様に削減できます。

一般に、アプリケーションとそのサイドカープロキシの間には最小限のセキュリティ境界しかありません。サイドカーの構成はポッドごとに許可されており、両方とも同じネットワーク/プロセス名前空間で実行されます。そのため、アプリケーションはリダイレクトルールを削除し、サイドカープロキシを削除、変更、終了、または置き換える機能を持っている場合があります。これにより、ポッドはアウトバウンドトラフィックのサイドカーを意図的にバイパスしたり、インバウンドトラフィックがサイドカーをバイパスすることを意図的に許可したりできます。

その結果、Istioによってすべてのトラフィックが無条件にキャプチャされると信頼することは安全ではありません。代わりに、セキュリティ境界は、クライアントが別のポッドのサイドカーをバイパスできないことです。

たとえば、ポート9080reviewsアプリケーションを実行する場合、productpageアプリケーションからのすべてのトラフィックはサイドカープロキシによってキャプチャされると想定できます。ここで、Istio認証および認証ポリシーを適用できます。

NetworkPolicy による多層防御

トラフィックをさらに保護するために、IstioポリシーはKubernetesネットワークポリシーと重ねて使用できます。これにより、メッシュのセキュリティをさらに強化するために使用できる強力な多層防御戦略が可能になります。

たとえば、reviewsアプリケーションのポート9080へのトラフィックのみを許可することを選択できます。ポッドが侵害されたり、クラスターにセキュリティ脆弱性が発生した場合、これにより攻撃者の進行を制限または停止できます。

実際の実装によっては、ネットワークポリシーの変更がIstioプロキシの既存の接続に影響を与えない場合があります。既存の接続が閉じられ、新しい接続が新しいポリシーに従うように、ポリシーを適用した後にIstioプロキシを再起動する必要がある場合があります。

エグレス トラフィックの保護

一般的な誤解は、outboundTrafficPolicy: REGISTRY_ONLYのようなオプションが、宣言されていないサービスへのすべてのアクセスを防止するセキュリティポリシーとして機能することです。ただし、これは上記のように強力なセキュリティ境界ではなく、最善の努力と見なされる必要があります。

これは意図しない依存関係を防ぐのに役立ちますが、エグレストラフィックを保護し、すべてのアウトバウンドトラフィックがプロキシを通過するように強制する場合は、代わりにエグレスゲートウェイに依存する必要があります。ネットワークポリシーと組み合わせると、すべてのトラフィック、または一部のサブセットがエグレスゲートウェイを通過するように強制できます。これにより、クライアントが誤ってまたは悪意を持ってサイドカーをバイパスした場合でも、リクエストがブロックされます。

TLS オリジネーションを使用する場合の Destination Rule での TLS 検証の構成

Istio は、サイドカープロキシまたはゲートウェイから TLS を開始する機能を提供します。これにより、プレーンテキストの HTTP トラフィックを送信するアプリケーションを透過的に HTTPS に「アップグレード」できます。

DestinationRuletls 設定で、caCertificatessubjectAltNames、および sni フィールドを指定する際には注意が必要です。caCertificate は、Istiod で環境変数 VERIFY_CERTIFICATE_AT_CLIENT=true を有効にすることで、システムの証明書ストアの CA 証明書から自動的に設定できます。自動的に使用されるオペレーティングシステムの CA 証明書が特定のホストでのみ必要な場合は、Istiod で環境変数 VERIFY_CERTIFICATE_AT_CLIENT=false を設定し、目的の DestinationRulecaCertificatessystem に設定できます。DestinationRulecaCertificates を指定すると優先され、OS の CA 証明書は使用されません。デフォルトでは、エグレストラフィックは TLS ハンドシェイク中に SNI を送信しません。ホストがリクエストを適切に処理できるように、SNI は DestinationRule で設定する必要があります。

例:

apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: google-tls
spec:
  host: google.com
  trafficPolicy:
    tls:
      mode: SIMPLE
      caCertificates: /etc/ssl/certs/ca-certificates.crt
      subjectAltNames:
      - "google.com"
      sni: "google.com"

ゲートウェイ

Istio の ゲートウェイを実行する場合、いくつかのリソースが関与します。

  • Gateway は、ゲートウェイのポートと TLS 設定を制御します。
  • VirtualService は、ルーティングロジックを制御します。これらは、gateways フィールドで直接参照することにより、および GatewayVirtualServicehosts フィールドで相互に合意することにより、Gateway に関連付けられます。

Gateway 作成権限の制限

Gateway リソースの作成を信頼できるクラスター管理者に制限することをお勧めします。これは、Kubernetes RBAC ポリシーまたは Open Policy Agent のようなツールによって実現できます。

広すぎる hosts 構成の回避

可能な限り、Gateway で過度に広範な hosts 設定を避けてください。

たとえば、この構成では、任意の VirtualServiceGateway にバインドすることを許可し、予期しないドメインを公開する可能性があります。

servers:
- port:
    number: 80
    name: http
    protocol: HTTP
  hosts:
  - "*"

これは、特定のドメインまたは特定の名前空間のみを許可するようにロックダウンする必要があります。

servers:
- port:
    number: 80
    name: http
    protocol: HTTP
  hosts:
  - "foo.example.com" # Allow only VirtualServices that are for foo.example.com
  - "default/bar.example.com" # Allow only VirtualServices in the default namespace that are for bar.example.com
  - "route-namespace/*" # Allow only VirtualServices in the route-namespace namespace for any host

機密性の高いサービスの分離

機密性の高いサービスに対して、より厳格な物理的隔離を強制したい場合があります。たとえば、機密性の高い payments.example.com には 専用のゲートウェイインスタンスを実行し、機密性の低いドメイン(blog.example.comstore.example.com など)には単一の共有ゲートウェイインスタンスを利用したい場合があります。これにより、より強力な多層防御を提供し、特定の規制コンプライアンスガイドラインを満たすことができます。

緩和された SNI ホストマッチングの下ですべての機密性の高い http ホストを明示的に無効にする

複数の Gateway を使用して、異なるホストで相互 TLS とシンプルな TLS を定義することは合理的です。たとえば、SNI ホスト admin.example.com には相互 TLS を使用し、SNI ホスト *.example.com にはシンプルな TLS を使用します。

kind: Gateway
metadata:
  name: guestgateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - "*.example.com"
    tls:
      mode: SIMPLE
---
kind: Gateway
metadata:
  name: admingateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - admin.example.com
    tls:
      mode: MUTUAL

上記が必要な場合は、*.example.com にアタッチする VirtualService で、http ホスト admin.example.com を明示的に無効にすることを強くお勧めします。その理由は、現在、基盤となる envoy プロキシが、SNI 制約に従って http 1 ヘッダー Host または http 2 疑似ヘッダー :authority を必要としないため、攻撃者はゲスト SNI TLS 接続を再利用して管理者 VirtualService にアクセスできる可能性があるためです。http レスポンスコード 421 は、この Host SNI の不一致のために設計されており、無効化を満たすために使用できます。

apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: disable-sensitive
spec:
  hosts:
  - "admin.example.com"
  gateways:
  - guestgateway
  http:
  - match:
    - uri:
        prefix: /
    fault:
      abort:
        percentage:
          value: 100
        httpStatus: 421
    route:
    - destination:
        port:
          number: 8000
        host: dest.default.cluster.local

プロトコル検出

Istio は、認識したトラフィックの プロトコルを自動的に判断します。予期しないトラフィック動作につながる可能性のある、偶発的または意図的な誤検出を回避するために、可能な限り プロトコルを明示的に宣言することをお勧めします。

CNI

すべてのトラフィックを透過的にキャプチャするために、Istio は istio-init initContainer によって構成された iptables ルールに依存しています。これにより、ポッドで NET_ADMIN および NET_RAW 機能が利用可能であるという 要件が追加されます。

ポッドに付与される権限を削減するために、Istio はこの要件を削除する CNI プラグインを提供しています。

強化された Docker イメージの使用

コントロールプレーン、ゲートウェイ、およびサイドカープロキシによって実行されるものを含め、Istio のデフォルトの Docker イメージは ubuntu をベースにしています。これにより、bashcurl などのさまざまなツールが提供され、利便性と引き換えに攻撃対象が増加します。

Istio は、イメージ内の依存関係を削減する distroless イメージに基づく、より小さなイメージも提供しています。

リリースとセキュリティポリシー

既知の脆弱性に対する最新のセキュリティパッチがクラスターに適用されていることを保証するために、Istio の最新のパッチリリースを維持し、セキュリティパッチをまだ受け取っている サポートされているリリースを使用していることを確認することが重要です。

無効な構成の検出

Istio はリソースが作成されるときに検証を提供しますが、これらのチェックではメッシュ内で構成が分散されるのを妨げるすべての問題をキャッチできません。これにより、予期せず無視されるポリシーが適用され、予期しない結果につながる可能性があります。

  • 構成を適用する前または適用した後に istioctl analyze を実行して、それが有効であることを確認してください。
  • 拒否された構成についてコントロールプレーンを監視します。これらは、ログに加えて pilot_total_xds_rejects メトリクスによって公開されます。
  • 構成をテストして、予期した結果が得られることを確認してください。セキュリティポリシーの場合、過度に多くのトラフィックまたは少なすぎるトラフィックを誤って制限しないように、ポジティブテストとネガティブテストを実行すると便利です。

アルファ版および実験的な機能の回避

すべての Istio の機能と API には、安定性、非推奨ポリシー、およびセキュリティポリシーを定義する 機能ステータスが割り当てられています。

アルファ機能と実験的機能にはセキュリティ保証が強くないため、可能な限り避けることをお勧めします。これらの機能で見つかったセキュリティ問題は、すぐには修正されない場合や、標準の セキュリティ脆弱性プロセスに従わない場合があります。

クラスターで使用中の機能の機能ステータスを判断するには、Istio 機能リストを参照してください。

ポートのロックダウン

Istio は、セキュリティを向上させるためにロックダウンできる さまざまなポートを構成します。

コントロールプレーン

Istiod は、便宜上、デフォルトでいくつかの認証されていないプレーンテキストポートを公開します。必要に応じて、これらを閉じることができます。

  • ポート 8080 は、クラスターの状態に関するさまざまな詳細への読み取りアクセスを提供するデバッグインターフェイスを公開します。これは、Istiod で環境変数 ENABLE_DEBUG_ON_HTTP=false を設定することで無効にできます。警告: 多くの istioctl コマンドはこのインターフェイスに依存しており、無効にすると機能しません。
  • ポート 15010 は、プレーンテキストを介して XDS サービスを公開します。これは、Istiod デプロイメントに --grpcAddr="" フラグを追加することで無効にできます。注: 証明書の署名および配布サービスなどの非常に機密性の高いサービスは、プレーンテキストで提供されることはありません。

データプレーン

プロキシはさまざまなポートを公開します。外部に公開されているのは、ポート 15090(テレメトリ)とポート 15021(ヘルスチェック)です。ポート 1502015000 は、デバッグエンドポイントを提供します。これらは localhost のみで公開されます。その結果、プロキシと同じポッドで実行されているアプリケーションがアクセスできます。サイドカーとアプリケーションの間には信頼境界はありません。

サードパーティサービスアカウントトークンの構成

Istio コントロールプレーンで認証するには、Istio プロキシはサービスアカウントトークンを使用します。Kubernetes は、これらのトークンを 2 つの形式でサポートしています。

  • スコープ付きの対象者と有効期限を持つサードパーティートークン。
  • 有効期限がなく、すべてのポッドにマウントされるファーストパーティートークン。

ファーストパーティートークンのプロパティは安全性が低いため、Istio はデフォルトでサードパーティートークンを使用します。ただし、この機能はすべての Kubernetes プラットフォームで有効になっているわけではありません。

istioctl を使用してインストールする場合、サポートは自動的に検出されます。これは手動でも実行でき、--set values.global.jwtPolicy=third-party-jwt または --set values.global.jwtPolicy=first-party-jwt を渡すことで構成できます。

クラスターがサードパーティートークンをサポートしているかどうかを確認するには、TokenRequest API を探してください。これが応答を返さない場合、その機能はサポートされていません。

$ kubectl get --raw /api/v1 | jq '.resources[] | select(.name | index("serviceaccounts/token"))'
{
    "name": "serviceaccounts/token",
    "singularName": "",
    "namespaced": true,
    "group": "authentication.k8s.io",
    "version": "v1",
    "kind": "TokenRequest",
    "verbs": [
        "create"
    ]
}

ほとんどのクラウドプロバイダーがこの機能をサポートしていますが、多くのローカル開発ツールとカスタムインストールは Kubernetes 1.20 より前ではサポートされていない場合があります。この機能を有効にするには、Kubernetes のドキュメントを参照してください。

ダウンストリーム接続の制限の構成

デフォルトでは、Istio(および Envoy)にはダウンストリーム接続の数に制限がありません。これは、悪意のある行為者によって悪用される可能性があります(セキュリティ速報 2020-007を参照)。これを回避するには、環境に適切な接続制限を構成する必要があります。

global_downstream_max_connections 値の構成

次の構成は、インストール中に指定できます。

meshConfig:
  defaultConfig:
    runtimeValues:
      "overload.global_downstream_max_connections": "100000"
この情報は役に立ちましたか?
改善のための提案はありますか?

フィードバックありがとうございます!