認証ポリシー
このタスクでは、Istio認証ポリシーの有効化、構成、使用時に実行する必要がある主要なアクティビティについて説明します。基礎となる概念の詳細については、認証の概要をご覧ください。
始める前に
インストール手順6に記載されているように、`default`構成プロファイルを使用して、KubernetesクラスタにIstioをインストールします。
設定
これらの例では、`foo`と`bar`の2つの名前空間を使用し、それぞれにEnvoyプロキシで実行される`httpbin`と`curl`という2つのサービスがあります。また、サイドカーなしで`legacy`名前空間で実行される`httpbin`と`curl`の第2インスタンスも使用します。タスクを試行するときに同じ例を使用する場合は、次のコマンドを実行してください。
設定の検証は、名前空間`foo`、`bar`、または`legacy`内の任意の`curl` podから、`httpbin.foo`、`httpbin.bar`、または`httpbin.legacy`のいずれかに`curl`を使用してHTTPリクエストを送信することで行うことができます。すべてのリクエストはHTTPコード200で成功する必要があります。
例えば、`curl.bar`から`httpbin.foo`への到達可能性をチェックするコマンドを以下に示します。
このワンライナーコマンドは、すべての到達可能性の組み合わせを簡単に反復処理します。
以下のコマンドを使用して、システムにピア認証ポリシーが存在しないことを確認してください。
最後に、例として示したサービスに適用される宛先ルールがないことを確認してください。既存の宛先ルールの`host:`値をチェックし、一致しないことを確認することで、これを行うことができます。例えば
自動相互TLS
デフォルトでは、IstioはIstioプロキシに移行されたサーバーワークロードを追跡し、クライアントプロキシがそれらのワークロードに自動的に相互TLSトラフィックを送信し、サイドカーのないワークロードにはプレーンテキストトラフィックを送信するように構成します。
したがって、プロキシを持つワークロード間のすべてのトラフィックは、何もせずに相互TLSを使用します。例えば、`httpbin/header`へのリクエストからのレスポンスを見てみましょう。相互TLSを使用する場合、プロキシはバックエンドへのアップストリームリクエストに`X-Forwarded-Client-Cert`ヘッダーを挿入します。そのヘッダーの存在は、相互TLSが使用されている証拠です。例えば
サーバーにサイドカーがない場合、`X-Forwarded-Client-Cert`ヘッダーは存在せず、リクエストがプレーンテキストであることを意味します。
厳格モードでのIstio相互TLSのグローバル有効化
Istioはプロキシとワークロード間のすべてのトラフィックを相互TLSに自動的にアップグレードしますが、ワークロードは依然としてプレーンテキストトラフィックを受信できます。メッシュ全体の非相互TLSトラフィックを防ぐには、相互TLSモードが`STRICT`に設定されたメッシュ全体のピア認証ポリシーを設定します。メッシュ全体のピア認証ポリシーには`selector`を含める必要がなく、**ルート名前空間**に適用する必要があります。例えば
このピア認証ポリシーは、TLSで暗号化されたリクエストのみを受け入れるようにワークロードを構成します。`selector`フィールドの値を指定していないため、このポリシーはメッシュ内のすべてのワークロードに適用されます。
テストコマンドをもう一度実行してください。
プロキシを持たないクライアント`curl.legacy`からプロキシを持つサーバー`httpbin.foo`または`httpbin.bar`へのリクエストを除き、リクエストは依然として成功します。これは、相互TLSが厳密に要求されるようになったため、サイドカーのないワークロードが準拠できないことが原因で予想される動作です。
クリーンアップパート1
セッションで追加されたグローバル認証ポリシーを削除します。
名前空間またはワークロードごとの相互TLSの有効化
名前空間全体のポリシー
特定の名前空間内のすべてのワークロードの相互TLSを変更するには、名前空間全体のポリシーを使用します。ポリシーの仕様はメッシュ全体のポリシーと同じですが、`metadata`の下に適用する名前空間を指定します。例えば、以下のピア認証ポリシーは`foo`名前空間に対して厳格な相互TLSを有効にします。
このポリシーは`foo`名前空間のワークロードのみに適用されるため、サイドカーなしのクライアント(`curl.legacy`)から`httpbin.foo`へのリクエストのみが失敗し始めるはずです。
ワークロードごとの相互TLSの有効化
特定のワークロードに対してピア認証ポリシーを設定するには、`selector`セクションを構成し、目的のワークロードに一致するラベルを指定する必要があります。例えば、以下のピア認証ポリシーは`httpbin.bar`ワークロードに対して厳格な相互TLSを有効にします。
再び、プローブコマンドを実行します。予想通り、`curl.legacy`から`httpbin.bar`へのリクエストは同じ理由で失敗し始めます。
ポートごとに相互TLSの設定を調整するには、`portLevelMtls`セクションを構成する必要があります。例えば、以下のピア認証ポリシーは、ポート`8080`を除くすべてのポートで相互TLSを要求します。
- ピア認証ポリシーのポート値は、コンテナのポートです。
- ポートがサービスにバインドされている場合のみ、`portLevelMtls`を使用できます。そうでない場合は、Istioによって無視されます。
ポリシーの優先順位
ワークロード固有のピア認証ポリシーは、名前空間全体のポリシーよりも優先されます。例えば、`httpbin.foo`ワークロードに対して相互TLSを無効にするポリシーを追加することで、この動作をテストできます。`foo`名前空間内のすべてのサービスに対して相互TLSを有効にする名前空間全体のポリシーを既に作成しており、`curl.legacy`から`httpbin.foo`へのリクエストが失敗していることに注意してください(上記参照)。
`curl.legacy`からのリクエストを再実行すると、成功の戻りコード(200)が再び表示され、サービス固有のポリシーが名前空間全体のポリシーをオーバーライドすることを確認します。
クリーンアップパート2
上記のステップで作成されたポリシーを削除します。
エンドユーザー認証
この機能を試すには、有効なJWTが必要です。JWTは、デモで使用したいJWKSエンドポイントに対応している必要があります。このチュートリアルでは、IstioコードベースからのテストトークンJWTテスト9とJWKSエンドポイント10を使用します。
また、便宜上、イングレスゲートウェイを介して`httpbin.foo`を公開します(詳細については、イングレスタスク11を参照してください)。
ゲートウェイの作成
`INGRESS_PORT`と`INGRESS_HOST`環境変数を設定します。
ゲートウェイを介してテストクエリを実行します。
次に、イングレスゲートウェイに対してエンドユーザーJWTを要求するリクエスト認証ポリシーを追加します。
それを選択するワークロードの名前空間、この場合はイングレスゲートウェイにポリシーを適用します。
承認ヘッダーにトークンを提供すると、その暗黙的なデフォルトの場所であるIstioは公開鍵セット10を使用してトークンを検証し、ベアラートークンが無効な場合はリクエストを拒否します。ただし、トークンがないリクエストは受け入れられます。この動作を確認するには、トークンなしで、無効なトークンで、有効なトークンでリクエストを再試行してください。
JWT検証の他の側面を確認するには、スクリプトgen-jwt.py
15を使用して、異なる発行者、対象者、有効期限などを使用して新しいトークンを生成してテストします。このスクリプトはIstioリポジトリからダウンロードできます。
`key.pem`ファイルも必要です。
JWT認証には60秒のクロックスキューがあります。つまり、JWTトークンは設定された`nbf`よりも60秒早く有効になり、設定された`exp`の後60秒間有効のままになります。
例えば、以下のコマンドは5秒後に期限切れになるトークンを作成します。ご覧のように、Istioは最初にそのトークンを使用してリクエストを正常に認証しますが、65秒後に拒否します。
イングレスゲートウェイ(例:サービス`istio-ingressgateway.istio-system.svc.cluster.local`)にJWTポリシーを追加することもできます。これは、個々のサービスではなく、ゲートウェイにバインドされているすべてのサービスに対してJWTポリシーを定義するために使用されることがよくあります。
有効なトークンの要求
有効なトークンがないリクエストを拒否するには、リクエストプリンシパルがないリクエストに対して`DENY`アクションを指定するルールを持つ承認ポリシーを追加します。これは、以下の例では`notRequestPrincipals: ["*"]`として示されています。リクエストプリンシパルは、有効なJWTトークンが提供されている場合のみ利用できます。そのため、このルールは有効なトークンがないリクエストを拒否します。
トークンなしでリクエストを再試行します。リクエストはエラーコード`403`で失敗します。
パスごとの有効なトークンの要求
ホスト、パス、またはメソッドごとにトークン要件を使用して承認を調整するには、承認ポリシーを変更して`/headers`でのみJWTを要求するようにします。この承認ルールが有効になると、`$INGRESS_HOST:$INGRESS_PORT/headers`へのリクエストはエラーコード`403`で失敗します。他のすべてのパスへのリクエスト(例:`$INGRESS_HOST:$INGRESS_PORT/ip`)は成功します。
クリーンアップパート3
認証ポリシーの削除
承認ポリシーの削除
トークンジェネレータースクリプトとキーファイルの削除
後続のタスクを実行しない場合は、テスト名前空間を削除するだけで、すべてのリソースを削除できます。