Infograb logo
OAuth2 및 OIDC 인증

이 가이드는 OpenID Connect (OIDC로도 알려짐)를 사용하여 SSO 공급자를 구성하여 특정 사용자 그룹에 Teleport 자격 증명을 발급하는 방법을 설명합니다. 역할 기반 접근 제어 (RBAC)와 결합하여 OIDC는 Teleport 관리자가 다음과 같은 정책을 정의할 수 있도록 합니다:

  • "DBA" 그룹의 구성원만 PostgreSQL 데이터베이스에 연결할 수 있습니다.
  • 개발자는 운영 서버에 SSH로 접속할 수 없습니다.

전제 조건

  • 그룹/역할에 할당된 사용자가 있는 SSO/IdP에 대한 관리자 접근 권한.
  • oidc 리소스를 유지할 수 있는 권한이 있는 Teleport 역할. 이 권한은 기본 editor 역할에서 사용 가능합니다.
  • 실행 중인 Teleport 클러스터. Teleport를 시작하려면 가입하여 무료 평가판을 이용해 보십시오.

  • tctl 관리자 도구 및 tsh 클라이언트 도구.

    tctltsh 다운로드에 대한 지침은 설치 를 방문하십시오.

  • 연결이 가능한지 확인하기 위해 tsh login 으로 로그인한 다음, 현재 자격 증명을 사용하여 tctl 명령어를 실행할 수 있는지 확인하십시오. 예를 들어:
    tsh login --proxy=teleport.example.com --user=email@example.com
    tctl status

    클러스터 teleport.example.com

    버전 17.0.0-dev

    CA 핀 sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

    클러스터에 연결할 수 있고 tctl status 명령어를 실행할 수 있다면, 현재 자격 증명을 사용하여 워크스테이션에서 후속 tctl 명령어를 실행할 수 있습니다.
    자신의 Teleport 클러스터를 호스팅하는 경우, Teleport Auth Service를 호스팅하는 컴퓨터에서 전체 권한으로 tctl 명령어를 실행할 수도 있습니다.
  • 사용자의 세션 최대 연령을 제어하여 다시 인증하도록 강제할 경우, Teleport 클러스터는 버전 13.3.7 이상이어야 합니다.

ID 공급자

사용할 외부 ID 공급자에 Teleport를 등록하고 client_idclient_secret 을 얻습니다. 이 정보는 ID 공급자 웹사이트에 문서화되어 있어야 합니다. 다음은 몇 가지 링크입니다:

Google Workspace

Google Workspace의 경우 Google Workspace와 Teleport 인증을 참조하세요.

ID 공급자에서 관련 정보를 저장하세요. 이 가이드를 따르기 쉽게 하기 위해 이곳에 Client ID를 추가하면 아래의 예제 명령에 포함됩니다:

Client ID: <CLIENT-ID>

OIDC 리디렉션 URL

OIDC는 인증이 완료된 후 Teleport로 제어를 반환하기 위해 HTTP 리디렉션을 사용합니다. 리디렉션 URL은 Teleport 관리자가 미리 선택해야 합니다.

Teleport에서 OIDC 인증의 리디렉션 URL은 mytenant.teleport.sh/v1/webapi/oidc/callback 입니다. mytenant.teleport.sh 를 귀하의 Teleport Cloud 테넌트 또는 Proxy Service 주소로 변경하세요.

OIDC 커넥터 구성

다음 단계는 Teleport에 OIDC 커넥터를 추가하는 것입니다. 커넥터는 tctl 리소스 명령이나 Teleport 웹 UI를 사용하여 생성, 테스트 및 추가 또는 제거됩니다.

작업 공간에서 client-secret.txt 라는 파일을 만들고, 그 안에는 오직 귀하의 클라이언트 비밀만 포함시킵니다.

새 커넥터를 만들기 위해 tctl sso configure 를 사용하십시오. 다음 예시는 oidc-connector.yaml 이라는 YAML 형식의 커넥터 리소스 파일을 만듭니다:

tctl sso configure oidc --name <CONNECTOR-NAME> \ --issuer-url <PATH-TO-PROVIDER> \ --id <CLIENT-ID> \ --secret $(cat client-secret.txt) \ --claims-to-roles <CLAIM-KEY>,<CLAIM-VALUE>,access \ --claims-to-roles <CLAIM-KEY>,<CLAIM-VALUE>,editor > oidc-connector.yaml
  • --name : 일반적으로 IdP의 이름으로, 이 방식으로 Teleport에서 커넥터가 식별됩니다.
  • --issuer-url : IdP의 OIDC 구성 엔드포인트에 대한 기본 경로로, .well-known/openid-configuration 을 제외합니다. 예를 들어, 엔드포인트가 https://example.com/.well-known/openid-configuration 인 경우, https://example.com 을 사용합니다.
  • --id : IdP에서 정의된 클라이언트 ID입니다. ID 공급자에 따라 자유롭게 정의할 수 있을 수도 있고 (예: teleport ), 할당된 문자열일 수도 있습니다.
  • --secret : IdP에서 이 클라이언트를 인증하기 위해 제공하는 클라이언트 토큰/비밀입니다.
  • --claims-to-roles : OIDC 클레임/값과 Teleport 역할을 연결하는 매핑입니다.

보다 자세한 정보와 사용 가능한 모든 플래그는 Teleport CLI 참조 페이지의 tctl sso configure oidc 섹션을 참조하세요.

생성된 파일은 아래 예제와 비슷하게 보일 것입니다. 이 커넥터는 ID 공급자로부터 <CLAIM-KEY> 범위를 요청하고, 해당 키의 값에 따라 access 또는 editor 역할로 맵핑합니다:

kind: oidc
metadata:
  name: oidc_connector
spec:
  claims_to_roles:
  - claim: groups
    roles:
    - access
    value: users
  - claim: groups
    roles:
    - editor
    value: admins
  client_id: <CLIENT-NAME>
  client_secret: <CLIENT-SECRET>
  issuer_url: https://idp.example.com/
  redirect_url: https://mytenant.teleport.sh:443/v1/webapi/oidc/callback
  max_age: 24h
  client_redirect_settings:
    # HTTPS 클라이언트 리디렉션 URL에 허용되는 호스트 이름 목록
    # 정규식 패턴일 수 있음
    allowed_https_hostnames:
      - remote.machine
      - '*.app.github.dev'
      - '^\d+-[a-zA-Z0-9]+\.foo.internal$'
    # HTTP 또는 HTTPS 클라이언트 리디렉션 URL에 허용되는 CIDR 목록
    insecure_allowed_cidr_ranges:
      - '192.168.1.0/24'
      - '2001:db8::/96'
version: v3

다음 예제는 Keycloak을 ID 공급자로 사용하여 생성되었습니다. Keycloak은 keycloak.example.com 에서 제공되며, Teleport Proxy Service는 teleport.example.com 에서 대기하고 있습니다. Keycloak에서 클라이언트 이름은 teleport 입니다. teleport-dedicated 클라이언트 범위 아래 "그룹 구성원" 매퍼를 추가했습니다:

kind: oidc
metadata:
  name: keycloak
spec:
  claims_to_roles:
    - claim: groups
      roles:
        - access
      value: /users
    - claim: groups
      roles:
        - editor
      value: /admins
  client_id: teleport
  client_secret: abc123...
  issuer_url: https://keycloak.example.com/realms/master
  redirect_url: https://teleport.example.com:443/v1/webapi/oidc/callback
version: v3

커넥터를 클러스터에 적용하기 전에 올바르게 구성되었는지 테스트할 수 있습니다:

cat oidc-connector | tctl sso test

이 명령은 웹 브라우저를 열고 ID 공급자를 통해 Teleport 클러스터에 로그인하려고 시도합니다. 실패할 경우 이 명령의 출력에서 문제 해결 세부 정보를 검토하세요.

Tip

CLI 출력의 "[OIDC] Claims" 섹션은 IdP에서 제공한 사용자에 대한 모든 세부 정보를 제공합니다. 이는 사용자 속성을 계산하는 데 실패했습니다.와 같은 오류를 문제 해결하는 좋은 시작점입니다.

테스트가 성공한 후, 커넥터를 만드세요:

tctl create -f oidc-connector.yaml

선택 사항: ACR 값

Teleport는 OIDC 공급자로부터 인증 코드 획득 시 인증 컨텍스트 클래스 참조(ACR) 값을 전송하는 것을 지원합니다. 기본적으로 ACR 값은 설정되지 않습니다. 그러나 acr_values 필드가 설정된 경우, Teleport는 acr 클레임에서 동일한 값을 수신할 것으로 기대하며, 그렇지 않을 경우 콜백을 유효하지 않은 것으로 간주합니다.

또한, Teleport는 OIDC 구성에서 provider 필드를 설정하여 공급자별 ACR 값 처리를 지원합니다. 현재로서는 NetIQ에 대한 기본 지원만 제공됩니다.

ACR 값과 공급자별 처리를 사용하는 예시는 아래와 같습니다:

# ACR 값을 사용하는 예제 커넥터
kind: oidc
version: v2
metadata:
  name: "oidc-connector"
spec:
  issuer_url: "https://oidc.example.com"
  client_id: "xxxxxxxxxxxxxxxxxxxxxxx.example.com"
  client_secret: "zzzzzzzzzzzzzzzzzzzzzzzz"
  redirect_url: "https://mytenant.teleport.sh/v1/webapi/oidc/callback"
  display: "Example로 로그인"
  acr_values: "foo/bar"
  provider: netiq
  scope: ["group"]
  claims_to_roles:
    - claim: "group"
      value: "editor"
      roles: ["editor"]
    - claim: "group"
      value: "user"
      roles: ["access"]

선택 사항: 최대 연령

Teleport는 버전 13.3.7부터 사용자의 세션 최대 연령을 제어하기 위해 max_age 필드를 설정하는 것을 지원합니다. 기본적으로 max_age 는 설정되지 않으며, 이는 사용자가 OIDC를 사용하여 인증한 후 공급자가 강제로 재인증하도록 요청하지 않는 한 재인증할 필요가 없음을 의미합니다. 사용자가 더 자주 재인증하도록 강제하기 위해 이 값을 시간으로 설정할 수 있습니다. max_age 가 0초로 설정되면, 사용자는 Teleport로 인증할 때마다 OIDC 공급자를 통해 재인증해야 합니다.

지정된 기간은 정수 초 단위여야 합니다. 24h1440s 와 동일하므로 작동하지만, 60s500ms 는 60.5초이기 때문에 허용되지 않습니다.

# OIDC yaml의 추가 부분은 제거되었습니다.
spec:
  max_age: 24h

모든 OIDC 공급자가 max_age 설정을 지원하는 것은 아닙니다. Google과 GitLab은 모두 지원하지 않는 것으로 알려져 있으며, max_age 필드가 설정된 경우 해당 공급자로의 인증은 작동하지 않습니다.

선택 사항: 프롬프트

OIDC 프로토콜에 따라 End-User의 재인증 및 동의를 위한 인증 서버 프롬프트를 설정합니다. prompt 값이 설정되지 않으면, Teleport는 기본값으로 select_account 를 사용합니다.

# OIDC yaml의 추가 부분은 제거되었습니다.
spec:
  # https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest 에서 정의된 유효한 값
  # none: 인증 서버는 인증 또는 동의 사용자 인터페이스 페이지를 표시하지 않아야 합니다.
  # select_account: 인증 서버는 End-User에게 사용자 계정을 선택하도록 요청해야 합니다.
  # login: 인증 서버는 End-User에게 재인증을 요청해야 합니다.
  # consent: 인증 서버는 정보를 클라이언트에게 반환하기 전에 End-User에게 동의를 요청해야 합니다.
  prompt: "login"

선택 사항: 리디렉션 URL 및 타임아웃

리디렉션 URL은 모든 사용자가 접근할 수 있어야 하며, 리디렉션 타임아웃은 선택 사항입니다.

# OIDC yaml의 추가 부분은 제거되었습니다.
spec:
  redirect_url: https://<cluster-url>.example.com:3080/v1/webapi/oidc/callback
  # 선택적 리디렉션 타임아웃.
  # redirect_timeout: 90s

선택 사항: 이메일 검증 비활성화

기본적으로, Teleport는 email_verified 주장을 검증하며, 검증되지 않은 이메일 주소로 로그인하려는 사용자는 로그인할 수 없습니다:

ERROR: SSO 흐름 실패.
신원 공급자 콜백이 오류로 실패했습니다: OIDC 공급자가 이메일을 검증하지 않았습니다.
        이메일이 OIDC 공급자에 의해 검증되지 않았습니다.

테스트 및 기타 목적을 위해, OIDC 커넥터에서 allow_unverified_email 을 활성화하여 이 동작을 선택 해제할 수 있습니다. 이 옵션은 시스템의 전체 보안을 약화시키므로 활성화를 권장하지 않습니다.

kind: oidc
version: v2
metadata:
  name: connector
spec:
  allow_unverified_email: true

선택 사항: 사용자 이름으로 사용할 주석 지정

기본적으로, Teleport는 사용자의 이메일을 Teleport 사용자 이름으로 사용합니다.

대신 사용해야 할 주장을 지정하기 위해 username_claim 을 정의할 수 있습니다:

kind: oidc
version: v2
metadata:
  name: connector
spec:
  # 사용자의 Teleport 사용자 이름으로 `preferred_username` 주장을 사용합니다.
  username_claim: preferred_username

기본 OIDC 인증 활성화

Teleport를 로컬 사용자 데이터베이스 대신 OIDC 인증을 기본값으로 사용하도록 구성합니다.

cluster_auth_preference 리소스를 편집합니다:

tctl edit cap

편집기에서 파일에 다음 내용이 포함되어 있는지 확인합니다:

kind: cluster_auth_preference
metadata:
  name: cluster-auth-preference
spec:    
  type: oidc
version: v2

문제 해결

SSO 구성 문제 해결은 어려울 수 있습니다. 일반적으로 Teleport 관리자는 다음을 수행할 수 있어야 합니다:

  • SSO 공급자가 Teleport에 내보내고 전달하는 SAML/OIDC 클레임 및 값이 무엇인지 확인할 수 있어야 합니다.
  • Teleport가 수신한 클레임을 커넥터에 정의된 역할 매핑으로 어떻게 매핑하는지 확인할 수 있어야 합니다.
  • 자체 호스팅된 Teleport Enterprise 클러스터의 경우, Teleport 프록시 서비스와 SSO 공급자 모두에 대해 HTTP/TLS 인증서가 올바르게 구성되어 있는지 확인해야 합니다.

작동하지 않는 경우, 다음을 권장합니다:

  • 커넥터 정의에서 호스트 이름, 토큰 및 TCP 포트를 다시 확인하십시오.

웹 UI 사용하기

"접근 거부" 또는 다른 로그인 오류가 발생하면 가장 먼저 확인할 곳은 감사 로그입니다. 관리 영역 아래에서 Teleport 웹 UI의 활동 탭 내에서 접근할 수 있습니다.

역할 clusteradmin 이 설정되지 않아 사용자 접근이 거부된 예시:

{
  "code": "T1001W",
  "error": "role clusteradmin is not found",
  "event": "user.login",
  "message": "Failed to calculate user attributes.\n\trole clusteradmin is not found",
  "method": "oidc",
  "success": false,
  "time": "2024-11-07T15:41:25.584Z",
  "uid": "71e46f17-d611-48bb-bf5e-effd90016c13"
}

Teleport에서 예상되는 노드가 표시되지 않음

Teleport의 Auth 서비스가 Teleport 노드를 목록화하라는 요청을 받을 때(예: 웹 UI에서 노드를 표시하거나 tsh ls 를 통해), 현재 사용자가 볼 수 있는 노드만 반환합니다.

사용자의 Teleport 클러스터의 각 노드에 대해 Auth 서비스는 다음과 같은 검사를 순서대로 적용하며, 하나의 검사가 실패할 경우 해당 노드를 사용자에게 숨깁니다:

  • 사용자의 역할 중 어느 것도 노드의 레이블과 일치하는 deny 규칙을 포함하지 않습니다.
  • 사용자의 역할 중 최소 하나가 노드의 레이블과 일치하는 allow 규칙을 포함합니다.

예상치 못하게 노드가 보이지 않는 경우, 사용자의 역할에 적절한 allowdeny 규칙이 포함되어 있는지 확인하십시오. 이는 Teleport Access Controls Reference에서 문서화되어 있습니다.

SSO를 구성할 때, ID 공급자가 각 사용자의 특성을 올바르게 인구시키고 있는지 확인하십시오. 사용자가 Teleport에서 노드를 보기 위해서는 역할의 allow.logins 에 있는 템플릿 변수의 결과가 사용자의 traits.logins 중 하나와 일치해야 합니다.

이 예에서 사용자는 env: dev 레이블이 있는 노드에 대해 ubuntu , debian 및 SSO 특성의 사용자 이름 logins 를 가집니다. SSO 특성 사용자 이름이 bob 인 경우 사용자 이름에는 ubuntu , debianbob 이 포함됩니다.

kind: role
metadata:
  name: example-role
spec:
  allow:
    logins: ["{{external.logins}}", ubuntu, debian]
    node_labels:
      "env": "dev"
version: v5

OIDC와 함께 단일 로그인 실패

**"JWT 검증 실패: oidc: JWT 서명 검증 불가능: 일치하는 키 없음"**라는 오류 메시지를 접하면, 이는 일반적으로 JWT 토큰 서명에 사용된 알고리즘과 JSON 웹 키 세트(JWKS)가 지원하는 알고리즘 간의 불일치를 나타냅니다. 특히, 토큰이 하나의 알고리즘(예: HS256)으로 서명되었으며, JWKS는 다른 알고리즘(예: RS256)에 대한 키만 나열될 수 있습니다. 이 문제는 기능이 매우 낮은 ID 공급자를 사용할 때 주로 발생합니다.

다음과 같은 사항을 확인하십시오:

  • JWT 헤더가 올바른 서명 알고리즘을 지정하고 있는지 확인하십시오. 이는 JWKS 엔드포인트 응답의 키 섹션에 나열된 알고리즘 중 하나와 일치해야 합니다.
  • JWKS 엔드포인트가 모든 관련 공개 키를 반환하는지 확인하십시오. 때때로 키 회전에 따라 유효한 키가 누락될 수 있습니다.

문제를 해결하려면 JWT 알고리즘 헤더를 JWKS에서 지원하는 알고리즘과 일치시킵니다. 필요시 키를 회전시킵니다. JWKS가 활성 공개 키만 게시하는지 확인하십시오. 올바른 구성이 이루어지면 서명이 성공적으로 검증되어야 합니다.

Teleport 원문 보기