인포레터에서 최신 DevOps 트렌드를 격주로 만나보세요!
데이터베이스 접근을 위한 머신 ID
Teleport는 데이터베이스에 대한 접근을 보호하고 제어합니다. 머신 ID는 이러한 데이터베이스에 안전하고 단기간 접근할 수 있도록 기계를 제공하는 데 사용될 수 있습니다.
이 가이드에서는 tbot
을 구성하여 Teleport에 설정된 데이터베이스에
접근할 수 있는 자격 증명을 생성하는 방법을 설명합니다.
전제 조건
-
실행 중인 Teleport 클러스터 버전 17.0.0-dev 이상. Teleport를 시작하려면 가입하여 무료 평가판을 이용하거나 데모 환경 설정 방법을 확인하십시오.
-
tctl
관리자 도구와tsh
클라이언트 도구.tctl
및tsh
다운로드 방법에 대한 지침은 설치를 방문하십시오.
- 이미 데이터베이스를 Teleport 데이터베이스 서비스 뒤에 놓지 않았다면, 데이터베이스 접근 시작 가이드를 따르십시오. Teleport 데이터베이스 서비스는 PostgreSQL, MongoDB, Redis 등을 포함한 데이터베이스를 지원합니다. 전체 목록은 데이터베이스 접근 가이드를 참조하십시오.
- 연결이 가능한지 확인하기 위해
tsh login
으로 로그인한 다음, 현재 자격 증명을 사용하여tctl
명령어를 실행할 수 있는지 확인하십시오. 예를 들어:클러스터에 연결할 수 있고tsh login --proxy=teleport.example.com --user=email@example.comtctl 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를 제공합니다. 대부분의 클라이언트와 호환됩니다. |
MongoDB | mongo | mongo.crt 및 mongo.cas 제공. |
CockroachDB | cockroach | cockroach/node.key , cockroach/node.crt , 및 cockroach/ca.crt 제공. |
일반 TLS | tls | 특정 파일 확장이 필요한 일반 클라이언트를 위해 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-proxysudo systemctl start tbot-db-proxysudo systemctl status tbot-db-proxy
인증된 터널
기본 동작은 클라이언트가 클라이언트 인증서 인증을 사용하도록 요구하지만, 인증된 터널을 구성할 수 있습니다. 이는 로컬 포트에 들어오는 모든 연결에 자격 증명을 자동으로 첨부합니다. 이는 덜 안전하지만, 데이터베이스와 함께 사용할 클라이언트가 클라이언트 인증서 인증을 지원하지 않는 경우 필요할 수 있습니다.
인증된 터널 모드를 활성화하려면, tbot proxy db...
와 함께 --tunnel
플래그를 사용합니다.
이것을 포그라운드에서 실행하는 경우, --tunnel
플래그를 제공하십시오. systemd 서비스를 사용하는 경우, machine-id-proxy.service
의 ExecStart
에 --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 접근 제어로 관리됩니다.
다음 단계
- 사용 가능한 모든 구성 옵션을 탐색하기 위해 구성 참조를 읽으세요.