Anthos Service Mesh のユーザー認証は、デプロイされたワークロードへのブラウザベースのエンドユーザー認証とアクセス制御のための統合ソリューションです。このソリューションにより、ユーザー認証の既存の ID プロバイダ(IDP)と統合できます。アクセス管理には、Istio API と認証ポリシーが使用されます。これは、Istio JSON Web Token(JWT)認証に代わる、ユーザー フレンドリーな代替手段です。
代表的な使用例は、従業員がウェブブラウザからアクセスできるように、組織が Anthos Service Mesh を使用して、ウェブ アプリケーションをホストする場合です。また、組織では既存の ID プロバイダを使用してユーザー ID を管理する必要があります。Anthos Service Mesh のユーザー認証では、ユーザーは標準のウェブベースの OpenID Connect(OIDC)ログインと同意フローを使用して簡単に認証できます。ユーザーが認証されると、Anthos Service Mesh によって Istio の認証ポリシーが適用されます。認証が正常に完了すると、安全な認証情報形式で ID がワークロードに送信されます。
仕組み
Anthos Service Mesh のユーザー認証では、新しいコンポーネント authservice
が導入されています。このコンポーネントは、すべての受信認証リクエストをインターセプトする外部承認サービスとして Envoy ベースの Ingress と統合します。authservice
は OIDC プロトコルのクライアント側を実装し、ユーザーがブラウザからアプリケーションにアクセスできるようにします。この際、ユーザーはインタラクティブな認証および同意フローを完了して、有効期間の短いセッションを確立します。authservice
は、OIDC 認証サーバーとして機能できる ID プロバイダと統合するための業界標準プロトコルを実装します。ユーザーが認証されると、主要な情報は RCToken
に JWT 形式でカプセル化され、authservice
によって署名されてから Ingress の Istio 認証レイヤに転送されます。このモデルは、メッシュへのトラフィックの境界アクセス制御を提供します。ユーザーがリソースへのアクセスを承認されている場合は、この RCToken もマイクロサービスに転送されるため、主要な情報を取得してきめ細かいアクセス制御を行えます。
次の図は、メッシュ内の authservice
の場所と、Ingress、ワークロード、ユーザーのブラウザ、既存の IDP など、メッシュの他の部分との関連を示しています。
管理者は、Anthos Service Mesh インストール時にアドオンとして authservice
をインストールできます。authservice
をインストールすると、UserAuth
カスタム リソースで定義されている OIDC エンドポイント構成と他の関連設定が読み取られます。管理者は、Anthos Service Mesh ExternalAuthorization
API を使用して、auth_server
を Ingress のフィルタとして構成できます。
ユーザー認証サービスをインストールする
次の手順では、authservice
の構成方法について説明します。
前提条件
次の手順に沿って、前提条件を満たしていることを確認してください。
ユーザー認証オーバーレイを使用してインストールをカスタマイズする
ユーザー認証サービスをインストールするには、ASM のインストールをカスタマイズして、メッシュレベルの外部認証プロバイダを追加する必要があります。
サンプルのユーザー認証オーバーレイを取得し、メッシュにカスタマイズがある場合は更新します。このオーバーレイ ファイルをソース コントロール内で管理することをおすすめします。
curl https://raw.githubusercontent.com/GoogleCloudPlatform/asm-user-auth/release-0.1/overlay/user-auth-overlay.yaml > user-auth-overlay.yaml
オーバーレイを使用して ASM をインストールするの手順に沿って、Google 提供のスクリプトを使用してユーザー認証オーバーレイで Anthos Service Mesh をインストールします。次に例を示します。
/install_asm \ --project_id "PROJECT_ID" \ --cluster_name "CLUSTER_NAME" \ --cluster_location "CLUSTER_LOCATION" \ --mode install \ --enable_all \ --custom_overlay user-auth-overlay.yaml
ユーザー認証の
kpt
パッケージがAuthorizationPolicy
を作成し、pkg/ext-authz.yaml
で指定された外部認証プロバイダを参照します。
OIDC クライアントの構成を準備する
次の手順で OIDC クライアント構成を設定します。このガイドでは Google を IDP として使用しますが、OIDC 認証をサポートする任意の IDP を使用できます。
Google Cloud コンソールで、[API とサービス] > [認証情報] に移動します。
[認証情報を作成] に移動し、[OAuth クライアント ID] を選択します。必要に応じて、[OAuth 同意画面] オプションを設定し、次のオプションを構成します。
- [アプリケーションの種類] を [ウェブ アプリケーション] に設定します。
- [承認済みのリダイレクト URI] を
https://localhost:8443/_gcp_anthos_callback
に設定します。
最後に [保存] をクリックします。
また、後で使用できるように、クライアント ID とクライアント シークレットを保存します。
export OIDC_CLIENT_ID='<your-client-id>' export OIDC_CLIENT_SECRET='<your-client-secret>' export OIDC_ISSUER_URI='https://accounts.google.com'
kpt
パッケージを入手する
公開リポジトリから推奨の authservice
構成をインストールするには、次の手順を行います。これらのコマンドは、最新の authservice
コンテナを取得し、asm-user-auth
名前空間の Pod として起動します。また、すべてのリクエストをインターセプトするように Ingress を構成します。
kpt パッケージを取得します。
kpt pkg get https://github.com/GoogleCloudPlatform/asm-user-auth@release-0.1 . cd asm-user-auth/
Ingress ゲートウェイのリダイレクト URL とシークレットを設定する
OAuth2
には、HTTPS で保護されたエンドポイントでホストされているリダイレクト URL が必要です。これらのコマンドはサンプル用途であり、Istio Ingress ゲートウェイの自己署名証明書を生成することで簡単に設定できます。本番環境デプロイでは、自己署名証明書は使用しません。
自己署名証明書を生成します。
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \ -days 365 -nodes -subj '/CN=localhost'
HTTPS トラフィックをホストする Ingress ゲートウェイのシークレットを作成します。
kubectl create -n istio-system secret tls userauth-tls-cert --key=key.pem \ --cert=cert.pem
暗号鍵と署名鍵を適用する
authservice
が正しく動作するには、2 つの鍵セットが必要です。1 つ目は、暗号化と復号の対称鍵です。この鍵は、セッションの状態を Cookie として設定する前に、セッションの暗号化に使用します。
2 つ目は、公開鍵/秘密鍵のペアです。この鍵は、RCToken として JWT 形式で認証されたユーザー情報に署名するために使用されます。このペアの公開鍵は、サイドカーが JWT の検証に使用できる事前定義されたエンドポイントで公開されます。
ユーザー認証の kpt
パッケージには、簡単に設定できるように 2 つのサンプルキーが含まれています。ただし、任意の鍵管理システムを使用して、これらの鍵を生成することもできます。
鍵を生成した後、同じ形式で鍵データを入力します。
cat ./samples/rctoken_signing_key.json { "keys":[ { "kty":"RSA", "kid":"rsa-signing-key", "K":"YOUR_KEY", # k contains a Base64 encoded PEM format RSA signing key. "useAfter": 1612813735, # unix timestamp } ] }
cat ./samples/cookie_encryption_key.json { "keys":[ { "kty":"oct", "kid":"key-0", "K":"YOUR_KEY", "useAfter": 1612813735 } ] }
authservice
が独自のファイル システムにマウントする Kubernetes Secret を作成します。kubectl create namespace asm-user-auth kubectl label namespace asm-user-auth istio-injection=enabled istio.io/rev=default --overwrite kubectl create secret generic secret-key \ --from-file="session_cookie.key"="./samples/cookie_encryption_key.json" \ --from-file="rctoken.key"="./samples/rctoken_signing_key.json" \ --namespace=asm-user-auth
ユーザー認証サービスをデプロイする
次のコマンドは、ユーザー認証サービスとデプロイを asm-user-auth
名前空間に作成します。
oauth
変数を設定します。kpt cfg set pkg anthos.servicemesh.user-auth.oidc.clientID ${OIDC_CLIENT_ID} kpt cfg set pkg anthos.servicemesh.user-auth.oidc.clientSecret ${OIDC_CLIENT_SECRET} kpt cfg set pkg anthos.servicemesh.user-auth.oidc.issuerURI ${OIDC_ISSUER_URI}
kpt
パッケージを適用します。kubectl apply -f ./pkg/asm_user_auth_config_v1alpha1.yaml kubectl apply -f ./pkg
authservice
は UserAuthConfig
CRD を使用してエンドユーザー認証を行います。UserAuthConfig
は実行時に構成可能で、authservice
の動作を変更し、任意の OIDC 認証サーバーのエンドポイントで構成するように更新できます。次のフィールドが含まれています。
cat pkg/user_auth_config.yaml
apiVersion: security.anthos.io/v1alpha1
kind: UserAuthConfig
metadata:
name: auth-config
namespace: user-auth
spec:
authentication:
- oidc:
clientID: "${OIDC_CLIENT_ID}"
clientSecret: "${OIDC_CLIENT_SECRET}"
issuerURI: "${OIDC_ISSUER_URI}"
redirectURIHost: ""
redirectURIPath: "/_gcp_anthos_callback"
outputJWTAudience: "test_audience"
user_auth_config.yaml
フィールドの詳細については、ユーザー認証構成の詳細をご覧ください。
インストール後のタスクを行う
前述のインストール手順が完了した後は、以下のタスクが必要になります。
アプリケーションのユーザー認証を有効にする
このセクションでは、Online Boutique のサンプル アプリケーションを例に使い、ユーザー認証を有効にする方法を説明します。
Anthos Service Mesh ユーザー認証では、CUSTOM
タイプの認証ポリシーを使用して OIDC フローをトリガーします。
また、インストール プロセスでは、前記の手順で作成した TLS 証明書 userauth-tls-cert
を使用して、HTTPS トラフィックを処理する Istio ゲートウェイが作成されます。pkg/gateway.yaml
の構成は次のとおりです。
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: userauth
namespace: asm-user-auth
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: https
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: userauth-tls-cert
---
# This ensures the OIDC endpoint has at least some route defined.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: userauth-oidc
namespace: asm-user-auth
spec:
gateways:
- userauth
hosts:
- '*'
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /_gcp_anthos_callback
name: user-auth-route
route:
- destination:
host: authservice
port:
number: 10004
Online Boutique アプリケーションを更新して、このゲートウェイを使って HTTPS トラフィックを処理し、ポート転送を使用してローカルでアプリケーションにアクセスします。
kubectl apply -f./samples/boutique-route.yaml -n demo kubectl port-forward service/istio-ingressgateway 8443:443 -n istio-system
ポート 8443 の Ingress ゲートウェイが
localhost
に転送され、アプリケーションはローカルでアクセス可能になります。Online Boutique サンプル アプリケーションが
https://localhost:8443/
でアクセスできることを確認します。
ユーザー認証を確認する
続いて、Online Boutique のアプリケーション サービスで、エンドユーザーが Google アカウントを使用してログインする必要があります。
https://localhost:8443/
にアクセスして、OIDC ログインページが表示されることを確認します。ログイン後、[次へ] をクリックして、Online Boutique のホームページにリダイレクトすることを確認します。
認証ポリシーを構成する
前の手順で構成を完了すると、各ユーザーはウェブベースの認証フローにリダイレクトされます。フローが完了すると、authservice
によって JWT 形式の RCToken
が生成されます。これを使用して、認証されたユーザー情報が転送されます。
Ingress で Istio の認証ポリシーを追加して、認証されたユーザーごとに認証チェックが行われるようにします。
kubectl apply -f ./samples/rctoken-authz.yaml
rctoken-authz.yaml
ファイルは、Ingress ゲートウェイを構成して authservice が発行した RC トークンを検証し、JWT にオーディエンスや発行者などの目的のフィールドが含まれている場合にのみ承認します。次の認証ポリシーの例をご覧ください。
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: require-rc-token namespace: istio-system spec: selector: matchLabels: istio: ingressgateway jwtRules: - issuer: "authservice.asm-user-auth.svc.cluster.local" audiences: - "test_audience" jwksUri: "http://authservice.asm-user-auth.svc.cluster.local:10004/_gcp_user_auth/jwks" fromHeaders: - name: X-ASM-RCTOKEN forwardOriginalToken: true --- apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: require-rc-token namespace: istio-system spec: selector: matchLabels: istio: ingressgateway action: ALLOW rules: - when: - key: request.auth.claims[iss] values: - authservice.asm-user-auth.svc.cluster.local - key: request.auth.claims[aud] values: - test_audience
環境固有の設定を構成する
前のステップでは、簡単にセットアップするため、localhost
と自己署名 HTTPS 証明書を使用しました。本番環境用に使用する場合は、example.com
などの実際のドメインを使用します。
さらに、UserAuthConfig
CRD で構成された tokenEndpoint
と authorizationEndpoint
に、VirtualService
で構成されているルートが設定されていることを確認します。前回のインストール手順では、asm-user-auth/userauth-oidc
VirtualService
に設定されています。
鍵の管理とローテーションを行う
authservice
で使用されるキーのセットは 2 つあります。各鍵を個別にローテーションできます。ただし、鍵をローテーションする前に、ローテーションの仕組みを理解しておくことが重要です。
どちらの鍵も JSON 形式です。useAfter
フィールドには、鍵の使用が開始されると考えられる期間のタイムスタンプを指定します。鍵のローテーション中は、JSON に古い鍵と新しい鍵の両方を含める必要があります。たとえば、次の例では、new-key
はタイムスタンプ 1712813735
の後にのみ使用されます。
{
"keys":[
{
"kty":"RSA",
"kid":"old-key",
"K":"...", # k contains a Base64 encoded PEM format RSA signing key.
"useAfter": 1612813735, # unix timestamp
}
{
"kty":"RSA",
"kid":"new-key",
"K":"...", # k contains a Base64 encoded PEM format RSA signing key.
"useAfter": 1712813735, # unix timestamp
}
]
}
Anthos Service Mesh では、ブラウザの Cookie に保存されるセッション データを暗号化するために対称鍵を使用します。既存のセッションの有効性を確保するため、authservice
は鍵セット内のすべての鍵で復号を試みます。ローテーション時には、authservice
は新しいセッションの暗号化に新しい鍵を使用し、引き続き古い鍵による復号を試みます。
公開鍵/秘密鍵ペアは、RCToken
の署名に使用されます。公開鍵は、JWT 検証のために istiod
によってサイドカーに送信されます。authservice
が新しい秘密鍵を使用して RCToken
に署名する前に、サイドカーが新しい公開鍵を受け取ることが重要です。この目的を達成するため、authservice
は、鍵が追加された直後に公開鍵の公開を開始します。ただし、その鍵を使用して RCToken
に署名するまではかなりの時間待機します。
要約すると、鍵のローテーションを行うときは、次のことをおすすめします。
- 定期的に、または必要に応じて、鍵のローテーションを実行します。
- JSON 形式で、現在の鍵と新しい鍵の両方を指定します。新しい鍵は、将来のタイムスタンプに関連付ける必要があります。タイムスタンプは現在の時刻の少なくとも数時間前に指定することをおすすめします。
- 新しい鍵が使用された後でもサービスが正常であるかをモニタリングし確認します。新しい鍵が使用されてから 1 日以上待って、次の手順に進みます。
- JSON エントリから古い鍵を削除します。今後それらの鍵は不要です。
ユーザー認証構成の詳細
次の表に、CRD の各フィールドの説明を示します。
フィールド名 | 説明 |
---|---|
authentication.oidc |
このセクションには、OIDC エンドポイントの構成と、OIDC フローで使用されるパラメータが含まれます。 |
authentication.oidc.certificateAuthorityData |
これは、OIDC 認証サーバーのドメインの SSL 証明書です。 |
authentication.oidc.clientID |
OIDC 認証フローに使用する OAuth クライアント ID。 |
authentication.oidc.clientSecret |
OIDC 認証フローに使用する OAuth クライアント シークレット。 |
authentication.oidc.issuerURI |
出力 RCToken の発行者として使用する URI。 |
authentication.oidc.redirectURIHost |
OAuth 終了 URI に使用するホスト。空白のままにすると、ターゲット URL からのホストが使用され、リダイレクト URI が動的に構成されます。 この値は、より高いレベルのドメインでユーザー認証 SSO セッションが必要な場合に使用できます。たとえば、profile.example.com/ と admin.example.com/ の間で SSO を有効にするには、この値を example.com に設定します。これにより、すべてのサブドメイン間で共有されるユーザー認証セッションを example.com で確立できます。注: 同じメッシュから複数のドメイン(example1.com と example2.com)が提供されている場合、この機能は使用できないため、空白のままにすることをおすすめします。 |
authentication.oidc.redirectURIPath |
「authservice」が OAuth フローを終了するエンドポイントのパス。authentication.oidc.clientID の承認サーバーで、この URI パスとホストを承認済みのリダイレクト URI として登録する必要があります。また、この URI は、「authservice」が有効になっている同じサービス メッシュと Ingress から提供される必要があります。 |
authentication.oidc.scopes |
認証リクエストでリクエストする必要がある OAuth スコープ。 |
authentication.oidc.groupsClaim |
「idtoken」にグループ クレームが含まれている場合は、このフィールドを使用して名前を指定します。指定すると、サービスは、このリクエストのデータを出力 RCToken の「groups」クレームに渡します。 |
authentication.outputJWTAudience |
「authservice」によって生成された RCToken の対象デバイス。サイドカーは、この対象デバイス値に対して受信 RCToken を検証できます。 |
マルチクラスタ デプロイ
Anthos Service Mesh のユーザー認証では、マルチクラスタのデプロイをサポートしています。前記のように、各クラスタにユーザー認証をデプロイする必要があります。UserAuth カスタム リソース、OIDC クライアント シークレット、暗号鍵などのユーザー認証構成は、すべて各クラスタに複製する必要があります。
デフォルトでは、Ingress ゲートウェイはいずれかの authservice
インスタンスへの認証リクエストを負荷分散します。宛先ルールを使用すると、同じクラスタ内の authservice
にリクエストを送信し、他のクラスタの authservice
にのみフェイル オーバーするように Ingress ゲートウェイを構成できます。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: authservice-fail-over
namespace: asm-user-auth
spec:
host: authservice.asm-user-auth.svc.cluster.local
trafficPolicy:
loadBalancer:
localityLbSetting:
enabled: true
failover:
- from: us-east
to: us-west
- from: us-west
to: us-east
他の構成と同様に、各クラスタで構成する必要があります。
よくある質問
ユーザー認証を有効にした Anthos Service Mesh をアップグレードするにはどうすればよいですか?
Anthos Service Mesh のアップグレード プロセスに従って、コマンドラインで
user-auth.yaml
オーバーレイ ファイルをinstall_asm
に指定します。