데이터베이스 접근 문제 해결
Teleport v18.9이 페이지에서는 Teleport로 데이터베이스를 등록할 때 발생하는 일반적인 문제와 이를 우회하거나 해결하는 방법을 설명합니다. 데이터베이스 연결 시도가 **"dial tcp ... Teleport Database Service는 데이터베이스 엔드포인트로의 연결이 필요합니다.
이 페이지에서는 Teleport로 데이터베이스를 등록할 때 발생하는 일반적인 문제와 이를 우회하거나 해결하는 방법을 설명합니다.
연결 시도 실패#
타임아웃 오류#
데이터베이스 연결 시도가 **"dial tcp ... i/o timeout"**과 유사한 메시지와 함께 실패합니다.
Teleport Database Service는 데이터베이스 엔드포인트로의 연결이 필요합니다.
방화벽 규칙(예: AWS 보안 그룹)이 Teleport Database Service와 데이터베이스 엔드포인트 간의 연결을 허용하는지 확인하세요.
- 데이터베이스에 대한 인바운드 방화벽 규칙은 Teleport Database Service로부터의 연결을 허용해야 합니다.
- Teleport Database Service에 대한 아웃바운드 방화벽 규칙은 데이터베이스 엔드포인트로의 연결을 허용해야 합니다.
Teleport Database Service와 동일한 호스트에서 nc를 실행하여 데이터베이스 포트에 도달할 수 있는지 확인해 보세요.
- 데이터베이스 호스트:
postgres-instance-1.sadas.us-east-1.rds.amazonaws.com - 데이터베이스 포트:
5432
$ nc -zv database-host database-port
# Connection to postgres-instance-1.sadas.us-east-1.rds.amazonaws.com (172.31.24.172) 5432 port [tcp/postgresql] succeeded!
AWS에서 연결 시간 초과 오류 디버깅
AWS 배포의 경우, AWS Reachability Analyzer를 사용하여 Teleport Database Service와 데이터베이스 간의 네트워크 경로를 분석하는 것이 도움이 될 수 있습니다.
- Teleport Database Service 호스트와 연결된 Elastic Network Interface(ENI)를 식별합니다. 이는 EC2 console에서 확인할 수 있습니다.
- 데이터베이스의 프라이빗 IP 주소를 식별합니다.
- 네트워크 경로를 생성하고 분석합니다:
- 경로 소스를 Teleport Database Service 호스트와 연결된 ENI로 설정합니다.
- 경로 대상을 데이터베이스 IP로 설정합니다.
- 분석 결과를 확인하여 도달성 문제를 식별합니다.
데이터베이스가 동적으로 또는 자동 검색을 통해 등록된 경우, 이 데이터베이스를
프록시하는 모든* Teleport Database Service 인스턴스에 대해 위의 연결
테스트를 반복하세요. 주어진 데이터베이스와 연결된 모든 Teleport Database
Service 인스턴스를 나열하려면 tctl get db_server/<db_name> 명령을
실행하세요. 예를 들어:
$ tctl get db_server/postgres-instance-1 --format json | jq '.[] | {hostname: .spec.hostname, host_id: .spec.host_id, version: .spec.version, target_health: .status.target_health}'
{
"hostname": "ip-10-0-0-111.ca-central-1.compute.internal",
"host_id": "e5e670ac-a7b8-44ef-b373-6296d87f50e8",
"version": "18.3.0",
"target_health": {
"status": "unhealthy",
...
}
}
{
"hostname": "ip-10-0-0-222.ca-central-1.compute.internal",
...
}
여기에 나열된 Database Service 인스턴스 중 데이터베이스를 프록시해서는
안 되는 인스턴스가 있는 경우(예: 연결이 되지 않는 다른 VPC 또는 AWS
리전에 있는 Database Service 인스턴스), 해당 구성을 찾아 도달할 수 있는
데이터베이스만 수신하거나 검색하도록 업데이트하세요. 대부분의 경우
vpc-id 레이블을 추가하는 등 태그 필터를 세분화하여 이를 달성할 수 있습니다.
인증서가 만료되었거나 아직 유효하지 않음#
데이터베이스 연결 시도가 실패하고, 반환되는 오류 메시지는 다음과 유사합니다: "Database service could not validate database's certificate: certificate expired."
해결 방법: 데이터베이스 인증서를 갱신하세요.
Teleport Database Service는 Teleport가 발급한 인증서를 사용하여 데이터베이스와 인증을 수행합니다. 이 오류는 Teleport가 인증에 실패할 때 발생하며, 대개 인증서 만료가 원인입니다.
새 인증서를 생성할 때 사용하는 명령어는 tctl auth sign입니다. 예를 들어
PostgreSQL용 인증서를 생성하는 명령어는 다음과 같습니다:
# Export Teleport's certificate authority and a generated certificate/key pair
# for host db.example.com with a 3-month validity period.
$ tctl auth sign --format=db --host=db.example.com --out=server --ttl=2190h
이 예시에서 db.example.com은 Teleport Database Service가 PostgreSQL 서버에
접근할 수 있는 호스트명입니다.
각 데이터베이스는 서로 다른 형식을 사용합니다. 자세한 내용과 예시는 해당 데이터베이스 가이드에서 확인할 수 있습니다:
새 인증서가 발급된 후에는 데이터베이스를 업데이트하여 적용해야 합니다.
db에 대한 접근이 거부됨#
데이터베이스 연결 시도가 다음과 유사한 오류 메시지와 함께 실패합니다: "access to db denied"
해결 방법: 사용자에게 접근을 허용하도록 데이터베이스 인스턴스와 Teleport 역할 기반 접근 제어(RBAC)를 구성하세요.
tsh를 통해 접근하려는 데이터베이스 사용자와 데이터베이스 이름(일명 스키마)이
해당 데이터베이스 인스턴스에 존재하는지 확인하세요. "데이터베이스 이름" 또는
db_names를 언급할 때, 이는 Database Service 구성의 db_service 섹션에 있는
name 필드와 같은 것이 아닙니다. 이는 특정 데이터베이스 인스턴스 내의
데이터베이스 이름 또는 스키마를 가리키는 것입니다.
데이터베이스 인스턴스가 구성되면, 접근을 허용하도록 Teleport RBAC를 구성해야
합니다. Teleport 사용자에게 데이터베이스 사용자, 데이터베이스 이름, 그리고
해당 데이터베이스의 Teleport 정적 또는 동적 라벨과 일치하는 db_users,
db_names, db_labels를 **허용(allow)**하는 역할을 할당하세요. 또한 사용자가
해당하는 db_users, db_names, db_labels를 **거부(deny)**하는 역할을 갖고
있지 않은지도 확인하세요.
데이터베이스 이름은 PostgreSQL 및 MongoDB 데이터베이스에서만 적용됩니다.
PostgreSQL 또는 MongoDB 인스턴스에 연결할 때는 반드시 --db-name을
지정하세요:
$ tsh db connect --db-user=exampleuser --db-name=exampledb
예를 들어 다음 user와 role 리소스는 Teleport 사용자 alice@example.com이
admin 데이터베이스 사용자나 postgres 데이터베이스 이름을 제외한 프로덕션
데이터베이스 내의 모든 데이터베이스 이름 또는 데이터베이스 사용자에 접근할 수
있도록 허용합니다:
kind: role
version: v5
metadata:
name: db-developer
description: "Example role that grants restricted access to production databases"
spec:
allow:
db_labels:
environment: ["prod"] # for this example, assume production databases have this label in your Teleport cluster
db_users: ["{{internal.db_users}}"]
db_names: ["{{internal.db_names}}"]
deny:
db_users: ["admin"]
db_names: ["postgres"]
---
kind: user
metadata:
name: alice@example.com
spec:
roles: ["db-developer"]
traits:
db_users: ["*"]
db_names: ["*"]
internal.db_users와 internal.db_names 트레이트는 Teleport 로컬 사용자
데이터베이스의 값으로 대체됩니다. Teleport 역할에서 트레이트가 작동하는 방식에
대한 자세한 내용은 Access Controls Reference를
참조하세요.
이제 Alice에게 더 관대한 접근 권한을 부여하고 싶다고 가정해 보겠습니다.
이 예시를 간단하게 유지하기 위해, Alice에게 다른 역할을 할당해 보겠습니다.
Alice의 역할을 모든 리소스에 대한 접근을 허용하는 기본 Teleport 역할인
access만 포함하도록 업데이트하세요. tctl users update 또는 tctl create를
사용하여 명령줄에서 사용자의 역할을 업데이트할 수 있습니다:
$ tctl users update alice@example.com --set-roles=access
텍스트 편집기에서 Alice의 사용자 리소스를 엽니다:
$ tctl edit users/alice@example.com
그런 다음 access 역할을 할당하도록 리소스를 수정합니다:
kind: user
metadata:
name: alice@example.com
spec:
roles: ["access"]
traits:
db_users: ["*"]
db_names: ["*"]
변경 사항을 적용하려면 파일을 저장하고 닫으세요.
이제 Alice는 어떤 데이터베이스 사용자나 데이터베이스 이름을 사용하더라도 Teleport 클러스터 내의 모든 데이터베이스에 연결할 수 있습니다.
이 예시는 의도적으로 단순하게 구성되었습니다. 더 세분화된 제어를 사용하여 Alice의 권한을 구성할 수도 있었습니다. 데이터베이스 접근 제어 및 접근 제한 방법에 대한 자세한 내용은 RBAC 문서를 참조하세요.
MySQL 데이터베이스 연결 시 "Unknown system variable 'query_cache_size'" 오류 발생#
TLS 라우팅이 기본적으로 비활성화되어 있을 때, Teleport Proxy Service는 MySQL
서버 버전으로 8.0.0-Teleport를 반환합니다. GUI 클라이언트로 연결하는 등의
일부 경우, 이로 인해 MySQL 클라이언트와 서버 간에 MySQL 기능이 제대로
협상되지 않았음을 나타내는 Unknown system variable 'query_cache_size' 오류가
발생할 수 있습니다.
이 문제를 해결하는 한 가지 방법은 TLS 라우팅 기능을 사용하는 것입니다. 이 경우 Teleport Proxy Service가 TLS 라우팅 확장을 통해 올바른 MySQL 서버 버전을 전달합니다.
TLS 라우팅으로 마이그레이션할 수 없는 경우, 이 오류를 우회하는 또 다른 방법은 Teleport 로컬 프록시 명령을 사용하는 것입니다. 이를 통해 Teleport 클러스터에서 TLS 라우팅이 활성화되어 있지 않은 경우에도 Teleport Proxy Service에 대한 TLS 라우팅 연결을 설정할 수 있습니다.
proxy_service:
mysql_server_version: "8.0.4"