Infograb logo
데이터베이스 액세스 제어

데이터베이스 액세스 제어는 사용자가 필요한 데이터만 관리할 수 있도록 역할 기반 액세스 제어를 구성할 수 있는 Teleport 기능입니다. 데이터베이스 액세스 제어를 사용하면 사용자가 필요한 데이터에 대한 권한만 가질 수 있습니다.

액세스 제어는 두 가지 수준의 세분화로 구성됩니다:

  • 데이터베이스 서버: Teleport 클러스터에 등록된 데이터베이스 리소스입니다.
  • 데이터베이스 객체: 테이블, 뷰 또는 저장 프로시저입니다.

데이터베이스 서버와 데이터베이스 객체 모두에 대해 데이터베이스 액세스 제어는 Teleport 레이블을 바탕으로 액세스를 부여하거나 거부합니다. 데이터베이스를 Teleport에 등록할 때 데이터베이스와 관련된 레이블을 구성할 수 있습니다. 데이터베이스 객체에 대해서는 가져오기 규칙을 정의하여 Teleport 데이터베이스 서비스가 가져오기 규칙 내에서 구성된 레이블과 일치하는 데이터베이스에서 가져온 데이터베이스 객체에 레이블을 적용하도록 지시할 수 있습니다.

사용자가 데이터베이스에 연결할 때, 데이터베이스 서비스는 사용자의 Teleport 역할에 대해 레이블을 확인하여 선택적으로 권한을 부여합니다.

데이터베이스 서비스는 연결 기간 동안 객체 수준 권한을 부여하고 연결이 종료되면 자동으로 이를 회수합니다.

Teleport 역할 및 예제에 대한 더 일반적인 설명은 RBAC를 참조하세요. 이 섹션은 데이터베이스 액세스에 대한 RBAC 구성을 중심으로 다룹니다.

데이터베이스 객체에 대한 데이터베이스 액세스 제어는 PostgreSQL 데이터베이스만 지원합니다.

역할 구성

Teleport의 역할 리소스는 데이터베이스 액세스를 제한하기 위한 다음의 도구를 제공합니다:

kind: role
version: v5
metadata:
  name: developer
spec:
  allow:
    # 이 역할이 액세스할 수 있는 데이터베이스 인스턴스에 대한 레이블 선택자.
    #
    # 이는 데이터베이스 서비스에 설정된 정적/동적 레이블과 일치해야 합니다.
    db_labels:
      environment: ["dev", "stage"]

    # 이 역할이 연결할 수 있는 데이터베이스 계정 이름.
    db_users: ["viewer", "editor"]

    # 이 역할이 연결할 수 있는 데이터베이스 이름.
    #
    # 참고, 이것은 "db_service"의 "name" 필드와는 다릅니다. 이는 특정 데이터베이스 인스턴스 내의 데이터베이스 이름입니다.
    #
    # 또한 현재 이 설정은 PostgreSQL에만 적용됩니다. MySQL 데이터베이스/스키마에는 현재 효과가 없습니다.
    db_names: ["main", "metrics", "postgres"]

와일드카드를 사용하여 모든 데이터베이스 이름/사용자를 일치시키는 것이 가능합니다.

예를 들어, 다음 역할은 내부 "postgres" 데이터베이스/사용자를 제외하고 프로덕션 데이터베이스 내의 모든 데이터베이스/사용자에 대한 액세스를 허용합니다:

kind: role
version: v5
metadata:
  name: developer
spec:
  allow:
    db_labels:
      environment: ["prod"]
    db_users: ["*"]
    db_names: ["*"]
  deny:
    db_users: ["postgres"]
    db_names: ["postgres"]
거부 규칙

거부 규칙은 공격적으로 매치됩니다. 위 예제에서, "postgres" 데이터베이스 계정을 사용하려는 데이터베이스 연결(데이터베이스 인스턴스나 데이터베이스 이름에 관계없이) 또는 "postgres" 데이터베이스 이름(데이터베이스 인스턴스나 데이터베이스 계정에 관계없이)은 거부됩니다.

데이터베이스 이름

서로 다른 데이터베이스 서버가 논리 데이터베이스를 처리하는 방식에는 차이가 있으며, 이는 연결 시 db_names 역할 필드가 적용되는 방식에 차이를 가져옵니다.

PostgreSQL은 여러 논리 데이터베이스를 지원하며, 각 논리 데이터베이스는 여러 스키마를 포함할 수 있습니다. 다른 데이터베이스로 변경하려면 사용자가 현재 연결을 끊고 새로운 연결을 설정합니다. PostgreSQL 연결 시도 동안 db_names 필드는 사용자가 연결하고 있는 논리 데이터베이스의 이름과 일치하는지 확인됩니다.

MySQL에서는 논리적 "데이터베이스"와 "스키마"가 서로 동의어 관계이며, 사용자가 연결된 후의 권한 범위는 데이터베이스 내의 계정에 설정된 권한 부여에 따라 결정됩니다. 따라서 현재 db_names 역할 필드는 MySQL 연결 시도에 적용되지 않습니다.

템플릿 변수

다른 역할 필드와 유사하게 db_* 필드는 템플릿 변수를 지원합니다.

external.xyz 특성은 외부 싱글 사인 온 제공자에서 값을 가져와 대체됩니다. OIDC의 경우, "xyz" 클레임의 값으로 대체됩니다. SAML의 경우, "xyz" assertion 값으로 대체됩니다.

텔레포트 역할에서 특성이 작동하는 방식에 대한 자세한 내용은 Teleport 액세스 제어 참조를 참조하세요.

예를 들어, 역할이 사용자의 Okta databases assertion에서 허용된 데이터베이스 이름을 할당하려는 경우 역할은 다음과 같이 보일 수 있습니다:

spec:
  allow:
    db_names: ["{{external.databases}}"]

{{internal.db_users}}{{internal.db_names}} 변수는 허용된 데이터베이스 계정 및 이름을 원격 클러스터와 공유할 수 있습니다. 이들은 루트 클러스터에서 연결되는 원격 사용자의 해당 속성으로 대체됩니다.

예를 들어, 루트 클러스터의 사용자가 다음 역할을 가진다고 가정합니다:

spec:
  allow:
    db_users: ["postgres"]
    db_names: ["postgres"]

리프 클러스터의 역할은 사용자가 허용된 데이터베이스 계정 및 이름을 사용하도록 설정할 수 있습니다:

spec:
  allow:
    db_users: ["{{internal.db_users}}"]
    db_names: ["{{internal.db_names}}"]

데이터베이스 객체 가져오기 규칙

Teleport의 데이터베이스 객체 가져오기 규칙은 Teleport에 가져온 데이터베이스 객체에 적용할 레이블을 정의하는 리소스입니다. 특정 객체가 규칙과 일치하지 않으면 가져오지 않습니다.

기본 가져오기 규칙

기본적으로 가져오기 규칙이 없는 경우(예: 새 클러스터를 생성하거나 모든 규칙을 삭제한 경우) Teleport는 시작 시 자동으로 import_all_objects 규칙을 생성합니다:

kind: db_object_import_rule
metadata:
  name: import_all_objects
spec:
  # 우선 순위는 규칙의 중요도를 결정하며, 낮은 숫자는 낮은 우선 순위를 나타냅니다.
  # 충돌 시 두 규칙이 동일한 레이블을 적용할 때 우선 순위가 높은 규칙이 적용됩니다.
  priority: 0
  # database_labels는 이 규칙의 범위에 있는 데이터베이스 리소스를 지정하는 필터입니다.
  database_labels:
  - name: '*'
    values:
    - '*'
  # 각 매핑은 일치할 경우 데이터베이스 객체에 적용할 레이블 세트를 도입합니다.
  # 레이블이 없는 데이터베이스 객체는 가져오지 않습니다.
  mappings:
  - add_labels:
      database: '{{obj.database}}'
      object_kind: '{{obj.object_kind}}'
      name: '{{obj.name}}'
      protocol: '{{obj.protocol}}'
      schema: '{{obj.schema}}'
      database_service_name: '{{obj.database_service_name}}'
    # match는 가져올 객체를 추가하며, 비어 있을 수 없습니다.
    match:
      # 모든 테이블 이름 목록
      table_names:
      - '*'
  # 추가 매핑을 여기에 추가할 수 있습니다.
  # - add_labels: ...
version: v1

이 규칙은 모든 객체를 가져오고 그들의 본질적인 속성을 사용하여 템플릿 구문으로 레이블을 지정합니다.

기본 가져오기 규칙 사용자 정의

기본 db_object_import_rule을 다른 Teleport 리소스처럼 수정할 수 있습니다.

예를 들어, 개발자가 읽기 전용 또는 읽기-쓰기 능력으로 액세스할 수 있도록 특정 테이블을 지정되는 규칙은 다음과 같을 수 있습니다:

kind: db_object_import_rule
metadata:
  name: ownership_nonprod
spec:
  priority: 100
  database_labels:
  # 'dev' 및 'staging' 환경에 영향을 미칩니다.
  # prod 환경은 다른 규칙을 가질 수 있습니다.
  - name: 'env'
    values:
    - 'staging'
    - 'dev'
    - 'prod'
  mappings:
  # 프로젝트 레이블 적용
  - add_labels:
      project: horizon
    # match 섹션은 필수이며 하나 이상의 비어 있지 않은 하위 섹션을 포함해야 합니다.
    match:
      table_names:
      - '*'
    # scope는 데이터베이스 및 스키마 이름으로 객체를 추가로 필터링하는 선택적 섹션입니다. 생략 시 이 필터링은 비활성화됩니다.
    scope:
      database_names:
      - 'horizon'
      - 'horizon_v2'
      schema_names:
      - 'application'
      - 'data_import'
  # 해당 테이블에 대해 `dept: hr` 레이블 추가.
  - add_labels:
      dept: hr
    match:
      table_names:
      - '*'
    scope:
      schema_names:
      - 'recruitment'
      - 'salaries'
      - 'pto'
      - 'hr_scratchpad'
version: v1

데이터베이스 관리자 사용자

데이터베이스 관리자 사용자는 최종 사용자에게 권한을 부여하는 책임이 있습니다. 데이터베이스 객체 가져오기 규칙을 사용하기 전에 데이터베이스 관리자 사용자를 지정해야 합니다. 데이터베이스 관리자 사용자를 지정하려면 Teleport 데이터베이스 서비스가 실행 중인 에이전트의 동적 데이터베이스 리소스 또는 구성 파일에 다음을 추가하십시오:

kind: db
version: v3
metadata:
  # ...
spec:
  # ...
  admin_user: "teleport-admin"
db_service:
  enabled: "yes"
  databases:
  - name: "example"
    # ...
    admin_user:
      name: "teleport-admin"

이 경우 Teleport 데이터베이스 서비스는 객체 가져오기 규칙을 실행하기 위해 teleport-admin이라는 사용자를 활성화할 것으로 기대합니다. 관리자가 데이터베이스에서 사용자 관리에 필요한 권한을 가지고 있는지 확인하십시오. 그렇지 않으면 데이터베이스 구성에 따라 객체 가져오기 규칙이 실패할 수 있습니다:

tsh db connect postgres-db --db-name postgres --db-user teleport-user
psql: error: connection to server at "localhost" (::1), port 50800 failed: Connection refused Is the server running on that host and accepting TCP/IP connections?connection to server at "localhost" (127.0.0.1), port 50800 failed: your Teleport role requires automatic database user provisioning but an attempt to activate database user "teleport-user" failed due to the following error: ERROR: permission denied for table pg_subscription (SQLSTATE 42501)ERROR: exit status 2

데이터베이스 객체 권한 규칙 실행

Teleport 데이터베이스 서비스는 사용자가 데이터베이스에 연결하기 전에 해당 사용자와 관련된 역할을 확인합니다.

데이터베이스 연결 중 데이터베이스 객체 권한을 부여하려면 사용자는 특정 기준을 충족하는 역할과 연결되어야 합니다:

  • spec.allow.db_labels는 특정 데이터베이스의 데이터베이스 레이블과 일치해야 합니다.
  • 데이터베이스 사용자 자동 프로비저닝이 활성화되어 있어야 합니다 (spec.options.create_db_user_modeoff로 설정되지 않거나 spec.options.create_db_user: true).
  • spec.allow.db_permissions.match의 레이블 키/값 쌍은 특정 데이터베이스 객체의 레이블과 일치해야 합니다.

사용자는 동일한 데이터베이스에 여러 동시 연결을 유지할 수 있습니다. 모든 연결은 동일한 권한을 가져야 하며, 그렇지 않으면 새로운 연결이 거부됩니다. 마지막 활성 연결이 종료되면 모든 사용자 권한은 자동으로 회수됩니다.

테이블에 대한 레이블은 적절한 역할과 일치해야 합니다. 아래는 dept 레이블을 사용하는 역할의 예입니다. 이는 ownership_nonprod 규칙에 의해 적용되어 데이터베이스 내 HR 기록에 대한 읽기 전용 액세스를 부여합니다. hr_scratchpad 테이블은 편집 가능하게 설정됩니다. 반대로, dept: sales로 레이블이 지정된 객체는 모든 권한을 제거하여 사용할 수 없게 됩니다. 와일드카드 권한은 deny 부분의 사양(spec.deny.db_permissions)에서만 허용됩니다:

version: v7
kind: role
metadata:
  name: dept_hr_permissions
spec:
  allow:
    db_labels:
      '*': '*'
    db_names:
    - '*'
    db_permissions:
    # 기본 권한: 읽기 전용
    - match:
        object_kind: table
        dept: hr
      permissions:
      - SELECT
    # 특정 테이블에 대한 추가 권한
    - match:
        object_kind: table
        dept: hr
        name: hr_scratchpad
      permissions:
      - SELECT
      - UPDATE
      - DELETE
      - INSERT
  deny:
    db_permissions:
    # `dept: sales` 테이블에 대한 상호작용을 명시적으로 금지합니다.
    - match:
        dept: sales
      permissions:
      - '*'
  options:
    create_db_user_mode: keep

객체 가져오기 규칙 문제 해결

데이터베이스 객체 가져오기 문제를 진단하려면 Teleport 데이터베이스 서비스 로그를 참조하십시오. 이는 데이터베이스에서 가져온 객체 수, 가져온 객체 수(규칙과 일치하지 않는 객체의 차이), 권한이 부여된 객체 수를 나타냅니다:

INFO [DB:SERVIC] Database objects fetched from the database (table:75). db:my-postgres id:b4a33740-1d82-4a8d-b2be-2aa90ae9d2eb total:75 postgres/users.go:212
INFO [DB:SERVIC] Database objects imported (table:75). db:my-postgres err_count:0 id:b4a33740-1d82-4a8d-b2be-2aa90ae9d2eb total:75 postgres/users.go:216
INFO [DB:SERVIC] Calculated database permissions: "INSERT": 75 objects (table:75), "SELECT": 75 objects (table:75), "UPDATE": 75 objects (table:75). db:my-postgres id:b4a33740-1d82-4a8d-b2be-2aa90ae9d2eb user:teleport-user postgres/users.go:223
Teleport 원문 보기