Infograb logo
머신 ID 구성 참조

이 참조 문서는 tbot 구성 파일에서 구성할 수 있는 다양한 옵션을 문서화합니다. 이 구성 파일은 CLI 매개변수만으로 tbot을 구성하는 것보다 더 많은 제어를 제공합니다.

tbot을 구성 파일을 사용하도록 설정하려면 -c 플래그와 함께 경로를 지정하십시오:

tbot -c ./tbot.yaml

이 참조에서 artifact라는 용어는 tbot이 결과물을 생성하는 과정의 일환으로 목적지에 작성하는 항목을 나타냅니다. 아티팩트의 예로는 구성 파일, 인증서 및 암호화 키 재료가 있습니다. 일반적으로 아티팩트는 파일이지만, 이 용어는 목적지가 반드시 파일 시스템일 필요는 없으므로 명시적으로 피합니다.

Teleport 14부터 tbot은 v2 구성 버전을 지원합니다.

# version은 사용 중인 구성 파일의 버전을 지정합니다. `v2`는
# 가장 최근 버전이며 모든 신규 봇에 사용해야 합니다. 이 예제의 나머지 부분은
# `v2` 스키마입니다.
version: v2

# debug는 stderr에 자세한 로깅을 활성화합니다. 지정하지 않으면 기본값은
# false입니다.
debug: true

# auth_server는 `tbot`이 연결해야 하는 인증 서비스 인스턴스의 주소를 지정합니다.
# 프록시 서비스 주소를 지정하기 위해 `proxy_server`를 사용하는 것이 좋습니다.
auth_server: "teleport.example.com:3025"

# proxy_server는 `tbot`이 연결해야 하는 Teleport 프록시 서비스의 주소를 지정합니다.
# Teleport 클라우드를 사용하는 경우 Teleport 클라우드 인스턴스의 주소를 사용하는 것이 좋습니다.
proxy_server: "teleport.example.com:443" # 또는 Teleport 클라우드의 경우 "example.teleport.sh:443"

# certificate_ttl은 `tbot`이 생성한 인증서의 유효 기간을 지정합니다.
# 이는 양의 숫자 값이어야 하며 `m`(분) 또는 `h`(시간) 접미사가 있어야 합니다. 기본적으로 이 값은 `1h`입니다.
# 최대 값은 `24h`입니다.
certificate_ttl: "1h"

# renewal_interval은 `tbot`이 생성한 출력물을 갱신하기 위해 aim해야 하는 빈도를 지정합니다.
# 이는 양의 숫자 값이어야 하며 `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`
  join_method: "token"

  # ca_pins는 첫 번째 연결 시 Teleport 인증 서비스의 신원을 확인하는 데 사용됩니다.
  # Teleport 클라우드를 사용하거나 Teleport 프록시를 통해 연결할 때는 이 값을 지정하지 않아야 합니다.
  ca_pins:
    - "sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678"
    - "sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678"

  # ca_path는 첫 번째 연결 시 Teleport 인증 서비스의 신원을 확인하는 데 사용할 수 있는 CA 파일의 위치를 지정하는 데 사용됩니다.
  # Teleport 클라우드를 사용하거나 Teleport 프록시를 통해 연결할 때는 이 값을 지정하지 않아야 합니다. ca_pins 옵션이 ca_path보다 선호되어야 합니다.
  ca_path: "/path/to/ca.pem"

# storage는 `tbot`이 내부 상태를 저장하는 데 사용할 목적지를 지정합니다. 
# 이 상태는 민감하며, 여기에서 지정한 목적지는 오직 `tbot`만 접근할 수 있도록 해야 합니다.
#
# 지정하지 않은 경우, storage는 `/var/lib/teleport/bot` 경로의 디렉토리로 설정됩니다.
#
# 이 참조 페이지의 Destinations 섹션 아래에서 지원되는 목적지 및 그 구성 옵션의 전체 목록을 참조하십시오.
storage:
  type: directory
  path: /var/lib/teleport/bot

# outputs는 `tbot`이 실행될 때 생성하고 갱신해야 하는 아티팩트를 지정합니다.
#
# 이 참조 페이지의 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 출력은 다음과 같은 인증을 위해 사용할 수 있습니다:

  • SSH 접근을 Teleport 서버에, tsh, openssh 및 ansible과 같은 도구를 사용합니다.
  • tsh 또는 tctl과 같은 도구를 사용하여 클러스터에 대한 관리 작업.
  • Teleport Terraform 공급자를 사용하여 Teleport 리소스 관리.
  • Teleport API에 접근하기 위한 Teleport Go SDK를 사용합니다.

시작하기 가이드를 참조하여 identity 출력을 컨텍스트에서 사용합니다.

# type은 출력의 유형을 지정합니다. identity 출력의 경우,
# 항상 `identity`가 됩니다.
type: identity

# 다음 구성 필드는 대부분의 출력 유형에서 사용할 수 있습니다.

# destination은 출력이 생성된 아티팩트를 쓸 위치를 지정합니다
# 인증서 및 구성 파일과 같은.
#
# 지원되는 목적지 및 해당 구성 옵션의 전체 목록은
# 이 참조 페이지의 목적지 섹션에서 확인하십시오.
destination:
  type: directory
  path: /opt/machine-id
# roles는 출력에 의해 생성된 인증서에 포함되어야 하는 역할을 지정합니다.
# 이러한 역할은 봇이 가장할 수 있는 권한을 부여받은 역할이어야 합니다.
#
# 역할이 지정되지 않으면 봇이 가장할 수 있는 모든 역할이 사용됩니다.
roles:
  - editor

application

application 출력은 Teleport로 구성된 애플리케이션에 접근하는 데 사용할 수 있는 자격 증명을 생성하는 데 사용됩니다.

애플리케이션 접근을 위한 머신 ID 가이드를 참조하여 application 출력을 컨텍스트에서 사용하는 방법을 확인하십시오.

# type은 출력의 유형을 지정합니다. application 출력의 경우,
# 항상 `application`이 됩니다.
type: application
# app_name은 `tbot`이 자격 증명을 생성해야 하는 Teleport 클러스터에서 구성된 애플리케이션 이름입니다.
# 이 필드는 반드시 지정해야 합니다.
app_name: grafana

# 다음 구성 필드는 대부분의 출력 유형에서 사용할 수 있습니다.

# destination은 출력이 생성된 아티팩트를 쓸 위치를 지정합니다
# 인증서 및 구성 파일과 같은.
#
# 지원되는 목적지 및 해당 구성 옵션의 전체 목록은
# 이 참조 페이지의 목적지 섹션에서 확인하십시오.
destination:
  type: directory
  path: /opt/machine-id
# roles는 출력에 의해 생성된 인증서에 포함되어야 하는 역할을 지정합니다.
# 이러한 역할은 봇이 가장할 수 있는 권한을 부여받은 역할이어야 합니다.
#
# 역할이 지정되지 않으면 봇이 가장할 수 있는 모든 역할이 사용됩니다.
roles:
  - editor

database

database 출력은 Teleport로 구성된 데이터베이스에 접근하기 위해 사용할 수 있는 자격 증명을 생성하는 데 사용됩니다.

데이터베이스 접근을 위한 머신 ID 가이드를 참조하여 database 출력을 문맥에서 사용하는 방법을 확인하십시오.

# type은 출력의 유형을 지정합니다. database 출력의 경우,
# 항상 `database`가 됩니다.
type: database
# service는 출력가 자격 증명을 생성해야 하는 Teleport에서 구성된 데이터베이스 서버의 이름입니다.
# 이 필드는 반드시 지정해야 합니다.
service: my-postgres-server
# database는 특정 데이터베이스의 이름이며,
# 이 필드는 개별 데이터베이스가 없을 경우 지정할 필요가 없습니다.
database: my-database
# username은 지정된 데이터베이스 서버에서 자격 증명을 생성해야 할 사용자의 이름입니다.
# 이 필드는 사용자가 없는 데이터베이스 유형에 대해서는 지정할 필요가 없습니다.
username: my-user
# format은 출력 아티팩트를 위해 사용할 형식을 지정합니다. 
# 지정하지 않으면 기본 형식이 사용됩니다. 전체 지원 값 목록은 아래의 "지원되는 형식" 테이블을 참조하십시오.
format: tls

# 다음 구성 필드는 대부분의 출력 유형에서 사용할 수 있습니다.

# destination은 출력이 생성된 아티팩트를 쓸 위치를 지정합니다
# 인증서 및 구성 파일과 같은.
#
# 지원되는 목적지 및 해당 구성 옵션의 전체 목록은
# 이 참조 페이지의 목적지 섹션에서 확인하십시오.
destination:
  type: directory
  path: /opt/machine-id
# roles는 출력에 의해 생성된 인증서에 포함되어야 하는 역할을 지정합니다.
# 이러한 역할은 봇이 가장할 수 있는 권한을 부여받은 역할이어야 합니다.
#
# 역할이 지정되지 않으면 봇이 가장할 수 있는 모든 역할이 사용됩니다.
roles:
  - editor

지원되는 형식

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 클러스터에 접근하는 데 사용할 수 있는 자격 증명을 생성하는 데 사용됩니다.

출력 목적지에서 kubeconfig.yaml를 출력하여 kubectl과 함께 사용할 수 있습니다.

쿠버네티스 접근을 위한 머신 ID 가이드를 참조하여 맥락에서 kubernetes 출력을 사용하는 방법을 확인하십시오.

# type은 출력의 유형을 지정합니다. kubernetes 출력의 경우,
# 항상 `kubernetes`가 됩니다.
type: kubernetes
# kubernetes_cluster는 출력이 자격 증명과 kubeconfig를 생성해야 할 Teleport에서 구성된 Kubernetes 클러스터의 이름입니다.
# 이 필드는 반드시 지정해야 합니다.
kubernetes_cluster: my-cluster

# 다음 구성 필드는 대부분의 출력 유형에서 사용할 수 있습니다.

# destination은 출력이 생성된 아티팩트를 쓸 위치를 지정합니다
# 인증서 및 구성 파일과 같은.
#
# 지원되는 목적지 및 해당 구성 옵션의 전체 목록은
# 이 참조 페이지의 목적지 섹션에서 확인하십시오.
destination:
  type: directory
  path: /opt/machine-id
# roles는 출력에 의해 생성된 인증서에 포함되어야 하는 역할을 지정합니다.
# 이러한 역할은 봇이 가장할 수 있는 권한을 부여받은 역할이어야 합니다.
#
# 역할이 지정되지 않으면 봇이 가장할 수 있는 모든 역할이 사용됩니다.
roles:
  - editor

ssh_host

ssh_host 출력은 Teleport로 OpenSSH 서버를 구성하는 데 필요한 아티팩트를 생성하는 데 사용됩니다,

출력은 다음과 같은 아티팩트를 생성합니다:

  • 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

# 다음 구성 필드는 대부분의 출력 유형에서 사용할 수 있습니다.

# destination은 출력이 생성된 아티팩트를 쓸 위치를 지정합니다
# 인증서 및 구성 파일과 같은.
#
# 지원되는 목적지 및 해당 구성 옵션의 전체 목록은
# 이 참조 페이지의 목적지 섹션에서 확인하십시오.
destination:
  type: directory
  path: /opt/machine-id
# roles는 출력에 의해 생성된 인증서에 포함되어야 하는 역할을 지정합니다.
# 이러한 역할은 봇이 가장할 수 있는 권한을 부여받은 역할이어야 합니다.
#
# 역할이 지정되지 않으면 봇이 가장할 수 있는 모든 역할이 사용됩니다.
roles:
  - editor

spiffe-svid

spiffe-svid 출력은 SPIFFE X509 SVID를 생성하고 이를 구성된 목적지에 작성하는 데 사용됩니다.

출력은 다음과 같은 아티팩트를 생성합니다:

  • svid.pem: X509 SVID입니다.
  • svid.key: X509 SVID와 연관된 개인 키입니다.
  • bundle.pem: 신뢰 도메인 CA가 포함된 X509 번들입니다.

SPIFFE SVID의 사용법에 대한 더 많은 정보는 워크로드 아이덴티티를 참조하십시오.

# type은 출력의 유형을 지정합니다. SPIFFE SVID 출력의 경우,
# 항상 `spiffe-svid`가 됩니다.
type: spiffe-svid
# svid는 요청해야 하는 SPIFFE SVID의 속성을 지정합니다.
svid:
  # path는 요청해야 하는 SPIFFE ID의 path 요소를 지정합니다.
  path: /svc/foo
  # sans는 생성된 X509 SVID에 포함될 선택적 주체 대안 이름(SAN)을 지정합니다.
  # 생략하면 포함되지 않습니다.
  sans:
    # dns는 생략하면 포함되지 않는 DNS SAN을 지정합니다.
    dns:
      - foo.svc.example.com
    # ip는 생략하면 포함되지 않는 IP SAN을 지정합니다.
    ip:
      - 10.0.0.1
# 다음 구성 필드는 대부분의 출력 유형에서 사용할 수 있습니다.

# destination은 출력이 생성된 아티팩트를 쓸 위치를 지정합니다
# 인증서 및 구성 파일과 같은.
#
# 지원되는 목적지 및 해당 구성 옵션의 전체 목록은
# 이 참조 페이지의 목적지 섹션에서 확인하십시오.
destination:
  type: directory
  path: /opt/machine-id
# roles는 출력에 의해 생성된 인증서에 포함되어야 하는 역할을 지정합니다.
# 이러한 역할은 봇이 가장할 수 있는 권한을 부여받은 역할이어야 합니다.
#
# 역할이 지정되지 않으면 봇이 가장할 수 있는 모든 역할이 사용됩니다.
roles:
  - editor

서비스

서비스는 tbot 내에서 실행되는 구성 가능한 장기 구성 요소입니다. 출력과 달리, 반드시 아티팩트를 생성하지 않을 수도 있습니다. 일반적으로 서비스는 기계 간 접근을 위한 지원 기능을 제공합니다. 예를 들어, 터널을 열거나 API를 제공하는 것입니다.

spiffe-workload-api

spiffe-workload-api 서비스는 SPIFFE Workload API를 구현하는 서비스에 대한 수신기를 엽니다. 이 서비스는 작업 부하에 SVID를 제공합니다.

워크로드 아이덴티티를 참조하여 SPIFFE Workload API에 대한 더 많은 정보를 확인하십시오.

# 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에 대한 워크로드 인증을 구성할 수 있습니다.
attestors:
  # kubernetes는 Kubernetes 워크로드 인증자의 구성을 위한 것입니다.
  # Kubernetes 워크로드 인증자 섹션에서 자세한 정보를 확인하십시오.
  kubernetes:
    # enabled는 Kubernetes 워크로드 인증자를 활성화해야 하는지 여부를 지정합니다.
    # 지정하지 않으면 기본값은 false입니다.
    enabled: true
    # kubelet은 Kubernetes 워크로드 인증자가 Kubelet API와 상호작용하는 것과 관련된 구성을 보유합니다.
    kubelet:
      # read_only_port는 Kubelet API가 읽기 전용 작업을 위해 노출되는 포트입니다.
      # Kubernetes 1.16 이후로는 기본적으로 읽기 전용 포트가 비활성화되어 있으며 secure_port가 대신 사용되어야 합니다.
      read_only_port: 10255
      # secure_port는 인증자가 Kubelet 보안 API에 연결해야 하는 포트입니다. 
      # 지정하지 않으면 기본값은 `10250`입니다. 읽기 전용 포트와 상호 배타적입니다.
      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는 워크로드 API가 제공해야 하는 SPIFFE SVID를 지정합니다.
svids:
    # path는 요청해야 하는 SPIFFE ID의 path 요소를 지정합니다.
  - path: /svc/foo
    # hint는 여러 개의 SVID이 있는 경우, 워크로드가 선택할 SVID를 선택하는 데 도움을 주기 위해 사용할 수 있는 자유 형식의 문자열입니다.
    # 생략하면 포함되지 않습니다.
    hint: my-hint
    # sans는 생성된 X509 SVID에 포함될 선택적 주체 대안 이름(SAN)을 지정합니다.
    # 생략하면 포함되지 않습니다.
    sans:
      # dns는 생략하면 포함되지 않는 DNS SAN을 지정합니다.
      dns:
        - foo.svc.example.com
      # ip는 생략하면 포함되지 않는 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는 SPIFFE가 활성화되어 있지 않은 워크로드의 아웃바운드 연결에 X.509 SVID를 부착하는 데 사용될 수 있습니다.

역 프록시로서, Envoy는 SPIFFE가 활성화된 클라이언트의 mTLS 연결을 종료하는 데 사용될 수 있습니다. Envoy는 클라이언트가 유효한 X.509 SVID를 제공했는지 확인하고 SVID에 포함된 SPIFFE ID를 기반으로 권한 부여 정책을 시행하는 데 사용됩니다.

특정 프로토콜에 대한 역 프록시로 작동할 때, Envoy는 서비스로 전달하기 전에 요청에 클라이언트의 신원을 나타내는 헤더를 추가하도록 구성될 수 있습니다. 이를 통해 서비스에서 클라이언트의 신원에 따라 권한 부여 결정을 내릴 수 있습니다.

Envoy를 SDS API를 사용하여 구성할 때, 다음 세 가지 특수 이름을 구성에 도움을 주기 위해 사용할 수 있습니다:

  • default: tbot는 워크로드의 기본 SVID를 반환합니다.
  • ROOTCA: tbot은 워크로드가 소속된 신뢰 도메인의 신뢰 번들을 반환합니다.
  • ALL: tbot은 워크로드가 소속된 신뢰 도메인의 신뢰 번들과 신뢰 도메인이 연합된 모든 신뢰 번들을 반환합니다.

다음은 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
                # 결합된 검증 컨텍스트는 두 개의 검증 컨텍스트를 결합합니다.
                # 이는 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" # 이는 신뢰 도메인 이름으로도 바꿀 수 있습니다.
  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 소켓: `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 애플리케이션 모두를 지원합니다. 이는 클라이언트 인증서를 사용할 수 없는 애플리케이션의 경우 유용하며, TCP 애플리케이션이거나 Teleport 프록시 앞에 L7 로드 밸런서를 두는 경우에는 더욱 그렇습니다.

터널은 클라이언트에 대한 연결을 인증하므로, 리스너에 연결하는 모든 클라이언트는 애플리케이션에 접근할 수 있습니다. 이러한 이유로, 리스너가 의도된 클라이언트만 접근할 수 있도록 Unix 소켓 리스너를 사용하거나 127.0.0.1에 바인딩하도록 해야 합니다.

# type은 애플리케이션 터널 서비스의 유형을 지정합니다. 
# 애플리케이션 터널 서비스의 경우, 항상 `application-tunnel`이 됩니다.
type: application-tunnel
# listen은 서비스가 수신해야 하는 주소를 지정합니다.
#
# 두 가지 유형의 리스너가 지원됩니다:
# - TCP: `tcp://<address>:<port>`
# - Unix 소켓: `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-multiplexer는 SSH 에이전트 프로토콜을 구현하는 소켓을 열어 SSH 클라이언트가 개인 키를 디스크에 쓰지 않고도 인증할 수 있도록 합니다.

기본적으로 ssh-multiplexer 서비스는 생성된 SSH 구성에서 멀티플렉서를 사용하도록 구성된 ssh_config를 출력합니다. fdpass-teleport 바이너리를 설치하고 지정함으로써 SSH 연결의 자원 소모를 더욱 줄일 수 있습니다.

# type은 SSH 멀티플렉서 서비스의 유형을 지정합니다. 
# SSH 멀티플렉서 서비스의 경우, 항상 `ssh-multiplexer`가 됩니다.
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 멀티플렉서가 실행 중인 프로세스가 접근할 수 있어야 합니다.
#
# 지정하지 않으면 프록시 템플릿은 사용되지 않습니다.
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 Unix 도메인 소켓은 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 Unix 도메인 소켓에 연결
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는 CA와 함께 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"

    // 에이전트 및 Known Hosts 설정
    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,
    }

    // Unix 도메인 소켓에 연결하고 멀티플렉스 요청 전송
    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

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 리소스는 머신 ID 봇을 관리하는 데 사용됩니다. 이는 봇에 부여된 액세스를 구성하는 데 사용됩니다.

kind: 
version: v1
metadata:
  # 이름은 클러스터에서 봇의 고유 식별자입니다.
  name: 로봇
spec:
  # 역할은 봇이 자격 증명을 생성할 수 있는 역할 목록입니다.
  roles:
  - 편집자
  # 특성은 봇 사용자에게 적용되는 특성을 제어합니다. 이러한 특성은 
  # 역할 템플릿 시스템에 제공되며, 새로운 역할을 생성하지 않고
  # 특정 봇에 특정 리소스에 대한 액세스를 부여하는 데 사용할 수 있습니다.
  traits:
  - name: 로그인
    values:
    - 루트

tctl create -f ./bot.yaml를 사용하여 bot 리소스를 정의하는 YAML 파일을 적용할 수 있습니다.

Teleport 원문 보기