OIDC 및 ADFS로 인증

이 페이지에서는 OpenID Connect(OIDC)를 ADFS(Active Directory Federated Services)와 함께 사용하여 GKE On-Prem 사용자 클러스터의 인증을 구성하는 방법을 설명합니다.

인증 흐름에 대한 개요는 인증을 참조하세요.

개요

GKE On-Prem은 OpenID Connect(OIDC)를 사용자 클러스터의 Kubernetes API 서버와 상호작용하는 인증 메커니즘 중 하나로 지원합니다. 클러스터 사용자의 인증 흐름을 자동으로 만들기 위해 GKE On-Prem은 kubectl 플러그인인 OIDC용 Kubectl 플러그인을 제공합니다.

이 연습에서는 일련의 ADFS 관리 마법사를 사용하여 kubectl 명령줄 도구, ADFS 서버, AD 직원 데이터베이스 간의 관계를 구성합니다.

시작하기 전에

이 주제에서는 개발자가 OAuth 2.0OpenID Connect에 익숙하다고 가정합니다. 이 주제에서는 개발자가 OpenID 범위클레임에 익숙하다고 가정합니다.

이 주제는 다음 인프라가 있는 기업에 적용됩니다.

  • 직원 데이터베이스에 Active Directory(AD)를 사용하는 기업
  • Active Directory Federation Services(ADFS) 서버를 실행하는 기업
  • OpenID 제공업체 역할을 수행하는 ADFS 서버

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. 애플리케이션 그룹 > 작업 > 애플리케이션 그룹 추가를 선택합니다.

  3. 서버 애플리케이션을 선택합니다. 원하는 이름과 설명을 입력합니다. Next(다음)를 클릭합니다.

  4. 리디렉션 URI를 입력합니다. 클라이언트 ID가 제공됩니다. 이 방법으로 OpenID 제공업체가 kubectl 애플리케이션을 식별합니다. 나중을 위해 클라이언트 ID를 저장합니다.

  5. 공유 보안 비밀 생성을 선택합니다. kubectl 애플리케이션은 이 보안 비밀을 사용하여 OpenID 제공업체를 인증합니다. 나중을 위해 이 보안 비밀을 저장합니다.

보안 그룹 구성(선택사항)

  1. ADFS 관리에서 신뢰 당사자 트러스트 > 새 신뢰 당사자 트러스트 추가를 선택합니다.

  2. 클레임 인식을 선택하고 시작을 클릭합니다.

  3. 신뢰 당사자에 대한 수동 데이터 입력을 선택합니다.

  4. 표시 이름을 입력합니다.

  5. 다음 두 단계를 건너뜁니다.

  6. 신뢰 당사자 트러스트 식별자를 입력합니다. 제안사항: token-groups-claim

  7. 액세스 제어 정책모두 허용을 선택합니다. 즉, 모든 직원이 보안 그룹 정보를 kubectl oidc과 공유합니다.

  8. 마침을 클릭합니다.

클레임 이름에 LDAP 속성 매핑

  1. ADFS 관리에서 신뢰 당사자 트러스트 > 클레임 발급 정책 수정을 선택합니다.

  2. Send LDAP Attributes as Claims(LDAP 특성을 클레임으로 보내기)를 선택하고 Next(다음)를 클릭합니다.

  3. 클레임 규칙 이름groups를 입력합니다.

  4. 속성 저장소Active Directory를 선택합니다.

  5. 테이블에서 LDAP 속성토큰 그룹 - 정규화된 이름을 선택합니다. 보내는 클레임 유형그룹을 선택합니다.

  6. 마침을 클릭하고 적용을 클릭합니다.

ADFS로 kubectl 등록

관리자 모드에서 PowerShell 창을 열고 다음 명령어를 입력합니다.

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

각 매개변수는 다음과 같습니다.

  • [CLIENT_ID]는 이전에 가져온 kubectl 클라이언트 ID입니다.

  • [SERVER_ROLE_IDENTIFIER]는 이전에 입력한 클레임 식별자입니다. 제안된 식별자는 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: 클라이언트 애플리케이션의 보안 비밀입니다. 필수 필드입니다.
  • usehttpproxy: 클러스터에 역방향 프록시를 배포하여 Connect 에이전트가 사용자 인증을 위해 온프레미스 OIDC 제공업체에 액세스하도록 허용할지 여부를 선택합니다. 값은 "true" 또는 "false" 문자열이어야 합니다. 필수 필드입니다.
  • username: 사용자 이름으로 사용할 JWT 클레임입니다. 기본값은 sub이며 최종 사용자의 고유 식별자로 사용됩니다. OIDC 제공업체에 따라 email 또는 name와 같은 다른 클레임을 선택할 수 있습니다. 하지만 email 이외의 클레임에는 다른 플러그인과 이름 충돌을 방지하기 위해 발급기관 URL이 프리픽스로 추가됩니다.
  • usernameprefix: 기존 이름과 충돌을 방지하기 위해 사용자 이름 클레임에 추가되는 프리픽스입니다. 이 플래그가 제공되지 않고 username이 이메일 이외의 값이면 프리픽스 기본값은 issueruri#입니다. - 값을 사용하여 모든 프리픽스를 중지할 수 있습니다.
  • group: 사용자 그룹으로 사용할 JWT 클레임입니다. 클레임이 있는 경우 문자열 배열이어야 합니다.
  • groupprefix: 기존 이름과 충돌을 방지하기 위해 그룹 클레임에 추가된 프리픽스입니다. 예를 들어 그룹이 foobar이고 프리픽스가 gid-이면 gid-foobar가 됩니다.
  • scopes: 주석으로 구분된 목록으로 OpenID 제공업체에 보낼 추가 범위입니다.
  • extraparams: OpenID 제공업체에 전송할 추가 키-값 매개변수입니다.
  • capath: ID 공급업체의 웹 인증서에 서명한 인증 기관(CA)의 인증서 경로입니다.

    GKE On-Prem 클러스터는 TLS를 사용하여 구성요소 간의 통신을 보호합니다. Kubernetes가 설치 및 노드 부트스트랩 중에 자동으로 클라이언트 인증서를 생성하려면 GKE On-Prem을 CA와 함께 설치해야 합니다.

    기본적으로 GKE On-Prem은 설치 중에 TLS 인증서를 생성하는 새 CA를 만듭니다. 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)를 사용하여 인증된 사용자에게 액세스 권한을 부여할 수 있습니다. 예를 들어 사용자에게 클러스터 보안 비밀에 대한 읽기 전용 액세스 권한을 부여하는 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은 인증 요청과 함께 키-값 쌍을 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은 인증 요청과 함께 키-값 쌍을 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 애플리케이션을 알고 있으며 kubectlopenidallatclaims 범위를 요청할 수 있음을 알고 있습니다.

AD 데이터베이스의 Token-Groups Qualified Names LDAP 속성은 OpenID 제공업체의 groups 클레임에 매핑됩니다. 공급업체는 직원 ID, 발급기관 ID, openid 클레임, groups 클레임이 포함된 토큰을 반환합니다. groups 클레임은 직원이 속한 보안 그룹을 나열합니다.

다음 단계