컨트롤러 구성하기

컨트롤러 구성하기 (Configure controllers)

Boundary 컨트롤러를 구성한다는 것은 TLS 인증서를 준비하고, root와 recovery KMS 키를 생성하고, PostgreSQL 데이터베이스를 연결하고, 컨트롤러를 systemd 서비스로 시작해서 클라이언트 연결을 받고 worker를 조정하게 하는 것을 의미해요. 이 페이지는 Boundary 설치에서 설명한 대로 최소 세 개의 컨트롤러 노드에 Boundary를 이미 설치했다고 가정합니다.

출처: HashiCorp Boundary docs

본문

TLS 인증서 준비

HashiCorp는 사용자 연결용으로 Boundary 컨트롤러 노드가 PKI로 TLS를 처리할 것을 권장합니다. 그리고 적절한 CA(인증 기관)가 생성하고 서명한 인증서를 사용하는 것을 강력히 권장해요.

TLS를 사용하려면 각 Boundary 컨트롤러 노드에 두 개의 파일이 있어야 합니다. 인증서 자료를 저장할 새 디렉터리 /etc/boundary.d/tls를 만들어야 할 수도 있어요. 다음 경로에 파일을 놓으세요:

  • /etc/boundary.d/tls/boundary-cert.pem (인증서)
  • /etc/boundary.d/tls/boundary-key.pem (키)

각 노드에 고유한 TLS 키 자료를 생성하지 않는다면, 키 자료를 각 Boundary 컨트롤러 노드에 안전하게 배포해야 합니다.

컨트롤러에게 필요한 KMS 키는 무엇인가요?

Boundary 컨트롤러는 다음 두 가지 서로 다른 암호화 키가 필요합니다:

  • Root 키 — Root KMS 키는 스코프별 KEK(Key Encrypting Key, 스코프의 root 키라고도 함)를 위한 KEK 역할을 해요. 스코프를 만들면 Boundary는 root KEK와 다양한 DEK(Data Encryption Keys)도 만듭니다. DEK를 스코프의 KEK로 암호화한 다음, KEK를 root 목적이라 표시된 KMS 키로 암호화합니다.
  • Recovery 키 — Recovery KMS 키는 Boundary 클라이언트 구조(rescue) 및 복구 운영 워크플로를 인증하는 데 사용해요. Recovery 키는 nonce와 생성 시간을 암호화된 페이로드로 포함합니다. Boundary는 페이로드를 토큰으로 포맷해서 컨트롤러에 보냅니다. 시간과 nonce 덕분에 공격자가 값을 재사용(replay)하지 못하며, 클라이언트가 각 작업을 개별적으로 인증해야 하므로 KMS 접근을 취소하면 즉시 효과가 있습니다.

다음 키는 선택 사항입니다:

  • Worker-auth 키 (선택) — 컨트롤러와 worker가 worker-auth KMS 키를 공유해서 worker를 컨트롤러에 인증해요. worker가 PKI 인증을 사용한다면 이 키는 필요 없습니다.
  • BSR 키 (선택) — 세션 녹화에는 BSR KMS 키가 필요해요. Boundary는 BSR 키로 데이터를 암호화하고 녹화의 무결성을 확인합니다. 컨트롤러 구성에 BSR 키를 추가하지 않으면, 세션 녹화를 활성화하려고 할 때 오류가 발생합니다.

다른 암호화 시나리오를 위해 구성할 수 있는 선택적 KMS 키도 더 있어요. 여기에는 Boundary worker PKI auth 암호화와 Boundary worker 또는 컨트롤러 구성 암호화가 포함됩니다. 자세한 내용은 Boundary의 데이터 암호화를 참고하세요.

Note — Boundary worker에는 두 가지 유형이 있고, 컨트롤러와 인증하는 방식으로 구분됩니다. 한 worker는 PKI(공개 키 인프라) 교환으로 컨트롤러와 인증하고, 다른 worker는 worker와 컨트롤러 양쪽이 KMS 키로 인증합니다. 위에 나열한 worker-auth 키로 KMS worker 인증을 활성화할 수 있어요.

HashiCorp는 Vault Transit이나 클라우드 프로바이더의 키 관리 시스템을 사용할 것을 강력히 권장합니다. 자세한 내용은 Vault Transit 문서나 클라우드 프로바이더의 키 관리 문서를 참고하세요.

Vault나 선택한 키 관리 시스템에서 키를 만든 다음에는 PostgreSQL 데이터베이스를 준비할 수 있습니다.

데이터베이스 준비

Boundary는 PostgreSQL이라는 RDBMS(관계형 데이터베이스 관리 시스템)에서 상태와 구성을 관리해요. 노드를 구성하기 전에 PostgreSQL 데이터베이스를 만들고, 설정하고, Boundary 컨트롤러 노드가 접근할 수 있게 해야 합니다.

클라우드 관리형 PostgreSQL 데이터베이스 예시는 데이터베이스 권장 사항 문서를 참고하세요.

컨트롤러 구성 만들기

다음을 구성했다면 컨트롤러 구성을 만들 수 있어요:

  • Boundary가 설치된 가상 머신 최소 세 대
  • TLS 통신을 위해 가상 머신에 배포할 TLS 인증서와 키 최소 하나
  • root와 recovery 작업에 사용할 KMS 키
  • 구성과 상태를 관리할 PostgreSQL 데이터베이스

각 Boundary 컨트롤러 노드에 대해 다음 컨트롤러 구성을 완료해야 합니다.

기본 컨트롤러 구성

Boundary 컨트롤러 구성의 핵심 필수 값은 다음과 같습니다:

  • api, cluster, ops용 listener 블록
  • kms 블록
  • disable_mlock
  • controller 블록

HashiCorp Linux Repository에서 Boundary를 설치하면 /etc/boundary.d/ 아래에 예시 구성 파일 몇 개가 설치됩니다. 다음 명령으로 예시 구성 파일의 이름을 바꾸세요:

  • sudo mv boundary.hcl boundary.hcl.old
  • sudo mv controller.hcl controller.hcl.old
  • sudo mv worker.hcl worker.hcl.old

HashiCorp는 구성 파일에 env:// 또는 file:// 표기법을 사용해서 비밀 구성 컴포넌트를 Boundary 컨트롤러 바이너리에 안전하게 제공할 것을 권장합니다. 다음 컨트롤러 구성 예시는 env://를 사용해서 PostgreSQL 연결 문자열을 선언하고 AWS KMS 구성 항목도 보호해요.

패키지 관리자로 Boundary 바이너리를 설치하면 /etc/boundary.d/boundary.env에 환경 파일을 구성하는 유닛 파일이 포함됩니다. 이 파일로 Boundary 컨트롤러와 worker를 구성하는 데 사용하는 민감한 값을 설정할 수 있어요. 다음은 이 환경 파일을 사용하는 구성 예시입니다:

/etc/boundary.d/boundary.env:

POSTGRESQL_CONNECTION_STRING=postgresql://boundary:***@postgres.yourdomain.com:5432/boundary
AWS_ACCESS_KEY_ID=«redacted:AKIA…»
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Note — 위 예시에서 Boundary가 서로 다른 KMS 키에 접근하는 데 사용할 수 있도록, 주어진 AWS_ACCESS_KEY와 AWS_SECRET_ACCESS_KEY에 대한 적절한 IAM 역할과 권한이 갖춰져 있어야 합니다.

다음으로 controller.hcl 파일에 관련 구성 정보를 채웁니다. 다음 예시 구성 파일은 프로덕션 Boundary 컨트롤러 설치를 위한 좋은 출발점이에요. 세 개의 listener 블록, AWS 전용의 두 개의 고유한 kms 블록(예시), disable_mlock 값, 그리고 controller 블록을 정의합니다.

/etc/boundary.d/controller.hcl:

# disable memory from being swapped to disk
disable_mlock = true

# API listener configuration block
listener "tcp" {
  # Should be the address of the NIC that the controller server will be reached on
  # Use 0.0.0.0 to listen on all interfaces
  address = "0.0.0.0:9200"
  # The purpose of this listener block
  purpose = "api"

  # TLS Configuration
  tls_disable   = false
  tls_cert_file = "/etc/boundary.d/tls/boundary-cert.pem"
  tls_key_file  = "/etc/boundary.d/tls/boundary-key.pem"

  # Uncomment to enable CORS for the Admin UI. Be sure to set the allowed origin(s)
  # to appropriate values.
  #cors_enabled = true
  #cors_allowed_origins = ["https://yourcorp.yourdomain.com", "serve://boundary"]
}

# Data-plane listener configuration block (used for worker coordination)
listener "tcp" {
  # Should be the IP of the NIC that the worker will connect on
  address = "0.0.0.0:9201"
  # The purpose of this listener
  purpose = "cluster"
}

# Ops listener for operations like health checks for load balancers
listener "tcp" {
  # Should be the address of the interface where your external systems'
  # (eg: Load-Balancer and metrics collectors) will connect on.
  address = "0.0.0.0:9203"
  # The purpose of this listener block
  purpose = "ops"

  tls_disable   = false
  tls_cert_file = "/etc/boundary.d/tls/boundary-cert.pem"
  tls_key_file  = "/etc/boundary.d/tls/boundary-key.pem"
}

# Controller configuration block
controller {
  # This name attr must be unique across all controller instances if running in HA mode
  name = "boundary-controller-1"
  description = "Boundary controller number one"

  # This is the public hostname or IP where the workers can reach the
  # controller. This should typically be a load balancer address
  public_cluster_addr = "example-cluster-lb.example.com"

  # Enterprise license file, can also be the raw value or env:// value
  license = "file:///path/to/license/file.hclic"

  # After receiving a shutdown signal, Boundary will wait 10s before initiating the shutdown process.
  graceful_shutdown_wait_duration = "10s"

  # Database URL for postgres. This is set in boundary.env and
  #consumed via the "env://" notation.
  database {
      url = "env://POSTGRESQL_CONNECTION_STRING"
  }
}

# Events (logging) configuration. This
# configures logging for ALL events to both
# stderr and a file at /var/log/boundary/controller.log
events {
  audit_enabled       = true
  sysevents_enabled   = true
  observations_enable = true
  sink "stderr" {
    name = "all-events"
    description = "All events sent to stderr"
    event_types = ["*"]
    format = "cloudevents-json"
  }
  sink {
    name = "file-sink"
    description = "All events sent to a file"
    event_types = ["*"]
    format = "cloudevents-json"
    file {
      path = "/var/log/boundary"
      file_name = "controller.log"
    }
    audit_config {
      audit_filter_overrides {
        sensitive = "redact"
        secret    = "redact"
      }
    }
  }
}

# Root KMS Key (managed by AWS KMS in this example)
# Keep in mind that sensitive values are provided via ENV VARS
# in this example, such as access_key and secret_key
kms "awskms" {
  purpose    = "root"
  region     = "us-east-1"
  kms_key_id = "19ec80b0-dfdd-4d97-8164-c6examplekey"
  endpoint   = "https://vpce-0e1bb1852241f8cc6-pzi0do8n.kms.us-east-1.vpce.amazonaws.com"
}

# Recovery KMS Key
kms "awskms" {
  purpose    = "recovery"
  region     = "us-east-1"
  kms_key_id = "19ec80b0-dfdd-4d97-8164-c6examplekey2"
  endpoint   = "https://vpce-0e1bb1852241f8cc6-pzi0do8n.kms.us-east-1.vpce.amazonaws.com"
}

# Worker-Auth KMS Key (optional, only needed if you use
# KMS authenticated workers)
kms "awskms" {
  purpose    = "worker-auth"
  region     = "us-east-1"
  kms_key_id = "19ec80b0-dfdd-4d97-8164-c6examplekey3"
  endpoint   = "https://vpce-0e1bb1852241f8cc6-pzi0do8n.kms.us-east-1.vpce.amazonaws.com"
}

# BSR KMS Key (optional, only needed if you use the
# session recording feature)
kms "awskms" {
  purpose    = "bsr"
  region     = "us-east-1"
  kms_key_id = "19ec80b0-dfdd-4d97-8164-c6examplekey4"
  endpoint   = "https://vpce-0e1bb1852241f8cc6-pzi0do8n.kms.us-east-1.vpce.amazonaws.com"
}

위 예시에서 사용된 파라미터에 대한 설명은 아래 표를 참고하세요:

Parameter Type Description
disable_mlock bool: false 서버가 mlock syscall 실행을 비활성화해서 메모리 스왑을 방지. 로컬 개발과 테스트에는 괜찮지만, 암호화된 스왑을 쓰거나 스왑을 전혀 쓰지 않는 시스템이 아니라면 프로덕션에는 권장하지 않음. Boundary는 Linux와 FreeBSD처럼 mlock() syscall을 지원하는 UNIX 계열 시스템에서만 메모리 잠금을 지원.
listener block Boundary가 트래픽을 서비스하는 리스너(API cluster와 proxy) 구성.
controller block 컨트롤러 구성. 있으면 boundary server가 컨트롤러 하위 프로세스를 시작.
events block 이벤트별 파라미터 구성.
kms block 다양한 목적을 위한 KMS 블록 구성.

Linux에서 루트로 실행하지 않고 Boundary 실행 파일이 mlock syscall을 쓸 수 있게 하려면 다음 명령을 실행하세요:

sudo setcap cap_ipc_lock=+ep $(readlink -f $(which boundary))

최신 systemd를 쓰는 Linux 배포판이라면 [Service] 구성 섹션에 다음 지시어를 추가할 수 있어요:

LimitMEMLOCK=infinity

위 예시 events 구성은 완전해서 모든 이벤트를 stderr와 파일 양쪽에 기록합니다. 이 구성이 조직의 로깅 솔루션에 맞지 않을 수도 있어요.

서로 다른 클라우드 kms 블록의 구성 정보는 다음 링크를 참고하세요: AWS, Azure, GCP, OCI, AliCloud, Vault Transit.

추가 최상위 구성 옵션과 컨트롤러별 옵션 문서도 참고하세요.

데이터베이스 초기화

Boundary를 시작하기 전에 한 Boundary 컨트롤러에서 데이터베이스를 초기화해야 해요. 초기화는 Boundary 클러스터가 동작하는 데 필요한 데이터베이스 마이그레이션을 실행하는 일회성 작업입니다.

$ boundary database init -config /etc/boundary.d/controller.hcl

Boundary는 지정하지 않는 한 시작을 쉽게 하기 위해 여러 리소스를 자동 생성합니다. 데이터베이스를 초기화하면 기본 스코프, 인증 방법, 사용자, 계정, 타깃이 자동 생성되요. 이 리소스들은 필수가 아닙니다.

다음 플래그를 추가해서 이런 초기 리소스 생성을 건너뛸 수 있어요:

$ boundary database init \
   -skip-auth-method-creation \
   -skip-host-resources-creation \
   -skip-scopes-creation \
   -skip-target-creation \
   -config /etc/boundary.d/controller.hcl

더 많은 초기화 옵션을 보려면 다음 명령으로 도움말을 확인하세요:

$ boundary database init -h

Boundary 서비스 시작

각 Boundary 컨트롤러에 구성 파일이 제자리에 있으면, systemd를 사용해 각 Boundary 컨트롤러 노드에서 바이너리를 활성화하고 시작할 수 있어요.

서비스를 활성화하고 시작하려면 다음 명령을 실행하세요:

$ sudo systemctl enable boundary
$ sudo systemctl start boundary

systemd 수동 구성 (선택)

Boundary를 수동으로 설치했다면, systemd 아래에서 Boundary를 서비스로 실행하도록 구성할 수 있어요.

이렇게 하려면:

  • 디스크에서 컨트롤러 구성 파일의 위치를 확인(예: 이 페이지 예시의 /etc/boundary.d/controller.hcl). 다음 단계에서 유닛 파일을 설정할 때 .hcl 구성 파일의 위치를 참조해야 해요.
  • Boundary 서비스가 실행되는 사용자와 그룹 구성
  • systemd 유닛 파일 설정
  • Boundary 서비스 시작

사용자와 그룹 구성

HashiCorp는 Boundary를 비루트 사용자로 실행하고, systemd 아래에서 실행되는 Boundary 프로세스를 그 사용자로 관리할 것을 권장합니다.

boundary 시스템 사용자와 그룹을 추가해서 Boundary를 소유하고 실행하는 로그인 불가(non-login) 사용자를 확보하세요:

$ sudo adduser --system --group boundary || true ;
$ sudo chown boundary:boundary /etc/boundary.d/controller.hcl ;
$ sudo chown boundary:boundary /usr/local/bin/boundary

Tip — 서비스를 시작하기 전에 데이터베이스를 초기화해야 해요. 다른 컨트롤러나 worker가 이미 이것을 했다면, 데이터베이스가 이미 초기화되었다는 예상된 오류를 받게 됩니다.

유닛 파일 설정

/etc/systemd/system/boundary-controller.service 같은 새 유닛 파일을 만듭니다. 파일에 다음 코드를 추가하세요. ExecStart 줄의 controller.hcl 파일 경로와, 필요에 따라 사용자와 그룹을 업데이트합니다.

/etc/systemd/system/boundary-controller.service:

[Unit]
Description="HashiCorp Boundary controller"
Documentation=https://developer.hashicorp.com/boundary/docs
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
EnvironmentFile=-/etc/boundary.d/boundary.env
User=boundary
Group=boundary
ProtectSystem=full
ProtectHome=read-only
ExecStart=/usr/bin/boundary server -config=/etc/boundary.d/controller.hcl
ExecReload=/bin/kill --signal HUP $MAINPID
KillMode=process
KillSignal=SIGINT
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
LimitMEMLOCK=infinity

[Install]
WantedBy=multi-user.target

([Install] 뒤의 EOF는 문서 예시에서 heredoc 마커로, 파일 내용에는 포함되지 않아요.)

Boundary 서비스 시작

유닛 파일에 적절한 권한을 설정합니다:

$ sudo chmod 664 /etc/systemd/system/boundary-controller.service

systemd 데몬을 리로드하고 Boundary 서비스를 활성화·시작합니다:

$ sudo systemctl daemon-reload ;
$ sudo systemctl enable boundary-controller ;
$ sudo systemctl start boundary-controller

인증 및 리소스 관리

Boundary에 처음 로그인할 때, HashiCorp는 Boundadry를 관리할 global/프로젝트 레벨 스코프용 admin 사용자를 만들 것을 권장합니다. admin 사용자를 만들면 그 스코프 내에서 타깃을 구성하고 관리할 수 있어요.

HashiCorp는 처음 로그인할 때 KMS recovery 워크플로를 사용할 것을 권장합니다. 앞으로 recovery KMS 워크플로 없이 Boundary에 로그인하려면 첫 번째 인증 방법, 사용자, 계정, 역할을 설정하는 방법을 첫 로그인 계정 만들기에서 알아보세요.

문제 해결

Boundary 컨트롤러를 구성할 때 흔한 문제는 다음과 같습니다:

  • TLS 인증서와 키 불일치 — /etc/boundary.d/tls/boundary-cert.pem과 /etc/boundary.d/tls/boundary-key.pem의 인증서와 키 파일이 짝이 맞는지, 인증서의 CN 또는 SAN이 컨트롤러의 DNS 레코드와 일치하는지 확인하세요.
  • KMS 권한 오류 — KMS 자격 증명(예: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)과 연관된 IAM 역할이나 권한이 controller.hcl 파일에서 참조하는 특정 KMS 키에 접근 권한을 부여하는지 확인하세요.
  • 데이터베이스 연결 실패 — boundary.env의 PostgreSQL 연결 문자열이 올바른지, 각 Boundary 컨트롤러 노드에서 데이터베이스에 도달할 수 있는지 확인하세요.

더 알아보기 (Learn more)

컨트롤러를 구성한 다음에는 다음을 해야 해요: