OIDC と ADFS による認証

このページでは、Active Directory Federated Services(ADFS)で OpenID Connect(OIDC)を使用して、GKE On-Prem ユーザー クラスタの認証を構成する方法について説明します。

認証フローの概要については、認証をご覧ください。

概要

GKE On-Prem は、ユーザー クラスタの Kubernetes API サーバーとやり取りする認証メカニズムの 1 つとして OpenID Connect(OIDC)をサポートしています。クラスタ ユーザーの認証フローを自動化するために、GKE On-Prem では kubectl プラグインである OIDC 用の Kubectl プラグインを提供しています。

この演習では、一連の ADFS 管理ウィザードを使用して、kubectl コマンドライン ツール、ADFS サーバー、AD 従業員データベースの間の関係を構成します。

始める前に

このトピックでは、OAuth 2.0OpenID Connect について理解していることを前提にしています。このトピックでは、OpenID のスコープクレームについて理解していることを前提としています。

このトピックは、次のインフラストラクチャを所有する企業に適用されます。

  • 企業が従業員データベースとして Active Directory(AD)を使用している。
  • 企業が Active Directory フェデレーション サービス(ADFS)サーバーを運用している。
  • ADFS サーバーが OpenID プロバイダとして使用されている。

OIDC 用の Kubectl プラグインのダウンロード

プラグインをダウンロードしてアクセス権限を設定します。

Linux

gsutil cp gs://gke-on-prem-release/oidc-plugin/v1.1alpha/linux_amd64/kubectl-oidc .
chmod +x kubectl-oidc

Windows

gsutil cp gs://gke-on-prem-release/oidc-plugin/v1.1alpha/windows_amd64/kubectl-oidc .

macOS

gsutil cp gs://gke-on-prem-release/oidc-plugin/v1.1alpha/darwin_amd64/kubectl-oidc .
chmod +x kubectl-oidc

プラグインのインストール

プラグインをインストールして、実行可能ファイルを PATH の任意の場所に移動します。実行可能ファイルの名前は kubectl-oidc とする必要があります。詳細は、kubectl プラグインのインストールをご覧ください。

リダイレクト URI の作成

OpenID プロバイダが ID トークンを返すために使用できるリダイレクト URI を指定する必要があります。トークンは OIDC 用の Kubectl プラグインに送られます。このプラグインは、各従業員のローカルマシンで実行され、選択されたポートでリッスンします。この目的に適した 1024 より大きいポート番号を選択します。リダイレクト URI は次のようになります。

http://localhost:[PORT]/callback

ここで、[PORT] はポート番号です。

ADFS の構成

次のセクションでは、GKE On-Prem 用に ADFS を構成する方法について説明します。

リダイレクト URI の設定

  1. ADFS 管理ペインを開きます。

  2. [Application Groups] > [Actions] > [Add an Application Group] の順に選択します。

  3. [Server Application] を選択します。名前と説明を入力します。[Next] をクリックします。

  4. リダイレクト URI を入力します。クライアント ID が付与されます。これにより、OpenID プロバイダは kubectl アプリケーションを識別します。後で使用するため、クライアント ID を保存します。

  5. [Generate a shared secret] を選択します。kubectl アプリケーションはこのシークレットを使用して OpenID プロバイダの認証を行います。後で使用するために Secret を保存します。

セキュリティ グループの構成(省略可)

  1. ADFS Management で、[Relying party trusts] > [Add a new relying party trust] の順に選択します。

  2. [Claims aware] を選択し、[Start] をクリックします。

  3. [Enter data about relying party manually] を選択します。

  4. 表示名を入力します。

  5. 次の 2 つの手順はスキップします。

  6. [Relying party trust identifier] を入力します。例: token-groups-claim

  7. Access control policy には、[Permit everyone] を選択します。これにより、すべての従業員がセキュリティ グループ情報を kubectl oidc と共有することになります。

  8. [Finish] をクリックします。

LDAP 属性のクレーム名へのマッピング

  1. ADFS Management で、[Relying party trusts] > [Edit claim issuance policy] の順に選択します。

  2. [LDAP 属性を要求として送信] をオンにしてから [次へ] をクリックします。

  3. [Claim rule name] に「groups」と入力します。

  4. [Attribute store] で [Active Directory] を選択します。

  5. 表の [LDAP Attribute] で、[Token Groups - Qualified Names] を選択します。[Outgoing Claim Type] で、[groups] を選択します。

  6. [Finish] をクリックし、[Apply] をクリックします。

ADFS への kubectl の登録

管理者モードで PowerShell ウィンドウを開き、次のコマンドを入力します。

Grant-AdfsApplicationPermission `
    -ClientRoleIdentifier "[CLIENT_ID]" `
    -ServerRoleIdentifier [SERVER_ROLE_IDENTIFIER] `
    -ScopeName "allatclaims", "openid"

ここで

  • [CLIENT_ID] は、前の手順で取得した kubectl クライアント ID です。

  • [SERVER_ROLE_IDENTIFIER] は、前に入力したクレーム ID です。提案された ID は token-groups-claim でした。

GKE On-Prem 構成ファイルに oidc 仕様を入力する

インストール中に、gkectl create-config を使用して GKE On-Prem 構成ファイルを生成します。構成には次の oidc 仕様が含まれます。プロバイダに固有の値で、「oidc」を入力します。

oidc:
  issuerurl:
  kubectlredirecturl:
  clientid:
  clientsecret:
  username:
  usernameprefix:
  group:
  groupprefix:
  scopes:
  extraparams:
  usehttpproxy:
  capath:
  • issuerurl: OpenID プロバイダの URL(例: https://example.com/adfs)。OIDC 用の Kubectl プラグインなどのクライアント アプリケーションは、この URL に認可リクエストを送信します。Kubernetes API サーバーは、この URL を使用してトークン検証用の公開鍵を検出します。HTTPS を使用する必要があります。このフィールドは必須です。
  • kubectlredirecturl: OIDC 用の Kubectl プラグインの localhost リダイレクト URL。このクラスタに割り当てられたクライアント ID で使用するには、OpenID プロバイダにリダイレクト URL を登録する必要があります。このフィールドは必須です。
  • clientid: OpenID プロバイダに対して認証リクエストを行う OIDC 用の Kubectl プラグインなどのクライアント アプリケーションの ID。このフィールドは必須です。
  • clientsecret: クライアント アプリケーション用の Secret。このフィールドは必須です。
  • usehttpproxy: ユーザー認証用の Connect Agent がオンプレミスの OIDC プロバイダにアクセスできるようにするため、クラスタにリバース プロキシをデプロイするかどうかを選択します。値は文字列("true" または "false")で指定する必要があります。このフィールドは必須です。
  • username: ユーザー名として使用する JWT クレーム。デフォルトは sub で、これはエンドユーザーの一意の識別子である必要があります。OIDC プロバイダによっては、emailname などの他のクレームを選択できます。ただし、他のプラグインとの競合を避けるため、email 以外のクレームには発行者の URL が先頭に付加されます。
  • usernameprefix: 既存の名前と競合しないように、ユーザー名のクレームの先頭に付加される接頭辞。このフラグが指定されておらず、username がメール以外の値の場合、プレフィックスはデフォルトの issueruri# になります。値 - を使用すると、すべてのプレフィックスの付加を無効にできます。
  • group: ユーザーのグループとして使用する JWT クレーム。クレームが存在する場合、文字列の配列でなければなりません。
  • groupprefix: 既存の名前と競合しないように、グループ クレームの先頭に付加される接頭辞。たとえば、グループ foobar と接頭辞 gid- が指定されている場合、gid-foobar となります。
  • scopes: OpenID プロバイダにカンマ区切りのリストとして送信する追加のスコープ。
  • extraparams: OpenID プロバイダに送信する追加の Key-Value パラメータ。
  • capath: ID プロバイダのウェブ証明書に署名した認証局(CA)の証明書へのパス。

    GKE On-Prem クラスタは TLS を使用してコンポーネント間の通信を保護します。Kubernetes がインストール中およびノードのブートストラップ中にクライアント証明書を自動的に生成するには、GKE On-Prem を CA とともにインストールする必要があります。

    デフォルトでは、GKE On-Prem はインストール時に新しい CA を作成し、TLS 証明書を生成します。CA と生成された証明書は、管理クラスタ内にローカルに保存されます。

例: グループの認証と認可

多くのプロバイダは、ユーザー識別プロパティ(メールやユーザー ID など)をトークンにエンコードします。ただし、これらのプロパティには認証ポリシーに関する潜在的なリスクがあります。

  • ユーザー ID を使用すると、ポリシーの読み取りと監査が困難になることがあります。
  • メールでは、可用性リスク(ユーザーがメインのメールを変更した場合)とセキュリティ リスク(メールを再割り当てできる場合)の両方が発生する可能性があります。

したがって、GID は永続的であり、監査が容易であるため、グループ ポリシーを使用することをおすすめします。

プロバイダが、次のフィールドを含む OpenID トークンを作成したとします。

{
  'iss': 'https://server.example.com'
  'sub': 'u98523-4509823'
  'groupList: ['developers@example.corp', 'us-east1-cluster-admins@example.corp']
  ...
}
このトークン形式では、構成ファイルの oidc 仕様を次のように指定します。
issueruri: 'https://server.example.com'
username: 'sub'
usernameprefix: 'uid-'
group: 'groupList'
groupprefix: 'gid-'
...

ユーザー クラスタを作成すると、Kubernetes のロールベースのアクセス制御(RBAC)を使用して、認証済みユーザーに特権アクセスを付与できます。たとえば、クラスタの Secret への読み取り専用アクセス権を付与する ClusterRole を作成し、認証されたグループにロールをバインドする ClusterRoleBinding リソースを作成できます。

ClusterRole

  apiVersion: rbac.authorization.k8s.io/v1
  kind: ClusterRole
  metadata:
    name: secret-reader
  rules:
  - apiGroups: [""]
    # The resource type for which access is granted
    resources: ["secrets"]
    # The permissions granted by the ClusterRole
    verbs: ["get", "watch", "list"]

ClusterRoleBinding

  apiVersion: rbac.authorization.k8s.io/v1
  kind: ClusterRoleBinding
  metadata:
    name: read-secrets-admins
  subjects:
    # Allows anyone in the "us-east1-cluster-admins" group to
    # read Secrets in any namespace within this cluster.
  - kind: Group
    name: gid-us-east1-cluster-admins # Name is case sensitive
    apiGroup: rbac.authorization.k8s.io
    # Allows this specific user to read Secrets in any
    # namespace within this cluster
  - kind: User
    name: uid-u98523-4509823
    apiGroup: rbac.authorization.k8s.io
  roleRef:
    kind: ClusterRole
    name: secret-reader
    apiGroup: rbac.authorization.k8s.io

サーバー認証局(CA)証明書の作成

ユーザー クラスタの kubeconfig は、そのホストの CA データを certificate-authority-data フィールドに格納します。この値をデコードし、server-ca-cert のようなローカル ファイルに保存する必要があります。

cat [USER_CLUSTER_KUBECONFIG]  | grep certificate-authority-data | awk '{ print $2}' | base64 --decode > server-ca-cert

クライアント認証構成ファイルの生成

OpenID 用のユーザー クラスタを構成して作成した後、ユーザーはクライアント認証構成ファイルを kubectl oidc login に渡すことでクラスタにログインできます。クライアント認証構成ファイルを生成するには、次のコマンドを入力します。

PowerShell

kubectl oidc client-config `
--issuer-uri [ISSUER_URI] `
--redirect-uri [REDIRECT_URI] `
--client-id [CLIENT_ID] `
--client-secret [CLIENT_SECRET] `
--scopes "allatclaims" `
--cluster-name [USER_CLUSTER_NAME] `
--server [CLUSTER_URL] `
--server-ca-file server-ca-cert `
--issuer-ca-file [ADFS_CA_CERT] `
--extra-params "resource=token-groups-claim"
> client-config.yaml
  • [ISSUER_URI] は、発行者の URI です。
  • [REDIRECT_URI] は、リダイレクト URI です。
  • [CLIENT_ID] は、kubectl アプリケーションのクライアント ID です。
  • [CLIENT_SECRET] は、生成されたクライアント シークレットです。
  • [USER_CLUSTER_NAME] は、ユーザー クラスタの名前です。
  • [CLUSTER_URL] は、クラスタの Kubernetes API サーバーの URL です。
  • --server-ca-file は、前のセクションで作成した CA ファイルへのパスを受け入れます。
  • [ADFS_CA_CERT] は、ADFS CA の公開証明書ファイルへのパスです。
  • --extra-param は、認証リクエストを含む Key-Value ペアを OIDC プロバイダに送信します。

Linux

kubectl oidc client-config \
--issuer-uri [ISSUER_URI] \
--redirect-uri [REDIRECT_URI] \
--client-id [CLIENT_ID] \
--client-secret [CLIENT_SECRET] \
--scopes "allatclaims" \
--cluster-name [USER_CLUSTER_NAME] \
--server [CLUSTER_URL] \
--server-ca-file server-ca-cert \
--issuer-ca-file [ADFS_CA_CERT] \
--extra-params "resource=token-groups-claim"
> client-config.yaml
  • [ISSUER_URI] は、発行者の URI です。
  • [REDIRECT_URI] は、リダイレクト URI です。
  • [CLIENT_ID] は、kubectl アプリケーションのクライアント ID です。
  • [CLIENT_SECRET] は、生成されたクライアント シークレットです。
  • [USER_CLUSTER_NAME] は、ユーザー クラスタの名前です。
  • [CLUSTER_URL] は、クラスタの Kubernetes API サーバーの URL です。
  • --server-ca-file は、前のセクションで作成した CA ファイルへのパスを受け入れます。
  • [ADFS_CA_CERT] は、ADFS CA の公開証明書ファイルへのパスです。
  • --extra-param は、認証リクエストを含む Key-Value ペアを OIDC プロバイダに送信します。

このコマンドは、client-config.yaml というクライアント認証ファイルを生成します。このファイルは手動で編集しないでください。ユーザー クラスタに対して認証する必要がある各従業員には、client-config.yaml を付与する必要があります。

OIDC 用 Kubectl プラグインを使用したユーザー クラスタに対する認証

クライアント認証ファイルを使用してユーザー クラスタに対して認証するには、ローカルマシンまたは VM から次の手順を実行します。

  1. client-config.yaml ファイルを使用してプラグインを初期化します。

    kubectl oidc login --clientconfig-file=client-config.yaml --user [NAME] \
    --kubeconfig [KUBECONFIG_OUTPUT_PATH]
    

    ここで

    • [NAME] は、選択したユーザー名です。
    • [KUBECONFIG_OUTPUT_PATH] は、認証情報が保存されている kubeconfig ファイルの出力場所です。

    kubectl oidc login は、ユーザーまたは従業員が認証情報を入力できるブラウザを起動します。

    現在指定されている kubeconfig ファイルには、kubectl でユーザー クラスタ上の Kubernetes API サーバーに認証するために使用される ID トークンが含まれています。

  2. これで認証されます。認証に成功したかどうかを確認するには、任意の kubectl コマンドを入力します。例:

    kubectl get nodes --kubeconfig [KUBECONFIG_OUTPUT_PATH]
    

まとめ

企業では、OpenID プロバイダとして機能する ADFS サーバーを実行しています。OpenID プロバイダは、kubectl アプリケーションを認識し、kubectlopenid スコープと allatclaims スコープをリクエストできることを認識しています。

AD データベースの Token-Groups Qualified Names LDAP 属性が、OpenID プロバイダの groups クレームにマッピングされます。プロバイダは、従業員 ID、発行者 ID、openid クレーム、groups クレームを含むトークンを返します。groups クレームでは、従業員が属するセキュリティ グループが一覧表示されます。

次のステップ