Infograb logo
머신 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설명
Unspecifiedtlscert 형식의 인증서, key 형식의 개인 키 및 teleport-database-ca.crt 에서 CA를 제공합니다. 이는 대부분의 클라이언트 및 데이터베이스와 호환됩니다.
mongomongo.crtmongo.cas 를 제공합니다. 이는 MongoDB 클라이언트와 함께 사용하도록 설계되었습니다.
cockroachcockroach/node.key , cockroach/node.crtcockroach/ca.crt 를 제공합니다. 이는 CockroachDB 클라이언트와 함께 사용하도록 설계되었습니다.
tlstls.key , tls.crttls.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 을 사용합니다.

Teleport 원문 보기