워크로드 아이덴티티와 AWS OIDC Federation 구성
Teleport v18.9Teleport 워크로드 아이덴티티는 JWT 형식으로 유연한 단기 유효 신원을 발급합니다. 이는 머신이 장기 자격 증명 없이 AWS 서비스에 안전하게 인증해야 하는 경우에 유용합니다. 이 가이드에서는 Teleport 워크로드 아이덴티티와 AWS를 구성하여 워크로드가 AWS S3 API에 인증하고 버킷에 콘텐츠를 업로드할 수 있도록 합니다.
Teleport 워크로드 아이덴티티는 JWT 형식으로 유연한 단기 유효 신원을 발급합니다. AWS OIDC Federation을 사용하면 이러한 JWT를 AWS 서비스에 인증하는 데 활용할 수 있습니다.
이는 머신이 장기 자격 증명 없이 AWS 서비스에 안전하게 인증해야 하는 경우에 유용합니다. 머신은 위임된 조인 방법 중 하나를 사용하여 공유 시크릿 없이 Teleport에 인증할 수 있기 때문입니다.
이 가이드에서는 Teleport 워크로드 아이덴티티와 AWS를 구성하여 워크로드가 AWS S3 API에 인증하고 버킷에 콘텐츠를 업로드할 수 있도록 합니다.
작동 방식#
이 구현은 AWS API를 보호하기 위해 Teleport 애플리케이션 서비스를 사용하는 방식과 다음과 같은 몇 가지 면에서 차이가 있습니다:
- AWS로 향하는 요청은 Teleport 프록시 서비스를 통해 프록시되지 않습니다. 이는 지연 시간이 줄어드는 대신 가시성이 낮아짐을 의미하며, 이러한 요청은 Teleport의 감사 로그에 기록되지 않습니다.
- 워크로드 아이덴티티는 명령줄 도구뿐만 아니라 SDK를 포함한 모든 AWS 클라이언트와 함께 작동합니다.
- Teleport 애플리케이션 서비스를 사용하여 AWS에 접근하는 방식은 Machine ID와 함께 작동하지 않으므로, 머신이 AWS에 인증해야 하는 경우에는 사용할 수 없습니다.
OIDC Federation과 Roles Anywhere 비교#
AWS 플랫폼은 워크로드 아이덴티티 페더레이션을 위한 두 가지 방법을 제공합니다: OIDC Federation과 Roles Anywhere입니다. Teleport 워크로드 아이덴티티는 두 가지 방법을 모두 지원합니다.
두 방법 사이에는 다음과 같은 몇 가지 차이가 있습니다:
- OIDC Federation은 JWT SVID를 AWS 자격 증명으로 교환하는 반면, Roles Anywhere는 X509 SVID를 AWS 자격 증명으로 교환합니다. 일반적으로 X509 SVID를 사용하는 방식이 더 안전한 것으로 간주됩니다.
- OIDC Federation은 워크로드와 함께 AWS 자격 증명 헬퍼를 추가로 설치할 필요가 없는 반면, Roles Anywhere는 이를 설치해야 합니다.
- OIDC Federation은 Teleport 프록시 서비스가 AWS에서 접근 가능해야 하는 반면, Roles Anywhere는 그럴 필요가 없습니다.
이 가이드에서는 OIDC federation 구성을 다룹니다. Roles Anywhere에 대해서는 워크로드 아이덴티티와 AWS Roles Anywhere 구성을 참조하세요.
사전 요구 사항#
-
실행 중인 Teleport 클러스터. Teleport를 시작하려면 무료 체험판에 가입하거나 데모 환경을 구성하세요.
-
tctlandtshclients.Installing `tctl` and `tsh` clients
-
Teleport 클러스터의 버전을 확인합니다.
tctlandtshclients는 Teleport 클러스터 버전보다 최대 한 개의 메이저 버전까지만 뒤처질 수 있습니다. Proxy Service의/v1/webapi/find로 GET 요청을 보내고 JSON 쿼리 도구를 사용하여 클러스터 버전을 확인합니다.teleport.example.com:443를 Teleport Proxy Service의 웹 주소로 바꿉니다:$ TELEPORT_DOMAIN=teleport.example.com:443 $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')" -
사용 중인 플랫폼에 대한 지침에 따라
tctlandtshclients를 설치합니다:
-
Mac
`tctl` and `tsh` clients가 포함된, 서명된 Teleport macOS .pkg 설치 프로그램을 다운로드합니다:
```code
$ curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkg
```
Finder에서 `pkg` 파일을 더블 클릭하여 설치를 시작합니다.
Homebrew를 사용하여 Teleport를 설치하는 것은 지원되지 않습니다. Homebrew의
Teleport 패키지는 Teleport에서 유지 관리하지 않으므로 신뢰성이나 보안을
보장할 수 없습니다.
Windows - Powershell
```code
$ curl.exe -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-windows-amd64-bin.zip
# Unzip the archive and move the `tctl` and `tsh` clients to your %PATH%
# NOTE: Do not place the `tctl` and `tsh` clients in the System32 directory, as this can cause issues when using WinSCP.
# Use %SystemRoot% (C:\Windows) or %USERPROFILE% (C:\Users\<username>) instead.
```
Linux
Linux 설치판의 모든 Teleport 바이너리에는 `tctl` and `tsh` clients가 포함되어 있습니다. RPM/DEB
패키지 및 i386/ARM/ARM64용 다운로드를 포함한 더 많은 옵션은
[설치 페이지](../installation/installation.mdx)를 참조하세요.
```code
$ curl -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
$ tar -xzf teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
$ cd teleport
$ sudo ./install
# Teleport binaries have been copied to /usr/local/bin
```
Teleport cluster에 연결할 수 있는지 확인하려면 tsh login으로 로그인한 다음,
현재 자격 증명으로 tctl 명령을 실행할 수 있는지 확인합니다.
예를 들어, teleport.example.com에 cluster 내 Teleport Proxy Service의
도메인 이름을, email@example.com에 Teleport 사용자 이름을 지정하여
다음 명령을 실행합니다:
$ tsh login --proxy=teleport.example.com --user=email@example.com
$ tctl status
# Cluster (=teleport.url=)
# Version (=teleport.version=)
# CA pin (=presets.ca_pin=)
cluster에 연결하여 tctl status 명령을 실행할 수 있다면, 현재 자격 증명을 사용하여
워크스테이션에서 이후의 tctl 명령을 실행할 수 있습니다.
자체 Teleport cluster를 호스팅하는 경우, 전체 권한을 얻기 위해 Teleport Auth Service를
호스팅하는 컴퓨터에서 tctl 명령을 실행할 수도 있습니다.
tbot이 Teleport 워크로드 아이덴티티에 접근해야 하는 워크로드가 실행될 호스트에 이미 설치되고 구성되어 있어야 합니다. 자세한 내용은 배포 가이드를 참조하세요.
SPIFFE ID 구조 결정하기#
Teleport 워크로드 아이덴티티 내에서 모든 아이덴티티는 SPIFFE ID를 사용하여 표현됩니다. 이는 아이덴티티가 나타내는 엔티티를 고유하게 식별하는 URI입니다. 스킴은 항상 spiffe://이며, 호스트는 Teleport 클러스터의 이름이 됩니다. 이 URI 경로의 구조는 사용자가 결정합니다.
이 가이드에서는 spiffe://example.teleport.sh/svc/example-service SPIFFE ID에
AWS 접근 권한을 부여할 것입니다.
Teleport 워크로드 아이덴티티를 이미 배포했다면 SPIFFE ID 구조가 이미 갖춰져 있을 것입니다. 그렇지 않다면 SPIFFE ID 구조를 결정해야 합니다.
Teleport 워크로드 아이덴티티를 AWS OIDC Federation과만 함께 사용하는 경우, SPIFFE ID가 맡을 수 있는 AWS 역할을 명시적으로 지정하도록 구조화할 수 있습니다. 그러나 SPIFFE ID를 사용할 워크로드나 사람의 이름을 지정하는 것이 더 합리적인 경우가 많습니다. 추가적인 조언은 모범 사례 가이드를 참조하세요.
1/4단계. AWS 구성#
AWS OIDC Federation을 처음 구성할 때는 몇 가지 단계가 필요합니다. Teleport 클러스터에 대해 이전에 AWS OIDC Federation을 구성한 적이 있다면 이 중 일부는 필요하지 않을 수 있습니다.
OpenID Connect 아이덴티티 공급자 생성#
먼저 AWS에서 OIDC 아이덴티티 공급자를 생성해야 합니다. 이를 통해 AWS와 Teleport 클러스터의 워크로드 아이덴티티 발급자 간의 신뢰 관계가 정의됩니다. 이 OIDC 아이덴티티 공급자를 재사용하여 Teleport 워크로드 아이덴티티를 사용하는 다양한 워크로드에 AWS 서비스에 대한 접근 권한을 부여할 수 있습니다.
공급자를 구성할 때는 발급자 URI를 지정해야 합니다. 이는 Teleport 프록시 서비스의 공개 주소에 /workload-identity 경로를 추가한 값이 됩니다. OIDC federation이 작동하려면 Teleport 프록시 서비스가 AWS에서 접근 가능해야 합니다.
OIDC 아이덴티티 공급자를 구성하기 전에, Teleport 프록시 서비스가 사용하는 TLS 인증서의 지문(thumbprint)을 확인해야 합니다. curl을 사용하여 이를 확인할 수 있습니다:
$ curl https://example.teleport.sh/webapi/thumbprint
"example589ee4bf31a11b78c72b8d13f0example"%
이미 AWS 계정을 관리하도록 구성된 Terraform 구성 파일에 다음 내용을 삽입합니다:
resource "aws_iam_openid_connect_provider" "example_teleport_sh_workload_identity" {
// Replace "example.teleport.sh" with the hostname used to access your
// Teleport Proxy Service.
url = "https://example.teleport.sh/workload-identity"
client_id_list = [
"sts.amazonaws.com",
]
thumbprint_list = [
// Replace with the thumbprint you determined using curl.
"example589ee4bf31a11b78c72b8d13f0example"
]
}
- IAM으로 이동합니다.
- 사이드바에서 "Identity Providers"를 선택합니다.
- "Add provider"를 선택합니다.
- "Provider type"으로 "OpenID Connect"를 선택합니다.
- "Provider URL"에 Teleport 프록시 서비스의 공개 호스트 이름에
"/workload-identity"를 추가한 값을 지정합니다. 예:
https://example.teleport.sh/workload-identity - Audience로
sts.amazonaws.com을 지정합니다. - "Add Provider"를 클릭합니다.
S3 버킷 생성#
이 가이드에서는 워크로드에 AWS S3 버킷에 대한 접근 권한을 부여할 것입니다. RBAC 구성으로 들어가기 전에, 먼저 버킷을 생성해야 합니다.
AWS 내의 다른 서비스에 대한 접근 권한을 부여하려는 경우에는 이 단계를 생략할 수 있습니다.
// Create an S3 bucket
resource "aws_s3_bucket" "example" {
// Replace "example" with a meaningful, unique name.
bucket = "workload-id-demo"
}
- S3로 이동합니다.
- "Create bucket"을 선택합니다.
- 버킷에 대해 의미 있고 고유한 이름을 입력합니다. 예:
workload-id-demo - 다른 설정은 기본값으로 둡니다.
- "Create bucket"을 클릭합니다.
RBAC 구성#
IAM 정책 생성#
먼저 S3 버킷에 대한 접근 권한을 부여하는 IAM 정책을 생성합니다. 이후 워크로드가 맡게 될 역할에 이 정책을 연결할 것입니다.
이 가이드의 예시는 예시 버킷에 대한 전체 접근 권한을 부여하는 IAM 정책을 생성합니다. 프로덕션 환경에서는 필요한 최소한의 권한만 부여하도록 이를 수정해야 합니다.
Terraform 구성 파일에 다음 내용을 삽입합니다:
resource "aws_iam_policy" "example" {
// Choose a unique, meaningful name that describes what the policy grants
// access to.
name = "workload-id-s3-full-access"
path = "/"
// This example policy grants full access to AWS S3. In production, you
// may wish to grant a less permissive policy.
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "s3:*"
Effect = "Allow"
Resource = [
aws_s3_bucket.workload_id_demo.arn,
"${aws_s3_bucket.workload_id_demo.arn}/*"
]
}]
})
}
- IAM으로 이동합니다.
- 사이드바에서 "Policies"를 선택합니다.
- "Create policy"를 클릭합니다.
- "S3" 서비스를 선택합니다.
- "Actions allowed" 아래에서 "All S3 actions"를 선택합니다.
- "Resources" 아래에서 "Specific"을 선택합니다.
- "bucket"에 앞서 생성한 버킷의 이름을 입력합니다.
- "object"에 앞서 생성한 버킷의 이름을 입력하고 "All objects"를 선택합니다.
- "Next"를 클릭합니다.
- 이 정책에 대해 고유하고 의미 있는 이름을 입력합니다. 이 예시에서는
workload-id-s3-full-access를 사용합니다. - "Create policy"를 클릭합니다.
IAM 역할 생성#
이제 IAM 역할을 생성합니다. 이 역할은 워크로드가 Teleport 워크로드 아이덴티티가 발급한 JWT SVID를 사용하여 AWS에 인증한 후 맡게 됩니다.
IAM 역할을 생성할 때는 어떤 워크로드 아이덴티티가 역할을 맡을 수 있는지 제어하는 신뢰 정책을 정의합니다. 이 정책에는 Teleport 워크로드 아이덴티티가 발급한 JWT SVID 내의 클레임에 대해 평가되는 조건이 포함됩니다. 이 경우 평가하려는 유일한 클레임은 워크로드의 SPIFFE ID를 포함하는 sub 클레임입니다.
마지막으로, 앞서 생성한 IAM 정책을 이 역할에 연결하여 해당 정책에 명시된 권한을 부여합니다.
Terraform 구성 파일에 다음 내용을 삽입합니다:
// Create a role that the workload identity will assume.
resource "aws_iam_role" "example" {
// Choose a unique, meaningful name that describes the role and the workload
// that will assume it.
name = "workload-id-demo"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = {
Federated = aws_iam_openid_connect_provider.example.arn
}
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringEquals = {
"${aws_iam_openid_connect_provider.example.url}:aud" = "sts.amazonaws.com"
"${aws_iam_openid_connect_provider.example.url}:sub" = "spiffe://example.teleport.sh/svc/example-service"
}
}
}]
})
}
// Attach the policy we created earlier to our role.
resource "aws_iam_role_policy_attachment" "example" {
role = aws_iam_role.example.name
policy_arn = aws_iam_policy.example.arn
}
- IAM으로 이동합니다.
- 사이드바에서 "Roles"를 선택합니다.
- "Create role"을 클릭합니다.
- "Trusted entity type"으로 "Web identity"를 선택합니다.
- 아이덴티티 공급자를 선택합니다.
sts.amazonaws.comaudience를 선택합니다.- "Add condition"을 클릭합니다.
- 키로
example.teleport.sh:sub를 선택합니다. - 조건으로 "StringEquals"를 선택합니다.
- 값으로 워크로드의 SPIFFE ID를 입력합니다. 이 예시에서는
spiffe://example.teleport.sh/svc/example-service를 사용합니다. - "Next"를 클릭합니다.
- 앞서 생성한 IAM 정책을 선택하고 "Next"를 클릭합니다.
- 이 역할에 대해 고유하고 의미 있는 이름을 입력합니다. 이 예시에서는
workload-id-demo를 사용합니다. - "Create role"을 클릭합니다.
2/4단계. Teleport RBAC 구성#
이제 선택한 SPIFFE ID를 포함하는 JWT가 발급되도록 Teleport를 구성해야 합니다.
먼저 아이덴티티와 그 특성을 정의하는 워크로드 아이덴티티 리소스를 생성합니다. workload-identity.yaml이라는 새 파일을 생성합니다:
kind: workload_identity
version: v1
metadata:
name: example-workload-identity
labels:
example: getting-started
spec:
spiffe:
id: /svc/example-service
다음을 교체합니다:
example-workload-identity를 워크로드 아이덴티티에 대한 설명적인 이름으로 교체합니다./svc/example-service를 선택한 SPIFFE ID의 경로 부분으로 교체합니다.
tctl을 사용하여 이를 클러스터에 적용합니다:
$ tctl create -f workload-identity.yaml
다음으로 이 워크로드 아이덴티티에 대한 접근 권한을 부여하는 역할을 생성합니다. 다음 내용으로 role.yaml을 생성합니다:
kind: role
version: v6
metadata:
name: example-workload-identity-issuer
spec:
allow:
workload_identity_labels:
example: ["getting-started"]
rules:
- resources:
- workload_identity
verbs:
- list
- read
다음을 교체합니다:
example-workload-identity-issuer를 역할에 대한 설명적인 이름으로 교체합니다.- 워크로드 아이덴티티의 라벨을 수정한 경우 라벨 선택기를 교체합니다.
tctl을 사용하여 이 역할을 Teleport 클러스터에 적용합니다:
$ tctl create -f role.yaml
Web UI를 사용하여 역할을 생성하고 편집할 수도 있습니다. Access -> Roles로 이동하여 Create New Role을 클릭하거나 편집할 기존 역할을 선택하십시오.
이제 이 역할을 봇에 할당해야 합니다:
$ tctl bots update my-bot --add-roles example-workload-identity-issuer
3/4단계. 워크로드 아이덴티티 JWT 발급#
이제 워크로드를 위한 단기 유효 JWT SVID를 발급하고 갱신하도록 tbot을 구성할 것입니다. tbot은 JWT를 디스크의 파일로 기록하며, 이후 이를 읽도록 AWS 클라이언트와 SDK를 구성할 수 있습니다.
이미 배포된 tbot 서비스에서, tbot 구성 파일에 다음 내용을 추가하여 SPIFFE SVID를 발급하도록 구성합니다:
services:
- type: workload-identity-jwt
destination:
type: directory
path: /opt/workload-identity
selector:
name: example-workload-identity
audiences: ["sts.amazonaws.com"]
다음을 교체합니다:
- /opt/workload-identity를 JWT를 기록할 디렉터리로 교체합니다.
- example-workload-identity를 생성한 워크로드 아이덴티티의 이름으로 교체합니다.
이 섹션의 내용은 원문 문서를 참조하세요. (reload-tbot.mdx)
/opt/workload-identity/jwt_svid에 JWT를 포함하는 파일이 생성된 것을 확인할 수 있습니다.
4/4단계. AWS CLI 및 SDK 구성#
마지막으로, 인증에 JWT SVID를 사용하도록 AWS CLI와 SDK를 구성해야 합니다.
이는 ~/.aws/config에 위치한 구성 파일을 사용하거나 환경 변수를 사용하여 수행할 수 있습니다.
진행하려면 앞서 생성한 역할의 ARN을 알아야 합니다.
~/.aws/config 파일에 다음 내용을 추가합니다:
# You can replace "workload-id-demo" with a recognizable name that identifies
# your use-case.
[profile workload-id-demo]
# Replace with the ARN of the role you created earlier.
role_arn=arn:aws:iam::123456789012:role/workload-id-demo
# Replace with the directory and file name you configured `tbot` to write the
# JWT to.
web_identity_token_file=/opt/workload-identity/jwt_svid
다음 환경 변수를 구성합니다:
AWS_ROLE_ARN: 앞서 생성한 역할의 ARN. 예:arn:aws:iam::123456789012:role/workload-id-demoAWS_WEB_IDENTITY_TOKEN_FILE:tbot이 기록하는 JWT 파일의 경로. 예:/opt/workload-identity/jwt_svid
이제 AWS S3 API에 대한 인증을 테스트할 수 있습니다. 버킷에 업로드할 파일을 생성합니다:
$ echo "Hello, World!" > hello.txt
이제 AWS CLI를 사용하여 이 파일을 버킷에 업로드합니다:
$ aws s3 cp hello.txt s3://workload-id-demo
모든 것이 올바르게 구성되었다면, 다음과 같이 버킷에 파일이 업로드된 것을 확인할 수 있습니다:
$ aws s3 ls s3://workload-id-demo
CloudTrail의 감사 로그를 검사하면 요청이 워크로드 아이덴티티를 사용하여 인증되었으며 요청을 보낸 워크로드의 SPIFFE ID가 명시된 것을 확인할 수 있습니다.
다음 단계#
- AWS OIDC Federation: OIDC federation에 대한 공식 AWS 문서입니다.
- AWS CLI documentation: 맡을 역할을 구성하기 위한 공식 AWS CLI 문서입니다.
- 워크로드 아이덴티티 개요: Teleport 워크로드 아이덴티티 개요입니다.
- JWT SVID 개요: Teleport 워크로드 아이덴티티가 발급하는 JWT SVID에 대한 개요입니다.
- 모범 사례: 프로덕션 환경에서 워크로드 아이덴티티를 사용하기 위한 모범 사례입니다.
- 사용 가능한 모든 구성 옵션을 살펴보려면 구성 레퍼런스를 참조하세요.