인포레터에서 최신 DevOps 트렌드를 격주로 만나보세요!
머신 ID 구성 참조
이 참조 문서는 tbot
구성 파일에서 구성할 수 있는 다양한 옵션을 문서화합니다. 이 구성 파일은 CLI 매개변수만으로 tbot
을 구성하는 것보다 더 많은 제어를 제공합니다.
구성 파일로 tbot
을 실행하려면 -c
플래그와 함께 경로를 지정하십시오:
tbot start -c ./tbot.yaml
이 참조에서 artifact라는 용어는 tbot
이 출력 생성 과정의 일환으로 목적지에 작성하는 항목을 나타냅니다. artifact의 예로는 구성 파일, 인증서 및 암호화 키 자료가 있습니다. 일반적으로 artifact는 파일이지만, 이 용어는 목적지가 파일 시스템일 필요가 없기 때문에 명시적으로 피하는 것입니다.
Teleport 14부터 tbot
은 v2 구성 버전을 지원합니다.
# version은 사용 중인 구성 파일의 버전을 지정합니다. `v2` 는 가장 최근의 버전이며,
# 모든 새로운 봇에 대해 사용해야 합니다. 이 예의 나머지 부분은 `v2` 스키마입니다.
version: v2
# debug는 stderr에 자세한 로깅을 활성화합니다. 지정하지 않으면 기본값은
# false입니다.
debug: true
# auth_server는 `tbot` 이 연결해야 하는 Auth Service 인스턴스의 주소를 지정합니다.
# Proxy Service 주소를 지정하기 위해 `proxy_server` 를 지정하는 것을 선호해야 합니다.
auth_server: "teleport.example.com:3025"
# proxy_server는 `tbot` 이 연결해야 하는 Teleport Proxy Service의 주소를 지정합니다.
# Teleport Proxy Service의 주소를 사용하거나, Teleport Cloud를 사용하는 경우
# Teleport Cloud 인스턴스의 주소를 사용하는 것이 좋습니다.
proxy_server: "teleport.example.com:443" # 또는 Teleport Cloud의 경우 "example.teleport.sh:443"
# certificate_ttl은 `tbot` 이 생성한 인증서가 얼마나 오래 유효해야 하는지를 지정합니다.
# 이는 `m` (분)을 포함하거나 `h` (시간)을 포함하는 양수 숫자 값이어야 합니다.
# 기본값은 `1h` 이며, 최대값은 `24h` 입니다.
certificate_ttl: "1h"
# renewal_interval은 `tbot` 이 생성한 출력을 갱신하려고 하는 빈도를 지정합니다.
# 이는 `m` (분)을 포함하거나 `h` (시간)을 포함하는 양수 숫자 값이어야 합니다.
# 기본값은 `20m` 입니다. 이 값은 `certificate_ttl` 보다 낮아야 합니다.
# `tbot` 이 일회성 모드로 실행 중일 때 이 값은 무시됩니다.
renewal_interval: "20m"
# oneshot은 출력을 생성한 후 즉시 `tbot` 을 종료하도록 구성합니다.
# 기본값은 `false` 입니다. `true` 값을 사용하는 것은 CI/CD와 같은 일시적인 환경에서 유용합니다.
oneshot: false
# onboarding은 `tbot` 이 Teleport 클러스터에 인증하는 방법을 제어하는 구성 옵션의 그룹입니다.
onboarding:
# token은 Teleport 클러스터에서 구성된 조인 토큰을 지정합니다.
# 이 값이 사용되어야 합니다.
#
# 이것은 사용하려는 값이 포함된 파일의 절대 경로일 수도 있습니다.
# 파일 경로 예시:
# token: /var/lib/teleport/tokenjoin
token: "00000000000000000000000000000000"
# join_method는 위에서 지정된 토큰과 관련된 조인 방법이어야 합니다.
# 이 설정은 `tctl` 을 사용하여 봇을 생성할 때 출력된 값과 일치해야 합니다.
#
# 지원되는 값은 다음과 같습니다:
# - `token`
# - `azure`
# - `gcp`
# - `circleci`
# - `github`
# - `gitlab`
# - `iam`
# - `ec2`
# - `kubernetes`
# - `spacelift`
# - `tpm`
# - `terraform_cloud`
join_method: "token"
# ca_pins는 첫 연결 시 Teleport Auth Service의 신원을 검증하는 데 사용됩니다.
# Teleport Cloud를 사용하거나 Teleport Proxy를 통해 연결할 때는 이 값을 지정하지 않아야 합니다.
ca_pins:
- "sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678"
- "sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678"
# ca_path는 첫 연결 시 Teleport Auth Service의 신원을 검증하는 데 사용할 수 있는 CA 파일의 위치를 지정하는 데 사용됩니다.
# Teleport Cloud를 사용하거나 Teleport Proxy를 통해 연결할 때는 이 값을 지정하지 않아야 합니다.
# ca_pins 옵션을 ca_path보다 선호해야 합니다.
ca_path: "/path/to/ca.pem"
# storage는 `tbot` 이 내부 상태를 저장하는 데 사용할 목적지를 지정합니다.
# 이 상태는 민감하므로 여기에 지정한 목적지는 `tbot` 만 접근할 수 있어야 합니다.
#
# 지정하지 않으면 저장소는 `/var/lib/teleport/bot` 경로를 갖는 디렉토리 목적지로 설정됩니다.
#
# 이 참조 페이지의 Destinations 섹션에 있는 지원되는 목적지의 전체 목록과 그 구성 옵션을 참조하십시오.
storage:
type: directory
path: /var/lib/teleport/bot
# outputs는 `tbot` 이 실행될 때 생성하고 갱신해야 하는 artifact를 지정합니다.
#
# 이 참조 페이지의 Outputs 섹션에 있는 지원되는 출력의 전체 목록과 그 구성 옵션을 참조하십시오.
outputs:
- type: identity
destination:
type: directory
path: /opt/machine-id
# services는 어떤 `tbot` 하위 서비스가 활성화되어야 하며 어떻게 구성되어야 하는지를 지정합니다.
#
# 이 참조 페이지의 Services 섹션에 있는 지원되는 서비스와 그 구성 옵션의 전체 목록을 참조하십시오.
services:
- type: example
구성 파일이 제공되지 않으면, 제공된 CLI 플래그에 따라 간단한 구성이 사용됩니다. tctl bots add ...
의 다음 샘플 CLI를 고려하십시오:
tbot start \ --destination-dir=./tbot-user \ --token=00000000000000000000000000000000 \ --ca-pin=sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678 \ --proxy-server=example.teleport.sh:443
이는 다음과 동등한 구성을 사용합니다:
proxy_server: example.teleport.sh:443
onboarding:
join_method: "token"
token: "abcd123-insecure-do-not-use-this"
ca_pins:
- "sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678"
storage:
type: directory
path: /var/lib/teleport/bot
outputs:
- type: identity
destination:
type: directory
path: ./tbot-user
출력
출력은 tbot
이 실행될 때 수행해야 할 작업을 정의합니다. 이는 생성될 인증서의 형식, 인증서를 생성하는 데 사용되는 역할 및 인증서를 기록할 목적지를 설명합니다.
여러 유형의 출력이 있습니다. 의도한 사용 사례에 가장 적합한 것을 선택하십시오.
identity
identity
출력은 다음과 같이 인증하는 데 사용할 수 있습니다:
tsh
, openssh 및 ansible과 같은 도구를 사용하여 Teleport 서버에 대한 SSH 액세스.tsh
또는tctl
과 같은 도구를 사용하여 클러스터에 대한 관리 작업.- Teleport Terraform 제공자를 사용한 Teleport 리소스 관리.
- Teleport Go SDK를 사용한 Teleport API에 대한 액세스.
문맥에서 사용되는 identity
출력을 보려면 시작 가이드를 참조하십시오.
# type은 출력의 유형을 지정합니다. identity 출력의 경우,
# 이는 항상 `identity` 입니다.
type: identity
(!docs/pages/includes/machine-id/common-output-config.yaml!)
application
application
출력은 Teleport로 구성된 애플리케이션에 액세스하는 데 사용할 수 있는 자격 증명을 생성하는 데 사용됩니다.
문맥에서 사용되는 application
출력을 보려면 애플리케이션 액세스가 포함된 머신 ID 가이드를 참조하십시오.
# type은 출력의 유형을 지정합니다. application 출력의 경우,
# 이는 항상 `application` 입니다.
type: application
# app_name은 `tbot` 이 자격 증명을 생성해야 하는 Teleport
# 클러스터에 구성된 애플리케이션 이름입니다.
# 이 필드는 반드시 지정해야 합니다.
app_name: grafana
(!docs/pages/includes/machine-id/common-output-config.yaml!)
database
database
출력은 Teleport로 구성된 데이터베이스에 액세스하는 데 사용할 수 있는 자격 증명을 생성하는 데 사용됩니다.
문맥에서 사용되는 database
출력을 보려면 데이터베이스 액세스가 포함된 머신 ID 가이드를 참조하십시오.
# type은 출력의 유형을 지정합니다. database 출력의 경우,
# 이는 항상 `database` 입니다.
type: database
# service는 Teleport에 구성된 데이터베이스 서버의 이름으로,
# 출력이 자격 증명을 생성해야 합니다. 이 필드는 반드시 지정해야 합니다.
service: my-postgres-server
# database는 지정된 데이터베이스 서버에서 자격 증명을 생성할 특정 데이터베이스의 이름입니다.
# 이 필드는 여러 개별 데이터베이스를 지원하지 않는 데이터베이스 유형의 경우 지정할 필요가 없습니다.
database: my-database
# username은 지정된 데이터베이스 서버에서 자격 증명을 생성할 사용자의 이름입니다.
# 이 필드는 사용자가 없는 데이터베이스 유형에서는 지정할 필요가 없습니다.
username: my-user
# format은 출력 아티팩트에 사용할 형식을 지정합니다. 지정되지 않은 경우 기본 형식이 사용됩니다.
# 아래의 "지원되는 형식" 표를 참조하여 전체 지원 값 목록을 확인하십시오.
format: tls
(!docs/pages/includes/machine-id/common-output-config.yaml!)
지원되는 형식
다음 값을 database
출력 유형의 format
구성 필드에 제공할 수 있습니다:
format | 설명 |
---|---|
Unspecified | tlscert 형식의 인증서, key 형식의 개인 키 및 teleport-database-ca.crt 에서 CA를 제공합니다. 이는 대부분의 클라이언트 및 데이터베이스와 호환됩니다. |
mongo | mongo.crt 및 mongo.cas 를 제공합니다. 이는 MongoDB 클라이언트와 함께 사용하도록 설계되었습니다. |
cockroach | cockroach/node.key , cockroach/node.crt 및 cockroach/ca.crt 를 제공합니다. 이는 CockroachDB 클라이언트와 함께 사용하도록 설계되었습니다. |
tls | tls.key , tls.crt 및 tls.cas 를 제공합니다. 이는 특정 파일 확장이 필요한 일반 클라이언트를 위한 것입니다. |
kubernetes
kubernetes
출력은 Teleport로 구성된 Kubernetes 클러스터에 접근할 수 있는 자격 증명을 생성하는 데 사용됩니다.
이 출력은 kubectl
과 함께 사용할 수 있는 출력 위치에 kubeconfig.yaml
을 생성합니다.
kubernetes
출력을 맥락에서 사용한 내용을 보려면 Kubernetes 접근 가이드의 Machine ID를 참조하십시오.
# type은 출력의 유형을 지정합니다. kubernetes 출력의 경우 이는
# 항상 `kubernetes` 입니다.
type: kubernetes
# kubernetes_cluster는 Teleport에서 구성된 Kubernetes 클러스터의 이름으로,
# 이 출력이 자격 증명과 kubeconfig를 생성해야 하는 대상입니다.
# 이 필드는 반드시 지정해야 합니다.
kubernetes_cluster: my-cluster
(!docs/pages/includes/machine-id/common-output-config.yaml!)
ssh_host
ssh_host
출력은 Teleport와 함께 OpenSSH 서버를 구성하는 데 필요한 아티팩트를 생성하여 Teleport 사용자가 서버에 연결할 수 있도록 합니다.
출력은 다음과 같은 아티팩트를 생성합니다:
ssh_host-cert.pub
: Teleport 호스트 인증 기관에 의해 서명된 SSH 인증서입니다.ssh_host
: SSH 호스트 인증서와 관련된 개인 키입니다.ssh_host-user-ca.pub
: OpenSSH 호환 형식으로 내보낸 Teleport 사용자 인증 기관입니다.
# type은 출력의 유형을 지정합니다. ssh host 출력의 경우 이는
# 항상 `ssh_host` 입니다.
type: ssh_host
# principals는 호스트 인증서에 포함할 호스트 이름 목록입니다.
# 이 이름들은 클라이언트가 호스트에 연결하는 데 사용하는 이름과 일치해야 합니다.
principals:
- host.example.com
(!docs/pages/includes/machine-id/common-output-config.yaml!)
spiffe-svid
spiffe-svid
출력은 SPIFFE X509 SVID를 생성하고 이를 구성된 목적지에 기록하는 데 사용됩니다.
출력은 다음과 같은 아티팩트를 생성합니다:
svid.pem
: X509 SVID입니다.svid.key
: X509 SVID와 관련된 개인 키입니다.bundle.pem
: 신뢰 도메인 CA를 포함하는 X509 번들입니다.
jwts
목록 내의 각 항목에 대해서도 아티팩트가 생성됩니다. 이 아티팩트는 file_name
에 따라 이름이 지정됩니다. 이 아티팩트는 audience
에 지정된 청중과 함께 JWT-SVID만 포함됩니다.
SPIFFE SVID 사용 방법에 대한 자세한 내용은 Workload Identity를 참조하십시오.
# type은 출력의 유형을 지정합니다. SPIFFE SVID 출력의 경우 이는
# 항상 `spiffe-svid` 입니다.
type: spiffe-svid
# svid는 요청해야 할 SPIFFE SVID의 속성을 지정합니다.
svid:
# path는 SPIFFE ID에 대해 요청해야 할 경로 요소를 지정합니다.
path: /svc/foo
# sans는 생성된 X509 SVID에 포함할 선택적 대체 주체 이름(SAN)을 지정합니다.
# 생략할 경우 SAN은 포함되지 않습니다.
sans:
# dns는 DNS SAN을 지정합니다. 생략할 경우 DNS SAN은 포함되지 않습니다.
dns:
- foo.svc.example.com
# ip는 IP SAN을 지정합니다. 생략할 경우 IP SAN은 포함되지 않습니다.
ip:
- 10.0.0.1
# jwts는 JWT-SVID의 출력을 제어합니다. 각 항목은
# 별도의 아티팩트로 생성됩니다. 생략할 경우 JWT-SVID는 생성되지 않습니다.
jwts:
# audience는 JWT-SVID가 발급되어야 할 청중을 지정합니다.
# 이는 일반적으로 JWT-SVID가 인증하는 데 사용될 서비스를 식별합니다.
- audience: https://example.com
# file_name은 JWT-SVID가 기록되어야 할 파일 이름을 지정합니다.
file_name: example-jwt
(!docs/pages/includes/machine-id/common-output-config.yaml!)
서비스
서비스는 tbot
내에서 실행되는 구성 가능하고 장기적인 구성 요소입니다. Outputs와는 달리, 서비스는 반드시 아티팩트를 생성하지 않을 수 있습니다. 일반적으로 서비스는 기계 간 액세스를 위한 지원 기능을 제공하며, 예를 들어 터널을 열거나 API를 제공합니다.
spiffe-workload-api
spiffe-workload-api
서비스는 SPIFFE Workload API를 구현하는 서비스에 대한 리스너를 엽니다. 이 서비스는 작업 부하에 SPIFFE SVID를 제공하는 데 사용됩니다.
SPIFFE Workload API에 대한 자세한 내용은 Workload Identity를 참조하십시오.
# type은 서비스의 유형을 지정합니다. SPIFFE Workload API 서비스의 경우,
# 이는 항상 `spiffe-workload-api` 입니다.
type: spiffe-workload-api
# listen은 서비스가 리스닝해야 하는 주소를 지정합니다.
#
# 두 가지 유형의 리스너가 지원됩니다:
# - TCP: `tcp://<address>:<port>`
# - Unix 소켓: `unix:///<path>`
listen: unix:///opt/machine-id/workload.sock
# attestors는 이 Workload API에 대한 Workload Attestation을 구성할 수 있게 합니다.
attestors:
# kubernetes는 Kubernetes Workload Attestor에 대한 구성입니다. 자세한 내용은
# Kubernetes Workload Attestor 섹션을 참조하십시오.
kubernetes:
# enabled는 Kubernetes Workload Attestor를 활성화할지 여부를 지정합니다.
# 지정하지 않으면 기본값은 false입니다.
enabled: true
# kubelet은 Kubelet API와의 상호작용과 관련된 Kubernetes Workload Attestors의
# 구성입니다.
kubelet:
# read_only_port는 Kubelet API가 읽기 전용 작업을 위해 노출되는 포트입니다.
# Kubernetes 1.16부터 읽기 전용 포트는 기본적으로 비활성화되며 secure_port가 대신 사용되어야 합니다.
read_only_port: 10255
# secure_port는 attestor가 Kubelet 보안 API에 연결할 포트입니다. 지정하지 않으면
# 기본값은 `10250` 입니다. 이는 ReadOnlyPort와 상호 배타적입니다.
secure_port: 10250
# token_path는 Kubelet API 클라이언트가 Kubelet API와 인증하는 데 사용할
# 토큰 파일의 경로입니다. 지정하지 않으면 기본값은
# `/var/run/secrets/kubernetes.io/serviceaccount/token` 입니다.
token_path: "/var/run/secrets/kubernetes.io/serviceaccount/token"
# ca_path는 Kubelet API 클라이언트가 Kubelet API 서버의 인증서를 검증하는 데
# 사용할 CA 파일의 경로입니다. 지정하지 않으면 기본값은
# `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt` 입니다.
ca_path: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
# skip_verify는 Kubelet API 서버의 인증서 검증을 비활성화하는 데 사용됩니다.
# 지정하지 않으면 기본값은 false입니다.
#
# 지정된 경우, ca_path에 지정된 값은 무시됩니다.
#
# 이는 Kubelet API 서버가 Kubernetes 클러스터의 CA에 의해 서명된 인증서를 발급받지
# 않은 경우에 유용합니다. 이는 여러 Kubernetes 배포에서 비교적 일반적입니다.
skip_verify: true
# anonymous는 Kubelet API와의 인증을 비활성화하는 데 사용됩니다. 지정하지 않으면
# 기본값은 false입니다. 설정된 경우, token_path 필드는 무시됩니다.
anonymous: false
# svids는 Workload API가 제공해야 하는 SPIFFE SVID를 지정합니다.
svids:
# path는 SPIFFE ID를 요청하기 위한 경로 요소를 지정합니다.
- path: /svc/foo
# hint는 여러 SVID 중에서 선택할 SVID를 결정하는 데 도움이 되는 자유 형식의 문자열입니다.
# 생략하면 힌트가 포함되지 않습니다.
hint: my-hint
# sans는 생성된 X509 SVID에 포함할 선택적 주체 대체 이름(SAN)을 지정합니다.
# 생략하면 SAN이 포함되지 않습니다.
sans:
# dns는 DNS SAN을 지정합니다. 생략하면 DNS SAN이 포함되지 않습니다.
dns:
- foo.svc.example.com
# ip는 IP SAN을 지정합니다. 생략하면 IP SAN이 포함되지 않습니다.
ip:
- 10.0.0.1
# rules는 작업 부하의 증명을 위한 규칙 목록을 지정합니다. 이 SVID를 수령하기 위해서는
# 이러한 규칙 중 적어도 하나가 만족되어야 합니다.
#
# 규칙이 지정되지 않으면 SVID는 이 서비스에 연결된 모든 작업 부하에 발급됩니다.
rules:
# unix는 작업 부하가 동일한 호스트에서 실행 중이고 Unix 소켓을 사용하여
# Workload API에 연결될 때 사용할 수 있는 작업 부하 증명 기준의 그룹입니다.
#
# 이 그룹의 기준 중 하나가 지정되면, Unix 소켓을 사용하지 않는 작업 부하는
# 이 SVID를 수령하지 않습니다.
- unix:
# uid는 작업 부하 프로세스가 이 SVID를 수령하기 위해 실행해야 하는
# 사용자 ID입니다.
#
# 지정하지 않으면 UID는 확인되지 않습니다.
uid: 1000
# pid는 작업 부하 프로세스가 이 SVID를 수령하기 위해 가져야 하는 ID입니다.
#
# 지정하지 않으면 PID는 확인되지 않습니다.
pid: 1234
# gid는 작업 부하 프로세스가 이 SVID를 수령하기 위해 실행해야 하는
# 기본 그룹 ID입니다.
#
# 지정하지 않으면 GID는 확인되지 않습니다.
gid: 50
Envoy SDS
spiffe-workload-api
서비스 엔드포인트는 또한 Envoy SDS API를 구현합니다.
이를 통해 Envoy 프록시를 위한 인증서 및 인증서 권한 기관의 소스로 작동할 수 있습니다.
전방 프록시로서 Envoy는 SPIFFE가 활성화되지 않은 워크로드의 외부 연결에 X.509 SVID를 부착하는 데 사용될 수 있습니다.
역방향 프록시로서 Envoy는 SPIFFE가 활성화된 클라이언트의 mTLS 연결을 종료하는 데 사용할 수 있습니다.
Envoy는 클라이언트가 유효한 X.509 SVID를 제시했는지 확인하고 SVID 내의 SPIFFE ID에 따라 권한 부여 정책을 시행할 수 있습니다.
특정 프로토콜에 대한 역방향 프록시로 작동할 때, Envoy는 요청을 서비스로 전달하기 전에 클라이언트의 신원을 나타내는 헤더를 부착하도록 구성할 수 있습니다.
이 정보는 서비스가 클라이언트의 신원을 기반으로 권한 부여 결정을 내리는 데 사용될 수 있습니다.
spiffe-workload-api
서비스에서 노출된 SDS API를 사용하도록 Envoy를 구성할 때, 구성에 도움이 되는 세 가지 추가 특수 이름을 사용할 수 있습니다:
default
:tbot
은 워크로드의 기본 SVID를 반환합니다.ROOTCA
:tbot
은 워크로드가 속한 신뢰 도메인의 신뢰 번들을 반환합니다.ALL
:tbot
은 워크로드가 속한 신뢰 도메인의 신뢰 번들과 신뢰 도메인이 연합된 모든 신뢰 도메인의 신뢰 번들을 반환합니다.
다음은 unix:///opt/machine-id/workload.sock
에서 수신하는 spiffe-workload-api
서비스에서 인증서 및 신뢰 번들을 비롯한 Envoy 구성의 예입니다.
연결하는 클라이언트가 유효한 SPIFFE SVID를 제시하도록 요구하며 이 정보를 x-forwarded-client-cert
헤더에 백엔드 서비스로 전달합니다.
node:
id: "my-envoy-proxy"
cluster: "my-cluster"
static_resources:
listeners:
- name: test_listener
enable_reuse_port: false
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
common_http_protocol_options:
idle_timeout: 1s
forward_client_cert_details: sanitize_set
set_current_client_cert_details:
uri: true
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: my_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: my_service
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
# 역방향 프록시가 제시해야 할 인증서 구성.
tls_certificate_sds_secret_configs:
# 여러 SVID가 있는 경우 `name` 을 원하는 SPIFFE ID로
# 바꿀 수 있습니다.
- name: "default"
sds_config:
resource_api_version: V3
api_config_source:
api_type: GRPC
transport_api_version: V3
grpc_services:
envoy_grpc:
cluster_name: tbot_agent
# 결합된 유효성 검사 컨텍스트는 두 개의 유효성 검사 컨텍스트를
# 함께 "melds"합니다. 이는 SDS 소스에서 유효성 검사 컨텍스트를
# 확장하는 데 유용합니다.
combined_validation_context:
default_validation_context:
# match_typed_subject_alt_names를 사용하여 특정 SPIFFE ID에서만
# 연결을 허용하는 규칙을 구성할 수 있습니다.
match_typed_subject_alt_names: []
validation_context_sds_secret_config:
name: "ALL" # 이를 신뢰 도메인 이름으로도 교체할 수 있습니다.
sds_config:
resource_api_version: V3
api_config_source:
api_type: GRPC
transport_api_version: V3
grpc_services:
envoy_grpc:
cluster_name: tbot_agent
clusters:
# my_service는 Envoy가 트래픽을 전달할 예제 서비스입니다.
- name: my_service
type: strict_dns
load_assignment:
cluster_name: my_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8090
- name: tbot_agent
http2_protocol_options: {}
load_assignment:
cluster_name: tbot_agent
endpoints:
- lb_endpoints:
- endpoint:
address:
pipe:
# `tbot` 가 수신 대기하는 소켓의 경로를 구성합니다.
path: /opt/machine-id/workload.sock
database-tunnel
database-tunnel
서비스는 데이터베이스 서버에 대한 연결을 터널링하는 서비스용 리스너를 엽니다.
터널은 클라이언트의 연결을 인증하며, 이는 리스너에 연결할 수 있는 모든 애플리케이션이 지정된 사용자로 데이터베이스에 연결할 수 있음을 의미합니다. 이러한 이유로, Unix 소켓 리스너 타입을 사용하는 것을 강력히 권장하며, 소켓의 권한을 설정하여 의도한 애플리케이션만 연결할 수 있도록 하십시오.
# type은 서비스의 유형을 지정합니다. 데이터베이스 터널 서비스의 경우
# 항상 `database-tunnel` 이 됩니다.
type: database-tunnel
# listen은 서비스가 수신해야 하는 주소를 지정합니다.
#
# 두 가지 유형의 리스너가 지원됩니다.
# - TCP: `tcp://<address>:<port>`
# - Unix socket: `unix:///<path>`
listen: tcp://127.0.0.1:25432
# service는 서비스가 터널을 열어야 하는 데이터베이스 서버의 이름으로,
# Teleport에서 구성된 이름입니다.
service: postgres-docker
# database는 지정된 데이터베이스 서비스에서 특정 데이터베이스의 이름입니다.
database: postgres
# username은 터널을 열기 위해 지정된 데이터베이스 서버에서의 사용자 이름입니다.
username: postgres
application-tunnel
application-tunnel
서비스는 Teleport의 애플리케이션에 대한 연결을 터널링하는 리스너를 엽니다. HTTP 및 TCP 애플리케이션 모두를 지원합니다. 이는 클라이언트 인증서를 사용할 수 없는 애플리케이션이나 Teleport 프록시 앞에 L7 로드 밸런서를 사용할 때 유용합니다.
터널은 클라이언트의 연결을 인증하며, 이는 리스너에 연결하는 모든 클라이언트가 애플리케이션에 접근할 수 있음을 의미합니다. 이러한 이유로, 리스너가 의도한 클라이언트만 접근할 수 있도록 Unix 소켓 리스너를 사용하거나 127.0.0.1
에 바인딩하는 것을 확인하십시오.
# type은 서비스의 유형을 지정합니다. 애플리케이션 터널 서비스의 경우
# 항상 `application-tunnel` 이 됩니다.
type: application-tunnel
# listen은 서비스가 수신해야 하는 주소를 지정합니다.
#
# 두 가지 유형의 리스너가 지원됩니다.
# - TCP: `tcp://<address>:<port>`
# - Unix socket: `unix:///<path>`
listen: tcp://127.0.0.1:8084
# app_name은 서비스가 터널을 열어야 하는 애플리케이션의 이름으로,
# Teleport에서 구성된 이름입니다.
app_name: my-application
ssh-multiplexer
ssh-multiplexer
서비스는 고성능 로컬 SSH 멀티플렉서를 위한 리스너를 엽니다. 이는 Teleport를 사용하는 SSH 연결을 대량으로 생성하는 사용 사례(예: Ansible)를 위해 설계되었습니다.
이것은 SSH를 위한 identity
출력을 사용하는 것과 몇 가지 방식에서 다릅니다:
ssh-multiplexer
서비스가 실행 중인tbot
인스턴스는 SSH 클라이언트와 동일한 호스트에서 실행되어야 합니다.ssh-multiplexer
서비스는 장기 실행 백그라운드 서비스로 설계되었으며, 원샷 모드로 사용할 수 없습니다. SSH 연결을 설정하고 계속 실행되기 위해서는 반드시 실행 중이어야 합니다.- SSH 연결을 통해 리소스 소비가 상당히 줄어듭니다. 이는 적은 수의 상위 연결을 통해 SSH 연결을 멀티플렉싱함으로써 가능해집니다.
추가적으로, ssh-multiplexer
는 SSH 에이전트 프로토콜을 구현하는 소켓을 엽니다. 이를 통해 SSH 클라이언트는 민감한 개인 키를 디스크에 기록하지 않고도 인증할 수 있습니다.
기본적으로, ssh-multiplexer
서비스는 tbot
자신을 ProxyCommand로 사용하는 ssh_config
를 출력합니다. fdpass-teleport
바이너리를 설치하고 지정하면 SSH 연결의 리소스 소비를 더 줄일 수 있습니다.
# type은 서비스의 유형을 지정합니다. SSH 멀티플렉서의 경우
type: ssh-multiplexer
# destination은 터널을 열어야 하는 위치와 모든 아티팩트가 작성되어야 하는지를 지정합니다.
# directory 유형이어야 합니다.
destination:
type: directory
path: /foo
# enable_resumption은 멀티플렉서가 세션 복원을 협상해야 하는지를 지정합니다.
# 이로 인해 SSH 연결이 네트워크 중단을 견딜 수 있습니다. 이는 연결당 사용되는 메모리 리소스를 증가시킵니다.
#
# 지정하지 않으면 기본값은 true입니다.
enable_resumption: true
# proxy_command는 생성된 SSH 구성에서 ProxyCommand로 사용할 명령을 지정합니다.
#
# 지정하지 않으면 ProxyCommand는 현재 실행 중인 `tbot` 바이너리가 됩니다.
proxy_command:
- /usr/local/bin/fdpass-teleport
# proxy_templates_path는 Teleport 노드를 연결할 때 사용해야 하는 프록시 템플릿 구성 파일의 경로를
# 지정합니다. 이 파일은 SSH 멀티플렉서가 실행 중인 장기 실행 tbot 프로세스에서 접근 가능해야 합니다.
#
# 지정하지 않으면 프록시 템플릿은 사용되지 않습니다.
proxy_templates_path: /etc/my-proxy-templates.yaml
구성이 완료되면, tbot
는 지정된 대역에 다음 아티팩트를 생성합니다:
ssh_config
: OpenSSH가 멀티플렉서 및 에이전트를 사용하도록 구성하는 SSH 구성 파일입니다.known_hosts
: OpenSSH가 서버의 신원을 검증하는 데 사용되는 known hosts 파일입니다.v1.sock
: 멀티플렉서가 수신 대기하는 Unix 소켓입니다.agent.sock
: SSH 에이전트가 수신 대기하는 Unix 소켓입니다.
SSH 멀티플렉서를 프로그래밍 방식으로 사용하기
SSH 멀티플렉서를 프로그래밍 방식으로 사용하려면 SSH 클라이언트 라이브러리가 두 가지 사항 중 하나를 지원해야 합니다:
- FDPass와 함께 ProxyCommand를 사용할 수 있는 기능. 그렇다면
tbot
에 의해 생성된ssh_config
파일을 사용하여 SSH 클라이언트를 구성할 수 있습니다. - SSH 서버와의 연결에 사용할 수 있는 열린 소켓을 수용할 수 있는 기능. 그러면 소켓에 수동으로 연결하고 멀티플렉서 요청을 보내야 합니다.
v1.sock
유닉스 도메인 소켓은 V1 Teleport SSH 멀티플렉서 프로토콜을 구현합니다. 클라이언트는 먼저 원하는 대상 호스트 및 포트를 나타내는 짧은 요청 메시지를 전송해야 하며, 이는 null 바이트로 종료됩니다. 그러면 멀티플렉서가 대상 호스트 및 포트로 트래픽을 포워딩하기 시작합니다. 클라이언트는 그 후 SSH 연결을 만들 수 있습니다.
import os
import paramiko
import socket
host = "ubuntu.example.teleport.sh"
username = "root"
port = 3022
directory_destination = "/opt/machine-id"
# Mux 유닉스 도메인 소켓에 연결합니다.
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(os.path.join(directory_destination, "v1.sock"))
# 연결할 서버를 지정하는 연결 요청을 전송합니다.
sock.sendall(f"{host}:{port}\x00".encode("utf-8"))
# Paramiko가 이 설정을 구성할 수 없기 때문에 환경 변수를 설정해야 합니다...
os.environ["SSH_AUTH_SOCK"] = os.path.join(directory_destination, "agent.sock")
ssh_config = paramiko.SSHConfig()
with open(os.path.join(directory_destination, "ssh_config")) as f:
ssh_config.parse(f)
ssh_client = paramiko.SSHClient()
# Paramiko는 CAs가 있는 known_hosts를 지원하지 않습니다: https://github.com/paramiko/paramiko/issues/771
# 따라서 호스트 키 확인을 비활성화해야 합니다.
ssh_client.set_missing_host_key_policy(paramiko.WarningPolicy())
ssh_client.connect(
hostname=host,
port=port,
username=username,
sock=sock
)
stdin, stdout, stderr = ssh_client.exec_command("hostname")
print(stdout.read().decode())
package main
import (
"fmt"
"net"
"path/filepath"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"golang.org/x/crypto/ssh/knownhosts"
)
func main() {
host := "ubuntu.example.teleport.sh"
username := "root"
directoryDestination := "/opt/machine-id"
// 에이전트 및 알려진 호스트 설정
agentConn, err := net.Dial(
"unix", filepath.Join(directoryDestination, "agent.sock"),
)
if err != nil {
panic(err)
}
defer agentConn.Close()
agentClient := agent.NewClient(agentConn)
hostKeyCallback, err := knownhosts.New(
filepath.Join(directoryDestination, "known_hosts"),
)
if err != nil {
panic(err)
}
// SSH 구성 생성
sshConfig := &ssh.ClientConfig{
Auth: []ssh.AuthMethod{
ssh.PublicKeysCallback(agentClient.Signers),
},
User: username,
HostKeyCallback: hostKeyCallback,
}
// 유닉스 도메인 소켓에 연결하고 멀티플렉싱 요청을 전송합니다.
conn, err := net.Dial(
"unix", filepath.Join(directoryDestination, "v1.sock"),
)
if err != nil {
panic(err)
}
defer conn.Close()
_, err = fmt.Fprint(conn, fmt.Sprintf("%s:0\x00", host))
if err != nil {
panic(err)
}
sshConn, sshChan, sshReq, err := ssh.NewClientConn(
conn,
// 멀티플렉서가 이미 연결을 설정했기 때문에 여기서 포트는 중요하지 않습니다.
fmt.Sprintf("%s:22", host),
sshConfig,
)
if err != nil {
panic(err)
}
sshClient := ssh.NewClient(sshConn, sshChan, sshReq)
defer sshClient.Close()
sshSess, err := sshClient.NewSession()
if err != nil {
panic(err)
}
defer sshSess.Close()
out, err := sshSess.CombinedOutput("hostname")
if err != nil {
panic(err)
}
fmt.Println(string(out))
}
목적지
목적지는 tbot
이 아티팩트를 읽고 쓸 수 있는 위치입니다.
목적지는 tbot
구성에서 두 가지 장소에서 사용됩니다:
tbot
이 내부 상태를 저장해야 하는 위치를 지정합니다.- 출력이 생성한 아티팩트를 기록해야 하는 위치를 지정합니다.
목적지는 여러 유형이 있습니다. 일반적으로 directory
유형이 가장 적합합니다.
directory
directory
목적지 유형은 아티팩트를 지정된 디렉터리에 파일로 저장합니다.
# type은 목적지 유형을 지정합니다. directory 목적지의 경우,
# 항상 `directory` 입니다.
type: directory
# path는 이 목적지가 기록할 디렉터리의 경로를 지정합니다.
# 이 디렉터리는 이미 존재해야 하며, 올바른 권한으로 생성하기 위해
# `tbot init` 를 사용해야 합니다.
path: /opt/machine-id
# symlinks는 심볼릭 링크 공격 방지의 동작을 구성합니다.
# Linux 5.6+가 필요합니다.
# 지원되는 값:
# * try-secure (기본값): 심볼릭 링크 없이 인증서를 안전하게 읽고 쓸 수 있도록 시도하지만,
# 호스트가 지원하지 않는 경우에는 비안전하게 읽고 쓸 수 있도록 경고합니다.
# * secure: 지원되지 않을 경우 하드 오류와 함께 인증서를 안전하게 읽고 쓰도록 시도합니다.
# * insecure: 경로에서 심볼릭 링크를 조용히 허용합니다.
symlinks: try-secure
# acls는 이 목적지에 대해 Linux 파일 접근 제어 목록 (ACL) 설정이 이루어져야 하는지 구성합니다.
# ACL을 지원하는 파일 시스템이 있는 Linux가 필요합니다.
# 지원되는 값:
# * try (Linux에서 기본값): ACL을 사용하려고 시도하며, ACL이 구성되었지만 유효하지 않은 경우
# 런타임에서 경고합니다.
# * off (비-Linux에서 기본값): ACL을 사용하지 않으려고 시도하지 않습니다.
# * required: 항상 ACL을 사용하며, 런타임에서 ACL이 유효하지 않은 경우 하드 오류를 발생시킵니다.
acls: try
# readers는 이 디렉터리 출력을 접근할 수 있는 사용자와 그룹 목록입니다. `acls` 매개변수는
# `try` 또는 `required` 이어야 합니다. 파일 ACL은 이 구성과 일치하도록 런타임에 모니터링 및
# 수정됩니다.
# 개별 항목은 `user` 또는 `group` 중 하나만 지정할 수 있습니다. `user` 는 기존의 명명된 사용자
# 또는 UID를 수용하고, `group` 은 기존의 명명된 그룹 또는 GID를 수용합니다. UID와 GID는
# 반드시 로컬 시스템에 존재할 필요는 없습니다.
# 비어 있는 readers 목록은 런타임 ACL 관리를 비활성화합니다.
readers:
- user: teleport
- user: 123
- group: teleport
- group: 456
memory
memory
목적지 유형은 아티팩트를 프로세스 메모리에 저장합니다. 프로세스가 종료되면 아무것도 지속되지 않습니다. 이 목적지 유형은 임시 환경에 가장 적합하지만, 테스트에도 사용할 수 있습니다.
구성:
# type은 목적지 유형을 지정합니다. memory 목적지의 경우,
# 항상 `memory` 입니다.
type: memory
kubernetes_secret
kubernetes_secret
목적지 유형은 아티팩트를 Kubernetes 비밀에 저장합니다. 이를 통해 Kubernetes에 배포된 다른 컨테이너에 마운트할 수 있습니다.
준비 사항:
tbot
는 최대 하나의 복제로 Kubernetes에서 실행되고 있어야 합니다.deployment
를 사용하는 경우, 항상 단일 인스턴스가 존재하도록Recreate
전략을 사용해야 합니다. 동일한 비밀로 구성된 여러tbot
에이전트가 비밀을 기록하기 위해 경쟁하게 되며, 이로 인해 비밀이 일관되지 않은 상태가 남거나tbot
에이전트가 기록에 실패할 수 있습니다.tbot
포드는 구성된 비밀을 읽고 쓸 수 있는 서비스 계정으로 설정해야 합니다.POD_NAMESPACE
환경 변수를tbot
가 실행 중인 네임스페이스의 이름으로 설정해야 합니다. 이는 Downward API를 사용하여 최적으로 수행됩니다.
비밀이 이미 존재할 필요는 없으며, 존재하지 않으면 생성됩니다. 비밀이 이미 존재하는 경우,
tbot
는 비밀 내의 다른 키를 덮어씁니다.
구성:
# type은 목적지 유형을 지정합니다. kubernetes_secret
# 목적지의 경우, 항상 `kubernetes_secret` 입니다.
type: kubernetes_secret
# name은 아티팩트를 기록할 Kubernetes 비밀의 이름을 지정합니다.
# 이는 `tbot` 가 실행 중인 동일한 네임스페이스에 있어야 합니다.
name: my-secret
Bot 리소스
bot
리소스는 머신 ID 봇을 관리하는 데 사용됩니다. 이는 봇에 부여된 액세스를 구성하는 데 사용됩니다.
kind: bot
version: v1
metadata:
# name은 클러스터에서 봇을 식별하기 위한 고유 식별자입니다.
name: robot
spec:
# roles는 봇이 자격 증명을 생성할 수 있는 역할 목록입니다.
roles:
- editor
# traits는 Bot 사용자에게 적용되는 특성을 제어합니다. 이러한 것은
# 역할 템플릿 시스템에 제공되며, 새로운 역할을 생성하지 않고도 특정 Bot에
# 특정 리소스에 대한 접근을 부여하는 데 사용할 수 있습니다.
traits:
- name: logins
values:
- root
bot
리소스를 정의하는 YAML 파일을 적용할 수 있으며, 이때 tctl create -f ./bot.yaml
을 사용합니다.