Infograb logo
데이터베이스 접근을 위한 머신 ID

Teleport는 데이터베이스에 대한 접근을 보호하고 제어합니다. 머신 ID는 이러한 데이터베이스에 안전하고 단기간 접근할 수 있도록 기계를 제공하는 데 사용될 수 있습니다.

이 가이드에서는 tbot 을 구성하여 Teleport에 설정된 데이터베이스에 접근할 수 있는 자격 증명을 생성하는 방법을 설명합니다.

머신 ID와 데이터베이스 접근
배포
머신 ID와 데이터베이스 접근 배포

전제 조건

  • 실행 중인 Teleport 클러스터 버전 17.0.0-dev 이상. Teleport를 시작하려면 가입하여 무료 평가판을 이용하거나 데모 환경 설정 방법을 확인하십시오.

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

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

  • 이미 데이터베이스를 Teleport 데이터베이스 서비스 뒤에 놓지 않았다면, 데이터베이스 접근 시작 가이드를 따르십시오. Teleport 데이터베이스 서비스는 PostgreSQL, MongoDB, Redis 등을 포함한 데이터베이스를 지원합니다. 전체 목록은 데이터베이스 접근 가이드를 참조하십시오.
  • 연결이 가능한지 확인하기 위해 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 명령어를 실행할 수도 있습니다.
  • 데이터베이스에 접근할 머신에는 tsh 바이너리가 설치되어 있어야 합니다. tbot 이 설치된 방법에 따라 이미 설치되었을 수 있습니다. 설치되지 않았다면, 설치를 참조하십시오.
  • 데이터베이스에 접근할 머신에는 tbot 이 이미 설치되고 구성되어 있어야 합니다. 자세한 내용은 배포 가이드를 참조하십시오.

1/4단계. RBAC 구성

먼저, Teleport는 봇이 생성한 자격 증명이 데이터베이스 서버와 데이터베이스에 접근할 수 있게끔 구성되어야 합니다. 이는 필요한 권한을 부여하는 역할을 생성한 후, 이 역할을 Bot에 할당하여 수행합니다.

다음과 같은 내용으로 role.yaml 이라는 파일을 생성하십시오:

kind: role
version: v6
metadata:
  name: example-role
spec:
  allow:
    db_labels:
      "*": "*"
    db_names: [example-db]
    db_users: [alice]
    rules:
      - resources: [db_server, db]
        verbs: [read, list]

다음을 교체하십시오:

  • example-role 을 사용 사례와 관련된 설명 이름으로 변경하십시오.
  • example-db 를 봇이 접근할 데이터베이스의 이름으로 변경하십시오.
  • alice 를 데이터베이스에 연결할 때 봇이 사용할 사용자 이름으로 변경하십시오.

tctl create -f ./role.yaml 을 사용하여 역할을 생성하십시오.

이제 tctl bots update 를 사용하여 역할을 Bot에 추가합니다. 생성한 봇의 이름을 example 로, 방금 생성한 역할 이름을 example-role 로 교체하십시오:

tctl bots update example --add-roles example-role

이 규칙은 봇이 다음 두 가지 작업을 수행할 수 있게 합니다:

  • 사용자 alice 로 디비 서버에서 데이터베이스 example 에 접근할 수 있습니다 ('*': '*' 레이블 선택기 덕분에).
  • Teleport에서 데이터베이스 리소스에 대한 정보를 검색할 수 있습니다.

'*': '*' 레이블 선택기는 Teleport에 구성된 모든 데이터베이스 서버에 대한 접근을 부여합니다. 운영 환경에서는 더 특정한 레이블 선택기를 사용하여 봇의 접근을 제한하는 것을 고려하십시오. 데이터베이스 관련 역할 옵션에 대한 전체 참조는 데이터베이스 접근 RBAC 가이드를 참조하십시오.

2/4단계. 데이터베이스 tbot 출력 구성

이제 tbot 은 데이터베이스 접근에 필요한 자격 증명을 생성하는 출력을 구성해야 합니다. 이를 위해 database 출력 유형이 사용됩니다.

생성하려는 자격 증명을 위한 데이터베이스는 database 출력의 일부로 구성됩니다. 이는 세 개의 필드를 사용하여 제어됩니다:

  • service 는 자격 증명이 접근을 부여할 Teleport 구성에 명명된 데이터베이스 서비스를 지정합니다.
  • database 는 자격 증명이 접근을 부여할 데이터베이스를 지정합니다.
  • username 은 자격 증명이 접근을 부여할 데이터베이스의 사용자를 지정합니다. 이 필드는 모든 유형의 데이터베이스에 대해 필수적으로 지정할 필요는 없습니다.

또한, 데이터베이스 출력의 format 필드는 생성된 자격 증명의 형식을 제어합니다. 이는 특정 형식을 기대하는 클라이언트와의 호환성을 허용합니다. 이 필드가 지정되지 않으면, 대부분의 클라이언트와 호환되는 합리적인 기본 옵션이 사용됩니다. 지원되는 format 옵션의 전체 목록은 다음과 같습니다:

클라이언트format설명
기본미지정tlscert 에 인증서를 제공하고, key 에 개인 키를 제공하며, teleport-database-ca.crt 에 CA를 제공합니다. 대부분의 클라이언트와 호환됩니다.
MongoDBmongomongo.crtmongo.cas 제공.
CockroachDBcockroachcockroach/node.key , cockroach/node.crt , 및 cockroach/ca.crt 제공.
일반 TLStls특정 파일 확장이 필요한 일반 클라이언트를 위해 tls.key , tls.crt , 및 tls.cas 를 제공합니다.

출력은 목적지를 구성해야 합니다. 이 예제에서는 directory 목적지가 사용됩니다. 이 목적지는 디스크의 지정된 디렉토리에 아티팩트를 씁니다. 이 디렉토리에 대해 tbot 이 실행되는 리눅스 사용자가 쓸 수 있고, 애플리케이션에 접근할 리눅스 사용자가 읽을 수 있는지 확인하십시오.

tbot 구성을 수정하여 database 출력을 추가하십시오:

outputs:
  - type: database
    destination:
      type: directory
      path: /opt/machine-id
    # 연결할 데이터베이스의 세부 정보를 지정합니다.
    service: example-server
    database: example
    username: alice
    # 출력 자격 증명에 사용할 형식을 지정합니다.
    # 대부분의 데이터베이스에 대해 이 구성 필드는 생략할 수 있습니다.
    # format: mongo

tbot 을 백그라운드 서비스로 운영하는 경우, 이를 재시작하십시오. 원샷 모드에서 tbot 을 실행하는 경우, Ansible 플레이북을 실행하기 전에 실행해야 합니다.

3/4단계. 로컬 데이터베이스 접근 프록시 구성

이제 tbot 이 데이터베이스 접근 자격 증명을 생성했으므로, 데이터베이스 클라이언트에서 Teleport Proxy Service로 TLS 연결을 통해 데이터베이스 연결을 전달하도록 로컬 프록시를 설정해야 합니다. 이는 TLS 연결이 Teleport Proxy Service가 프로토콜과 의도된 수신자를 식별할 수 있도록 하기 때문에 필요합니다.

로컬 프록시는 클라이언트가 데이터베이스에 연결해야 하는 한 또는 연결이 여전히 열려 있는 한 실행되고 있어야 합니다. 이 로컬 프록시를 백그라운드에서 실행하는 한 가지 방법은 systemd 서비스를 사용하는 것입니다. 이는 이 단계의 나머지 부분에서 설명되지만, 다른 서비스 관리자나 클라이언트가 실행되는 동안 로컬 프록시를 실행하는 여러 다른 기술을 사용할 수 있습니다.

로컬 프록시는 로컬 루프백 인터페이스에서 지정된 포트를 엽니다. 클라이언트는 localhost에서 이 포트에 연결하도록 구성해야 합니다. 포트가 로컬 루프백 인터페이스에서 열려 있기 때문에 로컬 프록시는 데이터베이스에 연결하려는 클라이언트와 동일한 호스트에서 실행되고 있어야 합니다.

기본적으로 데이터베이스 클라이언트는 로컬 포트에 연결할 때 자격 증명을 사용하도록 구성되어야 합니다. 이는 호스트의 다른 사용자들이 로컬 포트를 통해 데이터베이스에 접근할 수 없도록 보장하며, 데이터베이스 클라이언트와 서버 간의 연결이 로컬호스트에서도 결코 암호화되지 않도록 보장합니다.

이 목적을 위해 systemd 서비스를 생성하려면, /etc/systemd/system/tbot-db-proxy.service 에 유닛 파일을 생성합니다:

[Unit]
Description=Teleport Machine ID Proxy Service
After=network.target
# 이전 가이드를 따라 tbot 자체를 systemd 서비스로 구성한 경우,
# 두 서비스 간의 의존성을 생성하려면 다음 줄의 주석을 제거하십시오.
# Requires=tbot.service

[Service]
Type=simple
# teleport 사용자/그룹이 존재하고
# 대상 디렉토리에 대한 읽기 권한을 갖는지 확인합니다.
User=teleport
Group=teleport
Restart=always
RestartSec=5
# `12345` 를 로컬 루프백 인터페이스에서 무료인 원하시는 포트로 조정하십시오.
# `example-server` 를 teleport의 데이터베이스 서비스 이름으로 조정하십시오.
ExecStart=/usr/local/bin/tbot -c /etc/tbot.yaml proxy --proxy=proxy.example.com:3080 --destination-dir=/opt/machine-id db --port=12345 example-server
ExecReload=/bin/kill -HUP $MAINPID
PIDFile=/run/tbot-db-proxy.pid
LimitNOFILE=8192

[Install]
WantedBy=multi-user.target

이렇게 하면 example-server 데이터베이스 서버에 연결하는 데 사용할 수 있는 로컬 프록시가 12345 포트에서 시작됩니다. 필요에 따라 로컬 설정에 맞게 tbot 매개변수를 사용자 정의하십시오.

마지막으로, 다음 명령을 실행하여 로컬 프록시 서비스를 사용 설정하고 시작하십시오:

sudo systemctl enable tbot-db-proxy
sudo systemctl start tbot-db-proxy
sudo systemctl status tbot-db-proxy

인증된 터널

기본 동작은 클라이언트가 클라이언트 인증서 인증을 사용하도록 요구하지만, 인증된 터널을 구성할 수 있습니다. 이는 로컬 포트에 들어오는 모든 연결에 자격 증명을 자동으로 첨부합니다. 이는 덜 안전하지만, 데이터베이스와 함께 사용할 클라이언트가 클라이언트 인증서 인증을 지원하지 않는 경우 필요할 수 있습니다.

인증된 터널 모드를 활성화하려면, tbot proxy db...와 함께 --tunnel 플래그를 사용합니다.

이것을 포그라운드에서 실행하는 경우, --tunnel 플래그를 제공하십시오. systemd 서비스를 사용하는 경우, machine-id-proxy.serviceExecStart--tunnel 을 추가한 다음 유닛을 다시 로드하십시오.

이것을 활성화한 후에는 구성된 포트에 연결할 때 클라이언트에서 비밀번호나 TLS 인증서 및 인증 기관을 지정할 필요가 없습니다.

4/4단계. 데이터베이스에 연결하기 위해 클라이언트 구성

생성된 자격 증명과 로컬 프록시가 실행 중이므로, 이제 자격 증명을 사용하여 로컬 프록시를 활용하도록 클라이언트를 구성할 수 있습니다.

자격 증명을 사용하는 샘플 Go 프로그램을 참조하세요:

// This example program demonstrates how to connect to a Postgres database
// using certificates issued by Teleport Machine ID.

package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/jackc/pgx/v4/stdlib"
)

func main() {
	// Open connection to database.
	db, err := sql.Open("pgx", fmt.Sprint(
		"host=localhost ",
		"port=1234 ",
		"dbname=example ",
		"user=alice ",
		// The next four options should be omitted if the local proxy has been
		// placed in "authenticated tunnel" mode.
		"sslmode=verify-full ",
		"sslrootcert=/opt/machine-id/teleport-host-ca.crt ",
		"sslkey=/opt/machine-id/key ",
		"sslcert=/opt/machine-id/tlscert ",
	))
	if err != nil {
		log.Fatalf("Failed to open database: %v.", err)
	}

	defer db.Close()

	// Call "Ping" to test connectivity.
	err = db.Ping()
	if err != nil {
		log.Fatalf("Failed to Ping database: %v.", err)
	}

	log.Printf("Successfully connected to PostgreSQL.")
}

// This example program demonstrates how to connect to a MongoDB database
// using certificates issued by Teleport Machine ID.

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	// Create client and connect to MongoDB. Make sure to modify the host,
	// port, and certificate paths.
	uri := fmt.Sprintf(
		"mongodb://localhost:1234/?tlsCAFile=%s&tlsCertificateKeyFile=%s",
		"/opt/machine-id/mongo.cas",
		"/opt/machine-id/mongo.crt",
	)
	client, err := mongo.NewClient(options.Client().ApplyURI(uri))
	if err != nil {
		log.Fatalf("Failed to create database client: %v.", err)
	}
	err = client.Connect(ctx)
	if err != nil {
		log.Fatalf("Failed to connect to database: %v.", err)
	}

	defer client.Disconnect(ctx)

	log.Printf("Successfully connected to MongoDB.")

	// List databases to test connectivity.
	databases, err := client.ListDatabaseNames(ctx, bson.M{})
	if err != nil {
		log.Fatalf("Failed to list databases: %v.", err)
	}
	log.Println(databases)

}

모든 준비가 완료되었습니다. 데이터베이스에 접근할 수 있는 기계 신원에 연결된 단기 인증서를 애플리케이션에 제공하였으며, 이러한 인증서는 회전 가능하고 감사 가능하며, 모든 익숙한 Teleport 접근 제어로 관리됩니다.

다음 단계

  • 사용 가능한 모든 구성 옵션을 탐색하기 위해 구성 참조를 읽으세요.
Teleport 원문 보기