액세스 제어 목록(ACL) 시스템 부트스트랩

액세스 제어 목록(ACL) 시스템 부트스트랩 (Bootstrap Access Control List (ACL) System)

이 페이지는 Consul 서버 에이전트, 클라이언트 에이전트, 서비스에 대해 최소 권한으로 ACL 시스템을 부트스트랩하고 토큰을 생성하는 과정을 설명해요.

출처: 문서

본문

이 페이지는 Consul 서버 에이전트, 클라이언트 에이전트, 서비스에 대해 최소 권한으로 ACL 시스템을 부트스트랩하고 토큰을 생성하는 과정을 자세히 설명해요. ACL 시스템이 Consul 운영에 대한 접근과 서비스 및 에이전트 통신을 어떻게 보호하는지에 대한 자세한 내용은 ACL 개요를 참고해요.

개요 (Overview)

ACL 시스템을 부트스트랩하려면 다음 단계를 완료해요:

  1. 에이전트에서 ACL을 활성화해요.
  2. 초기 부트스트랩 토큰을 생성해요.

부트스트랩 토큰을 생성한 후 서버 에이전트, 클라이언트 에이전트, 서비스에 대한 ACL 토큰을 만들고 추가할 수 있어요. 그런 다음 규칙, 정책, 역할을 ACL 토큰과 연결해 특정 에이전트 및 서비스 상호작용을 허용하거나 거부할 수 있어요.

요구 사항 (Requirements)

최상의 결과를 위해 초기 Consul 클러스터를 배포하고 서비스를 등록한 후 ACL 시스템을 부트스트랩하는 것을 권장해요.

에이전트에서 ACL 활성화 (Enable ACLs on the agents)

ACL 시스템에 대한 매개변수를 에이전트의 구성 파일에 추가한 다음 Consul 서비스를 재시작해요. Consul이 ACL 구성을 올바르게 활성화하려면 Consul 데이터센터의 모든 서버와 클라이언트에 동일한 매개변수를 적용해야 해요. 먼저 모든 서버의 구성 파일을 업데이트한 다음 롤링 재시작을 시작해야 해요.

다음 예시는 Consul의 ACL을 활성화하고 기본 정책을 deny로 설정해요. 이 설정은 명시적으로 명명된 리소스만 Consul에 접근할 수 있음을 의미해요. 이 구성은 또한 토큰 지속성(token persistence)을 활성화해 토큰을 디스크에 저장하고 에이전트가 재시작할 때 다시 로드해요.

agent.hcl:

acl = {
  enabled = true
  default_policy = "deny"
  enable_token_persistence = true
}

다음 표는 ACL이 적용되는 일반적인 에이전트 구성 필드와 구성이 서버, 클라이언트 또는 둘 다에 적용되는지 여부를 설명해요. 구성 가능한 필드의 전체 목록은 에이전트 참조 문서를 참고해요.

구성 옵션 서버 클라이언트 설명
acl.enabled required required ACL이 활성화되는지 여부를 제어해요
acl.default_policy optional N/A allowlist 또는 denylist 모드를 결정해요
acl.down_policy optional optional 원격 토큰 또는 정책 해석이 실패할 때 무엇을 할지 결정해요
acl.role_ttl optional optional 캐시된 ACL 역할의 time-to-live를 결정해요
acl.policy_ttl optional optional 캐시된 ACL 정책의 time-to-live를 결정해요
acl.token_ttl optional optional 캐시된 ACL 토큰의 time-to-live를 결정해요

Consul 클라이언트 재시작을 줄이려면 토큰을 에이전트에 적용할 때 클라이언트에서 ACL을 활성화할 수 있어요.

기존 데이터센터에 ACL 부트스트랩

기존 데이터센터에 ACL을 부트스트랩한다면 먼저 default_policy = "allow"로 에이전트에서 ACL을 활성화해 다운타임을 줄여요. 이 방식은 ACL을 활성화하지만 모든 작업을 계속 허용하므로, 부트스트랩 과정에서 토큰을 만들어 적용하는 동안 Consul이 정상적으로 기능하게 해요.

초기 부트스트랩 토큰 생성 (Create the initial bootstrap token)

Consul 서버 중 하나에서 acl bootstrap 명령을 사용해요.

$ consul acl bootstrap

출력은 연결된 정책 global-management과 SecretID를 포함한 토큰에 대한 중요한 정보를 제공해요. SecretID의 값은 ACL 토큰이라고도 해요. 이 토큰은 요청자를 식별하는 불투명 UUID로, ACL 시스템이 요청된 리소스에 대한 접근을 허용할지 거부할지 결정할 수 있게 해요.

기본적으로 Consul은 무제한 권한을 가진 global-management 정책을 부트스트랩 토큰에 할당해요. 비상 상황에 대비해 무제한 권한의 토큰을 갖는 것이 중요하지만, 소수의 ACL 관리자만이 접근할 수 있어야 해요.

ACL 시스템을 설정할 때 한 Consul 서버 에이전트에서 CONSUL_HTTP_TOKEN 환경 변수를 일시적으로 부트스트랩 토큰으로 설정해요. 이렇게 하면 추가 ACL 토큰과 정책을 생성하기 위해 Consul과 상호작용하는 데 필요한 권한을 얻을 수 있어요.

$ export CONSUL_HTTP_TOKEN=<token>

에이전트에 개별 토큰 적용 (Apply individual tokens to agents)

모든 서버와 클라이언트 에이전트에는 ACL 토큰이 필요해요. Consul 데이터센터의 각 서버 및 클라이언트 에이전트에 대해 다음 단계를 완료해요.

  1. 에이전트 토큰 생성
  2. 에이전트에 토큰 추가

에이전트 토큰 생성 (Create the agent token)

노드의 이름과 데이터센터로 노드 ID를 지정해 각 Consul 에이전트에 대한 개별 토큰을 생성해요. 노드 ID는 해당 이름으로 노드를 등록하고 카탈로그의 모든 서비스를 읽는 데 필요한 권한을 부여해요.

$ consul acl token create -description "<node_name> agent token" \
  -node-identity "<node_name>:<datacenter_of_node>"

이 명령은 설명과 노드 ID 정보를 포함한 토큰 정보를 반환해요.

각 에이전트에 대해 이 과정을 반복해요. 토큰을 안전한 위치에 저장하는 것은 ACL 관리자의 책임이에요. Vault를 사용해 이러한 토큰을 저장할 것을 권장해요.

에이전트에 토큰 추가 (Add token to agents)

Consul 클라이언트에 에이전트 토큰을 적용하기 전에 에이전트 토큰을 Consul 서버에 적용하고 올바르게 작동하는지 확인해요.

다음 방법 중 하나로 Consul 에이전트에 토큰을 추가할 수 있어요:

  • 에이전트 구성 파일에 토큰 추가
  • Consul CLI 사용
  • Consul HTTP API 사용

에이전트 구성 파일을 사용할 것을 권장해요. 그러면 에이전트가 재시작하면 에이전트 구성 파일에서 토큰을 다시 로드해요.

구성 파일: 에이전트 구성 파일에서 토큰을 설정하려면 기존 Consul 구성에 다음 코드 조각을 추가하거나 Consul 구성 디렉터리에 새 파일을 생성해요.

acl {
  tokens {
    agent  = "<agent_token_secret_id>"
  }
}

Consul 구성을 리로드하도록 에이전트 환경에서 CONSUL_HTTP_TOKEN을 동일한 토큰으로 설정해요.

$ export CONSUL_HTTP_TOKEN="<agent_token_secret_id>"

에이전트의 구성을 리로드해요.

$ consul reload

CLI: 에이전트 토큰을 설정하려면 set-agent-token 하위 명령을 사용해요.

acl:write 권한이 있는 토큰으로 CONSUL_HTTP_TOKEN을 설정해요. 부트스트랩 토큰을 사용하거나 global-management 정책을 사용해 새 토큰을 만들 수 있어요.

$ export CONSUL_HTTP_TOKEN="<bootstrap_token>"

그런 다음 토큰을 에이전트에 적용해요.

$ consul acl set-agent-token agent "<agent_token_secret_id>"

API: 에이전트 토큰을 설정하려면 /agent/token/agent API 엔드포인트를 사용해요.

acl:write 권한이 있는 토큰으로 X-Consul-Token을 설정해요. 부트스트랩 토큰을 사용하거나 global-management 정책을 사용해 새 토큰을 만들 수 있어요.

API 요청에 대한 페이로드를 생성해요.

payload.json:

{
  "Token": "<agent_token_secret_id>"
}

그런 다음 토큰을 에이전트에 적용해요. <agent_ip>를 Consul 에이전트의 IP 주소로 바꿔요.

$ curl \
    --request PUT \
    --data @payload.json \
    --header "X-Consul-Token: <<bootstrap_token>" \
    http://<agent_ip>:8500/v1/agent/token/acl_token

이 과정은 모든 에이전트에 대해 완료해야 해요.

완료되면 모든 에이전트는 Consul에 대한 읽기 및 쓰기 권한이 있지만 노드 관련 작업에만 해당하는 토큰을 가져야 해요. 개별 서비스에 대한 작업은 아직 허용되지 않아요.

기존 데이터센터에 ACL 부트스트랩

기존 데이터센터에 ACL을 부트스트랩한다면 토큰을 적용한 후 기본 정책을 default_policy = "deny"로 업데이트하고 또 다른 롤링 재시작을 시작해야 해요.

이 과정을 사용해 서버 에이전트에 항상 에이전트 토큰을 추가해야 해요. 그러나 Consul은 auto-config 기능을 사용해 클라이언트 에이전트에 필요한 에이전트 토큰을 자동으로 적용할 수 있어요. Auto-config는 OIDC ID 제공자(IdP)를 사용해 보안 JWT를 발급하고 검증하는 것을 포함해요.

서비스에 토큰 추가 (Add tokens to services)

서비스 토큰은 등록 및 헬스 체크를 포함한 카탈로그의 서비스 정보를 관리하는 데 필요해요.

서비스에 토큰을 생성하고 적용하는 과정은 에이전트와 유사해요.

  1. 서비스 토큰 생성
  2. 서비스 정의에 토큰 추가. 서비스 메시를 사용한다면 Envoy 사이드카 프록시에도 토큰을 제공해야 해요.

서비스 토큰 생성 (Create the service token)

서비스의 이름과 데이터센터로 서비스 ID를 지정해 각 Consul 서비스에 대한 개별 토큰을 생성해요. 서비스 ID는 해당 이름으로 서비스 인스턴스와 관련 서비스 메시 사이드카 프록시를 등록하고 카탈로그의 모든 서비스를 읽는 데 필요한 권한을 부여해요.

$ consul acl token create -description "Token for <service_name>" \
  -service-identity "<service_name>"

명령은 설명과 서비스 ID 정보를 포함한 토큰에 대한 정보를 반환해요. 토큰을 안전한 위치에 저장해요. Vault를 사용해 이러한 토큰을 저장할 것을 권장해요.

또는 Consul 인증 메서드를 사용해 서비스 토큰 생성을 자동화할 수 있어요. 인증 메서드는 Kubernetes, JWT, OIDC 또는 AWS-IAM 같은 신뢰할 수 있는 ID 소스의 속성을 적절히 범위가 지정된 정책이 있는 ACL 토큰에 매핑해요. 예를 들어 service-type 바인딩 규칙이 있는 인증 메서드를 통해 JWT 속성을 서비스 ID에 매핑해 검증된 JWT를 사용해 서비스 토큰을 생성할 수 있어요. Consul 인증 메서드가 생성한 서비스 ACL 토큰을 서비스와 그 사이드카 프록시에 제공하도록 외부 자동화를 설정하는 것은 여전히 ACL 관리자의 책임이에요.

서비스 정의에 토큰 추가 (Add token to service definition)

다음 예시 서비스 정의 파일은 서비스 메시와 서비스 디스커버리(비 메시) 사용 사례 모두에 대한 서비스 토큰을 지정해요. 서비스 속성의 전체 목록은 서비스 정의 참조를 참고해요.

서비스 메시:

HCL:

service {
  name = "dashboard",
  port = 9002,

  # This service instance's sidecar proxy should be given the same ACL token
  # when launched with "consul connect envoy".
  token = "57c5d69a-5f19-469b-0543-12a487eecc66",

  connect {
    sidecar_service {}
  }

  check {
    id = "dashboard-check",
    http = "http://localhost:9002/health",
    method = "GET",
    interval = "1s",
    timeout = "1s"
  }
}

JSON:

{
  "service": {
    "name": "dashboard",
    "port": 9002,

    "token": "57c5d69a-5f19-469b-0543-12a487eecc66",

    "connect": {
      "sidecar_service": {}
    },

    "check": {
      "id": "dashboard-check",
      "http": "http://localhost:9002/health",
      "method": "GET",
      "interval": "1s",
      "timeout": "1s"
    }
  }
}

서비스가 Consul의 서비스 메시에 등록되어 있다면 해당 사이드카 프록시에는 서비스 토큰이 필요해요. 토큰을 사이드카 프록시에 직접 제공해야 해요. Consul은 서비스 정의에서 토큰을 검색할 수 없어요.

consul connect envoy로 Envoy 사이드카 프록시 인스턴스를 시작할 때 환경 변수 또는 CLI 플래그를 통해 서비스 토큰을 제공해요.

  1. 환경 변수: CONSUL_HTTP_TOKEN 또는 CONSUL_HTTP_TOKEN_FILE
  2. CLI 플래그: -token 또는 -token-file

서비스 디스커버리(비 메시):

HCL:

service {
  name = "dashboard",
  port = 9002,

  token = "57c5d69a-5f19-469b-0543-12a487eecc66",

  check {
    id = "dashboard-check",
    http = "http://localhost:9002/health",
    method = "GET",
    interval = "1s",
    timeout = "1s"
  }
}

JSON:

{
  "service": {
    "name": "dashboard",
    "port": 9002,

    "token": "57c5d69a-5f19-469b-0543-12a487eecc66",

    "check": {
      "id": "dashboard-check",
      "http": "http://localhost:9002/health",
      "method": "GET",
      "interval": "1s",
      "timeout": "1s"
    }
  }
}

서비스 등록 지침은 서비스 및 헬스 체크 등록을 참고해요. 서비스가 이미 등록되어 있다면 토큰으로 다시 등록해요.

다음 단계 (Next steps)

이제 ACL 시스템을 부트스트랩하고 에이전트와 서비스에 대한 토큰을 생성했으니, Consul 운영, 서비스 상호작용, 에이전트 통신에 대한 접근을 제한하기 위해 추가 ACL 토큰과 정책을 생성할 수 있어요. 자세한 내용은 다음 리소스를 참고해요:

더 알아보기 (Learn more)