에이전트 mTLS 암호화 관리
에이전트 mTLS 암호화 관리 (Manage Agent mTLS Encryption)
이 주제는 Consul 데이터센터의 에이전트 간 상호 TLS(mTLS) 암호화에 대해 설명해요. 이 mTLS 암호화는 Consul 서비스 메시의 mTLS 암호화와는 구별돼요.
출처: 문서
본문
이 주제는 Consul 데이터센터의 에이전트 간 상호 TLS(mTLS) 암호화에 대해 설명해요.
이 mTLS 암호화는 Consul 서비스 메시 mTLS 암호화와는 구별돼요. 서비스 간 암호화된 mTLS 통신에 대해 알아보려면 서비스 메시 인증 기관을 참고해요.
TLS 암호화의 이점 (Benefits of TLS encryption)
Consul은 서버와 클라이언트의 진위를 검증하는 TLS 인증서를 지원해 RPC, gRPC, HTTP 트래픽을 보호해요.
Consul 데이터센터에서 TLS 암호화를 구현하면 배포의 보안이 다음과 같이 개선돼요:
- 전송 중 데이터 암호화: TLS는 Consul 데이터센터 노드와 UI 또는 CLI 같은 사용자 인터페이스 간 전송되는 데이터를 암호화해 민감한 정보가 승인되지 않은 당사자에게 노출되지 않도록 보장해요.
- 에이전트 인증: TLS는 인증서를 사용해 검증된 당사자만 서로 통신할 수 있도록 보장해요. 이 보안 조치는 승인되지 않은 노드, 서비스, 사용자가 Consul 데이터센터와 상호작용하는 것을 방지해요.
- 중간자(MITM) 공격 방지: TLS가 없으면 공격자가 Consul 배포 내의 통신을 가로채고 변경할 수 있어요. TLS는 데이터를 암호화하고 통신 참여자의 ID를 검증함으로써 이 위험을 완화해요.
- 보안 규정 및 표준 준수: PCI-DSS와 HIPAA 같은 규정 준수 프레임워크와 규정은 전송 중 데이터의 암호화를 요구하므로 규제 환경의 Consul 배포에서 TLS가 필요해요.
상호 TLS(mTLS)는 모든 클라이언트와 서버가 단일 인증 기관(CA)이 생성한 키 쌍을 가져야 해요. 다른 애플리케이션과 공유되지 않는 비공개 CA를 사용할 것을 권장해요.
에이전트 구성 파일의 다음 매개변수는 에이전트 검증 동작을 정의해요:
워크플로 (Workflow)
Consul 배포에서 TLS 암호화를 활성화하는 과정은 다음 단계로 구성돼요:
- 모든 인증서를 서명하는 데 사용되는 내장 CA 초기화.
- Consul 서버를 보호하기 위한 서버 인증서 생성.
- TLS 암호화를 위한 서버 에이전트 구성.
- 서버 에이전트 시작.
- Consul 클라이언트 에이전트 구성.
- 클라이언트 에이전트 시작.
내장 CA 초기화 (Initialize the built-in CA)
Consul용 mTLS를 구성하는 첫 번째 단계는 인증서를 서명하는 인증 기관(CA)을 초기화하는 것이에요. 무단 데이터센터 접근을 방지하기 위해 Consul은 모든 인증서가 동일한 CA로 서명되도록 요구해요. 비공개 CA를 사용할 것을 권장하는데, 이 CA가 서명한 모든 인증서는 Consul 데이터센터와 통신할 수 있도록 허용되기 때문이에요.
Consul은 자체 CA를 만들고 관리하는 다양한 도구를 지원해요. 예를 들어 Vault의 PKI 시크릿 엔진이나 Terraform TLS 제공자가 있어요. Consul에는 인증서를 만들고 관리하는 내장 TLS 도구도 포함돼요.
PATH에 Consul 바이너리가 설치되어 있다면 Consul 서버 에이전트를 시작하기 전에도 CA와 인증서를 만들 수 있어요.
$ consul tls ca create -domain=consul
==> Saved consul-agent-ca.pem
==> Saved consul-agent-ca-key.pem
명령은 <domain>-agent-ca.pem과 <domain>-agent-ca-key.pem 두 파일을 생성해요. 이 예시에서 인증서를 생성하는 데 사용된 도메인은 기본값인 consul이에요.
CA 인증서 consul-agent-ca.pem은 Consul 인증서를 검증하는 데 필요한 공개 키를 포함해요. Consul 에이전트가 실행되는 모든 노드에 이 인증서를 배포해야 해요.
CA 키 consul-agent-ca-key.pem은 Consul 노드의 인증서를 서명해요. 이 키는 비공개로 유지해야 해요. 이 키를 소유하면 누구나 신뢰할 수 있는 서버로 Consul을 실행하거나 데이터센터에 대한 새 유효 인증서를 생성할 수 있어요. 악의적인 행위자는 이 키를 사용해 ACL 토큰을 포함한 모든 Consul 데이터에 접근할 수 있어요.
서버 인증서 생성 (Create server certificates)
Consul 서버를 인증하려면 서버에 Common Name 및 Subject Alternative Name 필드에 server.<domain>.<datacenter>를 나열하는 특수 인증서가 제공돼요. tls.defaults.verify_server_hostname을 활성화하면 이 인증서를 제공하는 에이전트만 서버로 부팅할 수 있어요.
tls.defaults.verify_server_hostname = true가 없으면 Consul 클라이언트 에이전트를 손상시킨 공격자가 에이전트를 서버로 재시작해 데이터센터의 모든 데이터에 접근할 수 있어요. Consul 데이터를 보호하려면 서버 키를 비공개로 유지해야 해요.
다음 예시는 consul 도메인의 dc1 데이터센터에 대한 서버 인증서를 생성해요. 데이터센터나 도메인이 다르다면 적절한 플래그 값을 사용하도록 명령을 수정해요.
$ consul tls cert create -server -dc=dc1 -domain=consul
==> WARNING: Server Certificates grants authority to become a
server and access all state in the cluster including root keys
and all ACL tokens. Do not distribute them to production hosts
that are not server nodes. Store them as securely as CA keys.
==> Using consul-agent-ca.pem and consul-agent-ca-key.pem
==> Saved dc1-server-consul-0.pem
==> Saved dc1-server-consul-0-key.pem
CA를 만든 동일한 노드에서 인증서 수가 데이터센터의 서버 수와 같아질 때까지 이 과정을 반복해요. 명령을 연속으로 여러 번 실행할 수 있으며, 매번 인증서와 키 번호가 자동으로 증가해요.
페더레이션 Consul 데이터센터 (Federated Consul datacenter)
페더레이션 Consul 환경에서는 서버 인증서에 페더레이션 환경 내의 모든 Consul 데이터센터 이름이 포함되어야 해요.
Subject Alternative Name에 추가 DNS 이름을 제공하려면 -additional-dnsname 플래그를 사용해요. localhost는 항상 포함돼요. 단일 명령에서 이 플래그를 여러 번 제공할 수 있어요.
다음 예시는 dc1과 dc2라는 두 Consul 데이터센터를 포함하는 페더레이션 환경에 대한 인증서를 생성해요.
$ consul tls cert create -server -dc dc1 -domain=consul -additional-dnsname="server.dc2.consul"
==> WARNING: Server Certificates grants authority to become a
server and access all state in the cluster including root keys
and all ACL tokens. Do not distribute them to production hosts
that are not server nodes. Store them as securely as CA keys.
==> Using consul-agent-ca.pem and consul-agent-ca-key.pem
==> Saved dc1-server-consul-0.pem
==> Saved dc1-server-consul-0-key.pem
서버 에이전트 구성 (Configure server agents)
서버 인증서를 생성한 후 Consul 서버에 배포하고 에이전트 구성 파일을 수정해 로컬 위치를 포함해요.
각 Consul 서버에 다음 파일을 복사해요:
consul-agent-ca.pem: CA 공개 인증서.dc1-server-consul-0.pem:consul도메인의dc1데이터센터에서 첫 번째 서버 노드에 대한 Consul 서버 노드 공개 인증서.dc1-server-consul-0-key.pem:consul도메인의dc1데이터센터에서 첫 번째 서버 노드에 대한 Consul 서버 노드 개인 키.
클라이언트 에이전트에 인증서를 배포하는 원하는 방식에 따라 Consul 서버 에이전트를 구성하는 두 가지 방법이 있어요:
- 자동 암호화( auto encryption) 방법 은 Consul Connect CA를 사용해 클라이언트 인증서를 생성한 다음 모든 Consul 클라이언트에 자동으로 배포해요.
- 운영자(operator) 방법 은 클라이언트 인증서를 수동으로 생성하고 각 클라이언트 에이전트에 개별적으로 배포해야 해요.
내장 CA와 함께 자동 암호화 방법을 사용할 것을 권장해요. 그러면 운영자 개입 없이 Consul이 인증서를 자동으로 교체할 수 있기 때문이에요.
타사 CA를 사용해야 하거나 인증서 관리에 대한 더 세분화된 제어가 필요하다면 운영자 방법을 사용해요.
자동 암호화 방법:
HCL:
addresses = {
https = "0.0.0.0"
}
ports {
https = 8501
}
tls {
defaults {
ca_file = "consul-agent-ca.pem"
cert_file = "dc1-server-consul-0.pem"
key_file = "dc1-server-consul-0-key.pem"
verify_incoming = true
verify_outgoing = true
verify_server_hostname = true
}
}
auto_encrypt {
allow_tls = true
}
JSON:
{
"addresses": {
"https" : "0.0.0.0"
},
"ports": {
"https" : 8501
},
"tls" : {
"defaults": {
"ca_file": "consul-agent-ca.pem",
"cert_file": "dc1-server-consul-0.pem",
"key_file": "dc1-server-consul-0-key.pem",
"verify_incoming": true,
"verify_outgoing": true,
"verify_server_hostname": true
}
},
"auto_encrypt" : {
"allow_tls" : true
}
}
운영자 방법:
HCL:
addresses = {
https = "0.0.0.0"
}
ports {
https = 8501
}
tls {
defaults {
ca_file = "consul-agent-ca.pem"
cert_file = "dc1-server-consul-0.pem"
key_file = "dc1-server-consul-0-key.pem"
verify_incoming = true
verify_outgoing = true
verify_server_hostname = true
}
}
JSON:
{
"addresses": {
"https": "0.0.0.0"
},
"ports": {
"https": 8501
},
"tls": {
"defaults": {
"ca_file": "consul-agent-ca.pem",
"cert_file": "dc1-server-consul-0.pem",
"key_file": "dc1-server-consul-0-key.pem",
"verify_incoming": true,
"verify_outgoing": true,
"verify_server_hostname": true
}
}
}
Consul은 https 포트에 0보다 큰 포트 번호가 할당되지 않으면 HTTP에 대해 TLS를 활성화하지 않아요. https 포트의 기본 번호인 8501을 사용할 것을 권장하는데, 이 기본값은 다른 도구와 자동으로 작동하도록 설계되었기 때문이에요.
Consul 서버 시작 (Start Consul servers)
서버를 구성한 후 Consul 프로세스를 시작해요.
$ systemctl start consul
Consul 서버는 이제 RPC와 합의에 TLS 암호화를 사용해 통신할 수 있어요.
클라이언트 에이전트 구성 (Configure client agents)
다음으로 서버 에이전트를 구성할 때 사용한 것과 동일한 방법으로 클라이언트 에이전트를 구성해요.
자동 암호화 방법: 자동 암호화를 사용해 Consul 클라이언트 에이전트를 구성하는 데 로컬 디스크에서 필요한 유일한 파일은 CA 인증서 consul-agent-ca-.pem이에요.
HCL:
addresses = {
https = "0.0.0.0"
}
ports {
https = 8501
}
tls {
defaults {
ca_file = "consul-agent-ca.pem"
verify_incoming = true
verify_outgoing = true
verify_server_hostname = true
}
}
auto_encrypt = {
tls = true
}
JSON:
{
"addresses": {
"https": "0.0.0.0"
},
"ports": {
"https": 8501
},
"tls": {
"defaults": {
"ca_file": "consul-agent-ca.pem",
"verify_incoming": true,
"verify_outgoing": true,
"verify_server_hostname": true
}
},
"auto_encrypt" : {
"tls" : true
}
}
운영자 방법: CA와 서버 인증서를 만든 노드에서 consul tls cert create -client 명령으로 클라이언트 인증서를 생성해요.
$ consul tls cert create -client -dc=dc1 -domain=consul
==> Using consul-agent-ca.pem and consul-agent-ca-key.pem
==> Saved dc1-client-consul-0.pem
==> Saved dc1-client-consul-0-key.pem
클라이언트 인증서도 서버 인증서에 사용된 것과 동일한 CA로 서명되지만 Common Name과 Subject Alternative Name에 server.<domain>.<datacenter>를 포함하지 않아요. verify_server_hostname이 활성화되어 있으므로 손상된 클라이언트는 이 인증서를 사용해 서버로 시작하고 데이터센터 데이터에 접근할 수 없어요.
클라이언트 인증서와 CA 인증서 consul-agent-ca.pem을 데이터센터의 모든 Consul 클라이언트에 배포해요. 그런 다음 클라이언트 에이전트 구성에 추가해요.
HCL:
addresses = {
https = "0.0.0.0"
}
ports {
https = 8501
}
tls {
defaults {
ca_file = "consul-agent-ca.pem"
cert_file = "dc1-client-consul-0.pem"
key_file = "dc1-client-consul-0-key.pem"
verify_incoming = true
verify_outgoing = true
verify_server_hostname = true
}
}
JSON:
{
"addresses": {
"https": "0.0.0.0"
},
"ports": {
"https": 8501
},
"tls": {
"defaults": {
"ca_file": "consul-agent-ca.pem",
"cert_file": "dc1-client-consul-0.pem",
"key_file": "dc1-client-consul-0-key.pem",
"verify_incoming": true,
"verify_outgoing": true,
"verify_server_hostname": true
}
}
}
Consul 클라이언트 시작 (Start Consul clients)
각 클라이언트를 구성한 후 노드에서 Consul 프로세스를 시작해요.
$ systemctl start consul
클라이언트 에이전트는 이제 상호 TLS 암호화를 사용해 통신해요.
API, CLI, UI 상호작용 (API, CLI, and UI interactions)
이 페이지에 제공된 구성 스니펫은 Consul 데이터센터에 대한 완전한 mTLS를 구성하기에 유효해요. 즉 모든 인터페이스가 Consul 에이전트와 통신하려면 클라이언트가 유효한 인증서를 제공해야 해요. 이는 모든 요청, API, CLI, UI에 대해 유효해요.
Consul v1.12부터 다음에 대해 다른 설정을 가질 수 있어요:
- Consul의 REST API, CLI 통합, UI에 사용되는 HTTP 프로토콜
- Consul 에이전트 간 내부 통신에 사용되는 RPC 프로토콜
클라이언트 인증서 없이 Consul과 상호작용 (Interact with Consul without a client certificate)
HTTP API, CLI 또는 UI를 사용해 Consul과 상호작용할 때마다 유효한 클라이언트 인증서를 제시하는 것을 피하려면 tls.https.verify_incoming을 false로 설정해 Consul이 모든 들어오는 HTTPS 연결을 신뢰하도록 구성해요. RPC 통신은 여전히 mTLS로 암호화돼요.
HCL:
addresses = {
https = "0.0.0.0"
}
ports {
https = 8501
http = -1
}
tls {
https {
ca_file = "/etc/consul.d/consul-agent-ca.pem"
cert_file = "/etc/consul.d/consul-agent.pem"
key_file = "/etc/consul.d/consul-agent-key.pem"
verify_incoming = false
verify_outgoing = true
}
internal_rpc {
ca_file = "/etc/consul.d/consul-agent-ca.pem"
cert_file = "/etc/consul.d/consul-agent.pem"
key_file = "/etc/consul.d/consul-agent-key.pem"
verify_incoming = true
verify_outgoing = true
verify_server_hostname = true
}
}
JSON:
{
"addresses": {
"https": "0.0.0.0",
"http": "127.0.0.1",
},
"ports": {
"https": 8501,
"http": 8500
},
"tls": {
"https": {
"ca_file": "consul-agent-ca.pem",
"cert_file": "consul-agent.pem",
"key_file": "consul-agent-key.pem",
"verify_incoming": false,
"verify_outgoing": true
},
"internal_rpc": {
"ca_file": "consul-agent-ca.pem",
"cert_file": "consul-agent.pem",
"key_file": "consul-agent-key.pem",
"verify_incoming": true,
"verify_outgoing": true,
"verify_server_hostname": true
}
}
}
로컬 클라이언트 상호작용에 HTTP 사용 (Use HTTP for local client interaction)
로컬 Consul 에이전트와 상호작용할 때마다 유효한 클라이언트 인증서나 CA 인증서를 제시해야 하는 것을 피하려면 HTTP 리스너를 localhost 인터페이스에서만 활성화하고 tls.https.verify_incoming을 false로 설정하도록 Consul을 구성해요. API 또는 UI에 대한 외부 요청은 여전히 TLS 암호화로 보호되지만 로컬에서 시작된 요청은 클라이언트 인증서를 제시할 필요가 없어요. RPC 통신은 여전히 mTLS로 암호화돼요.
HCL:
addresses = {
https = "0.0.0.0"
http = "127.0.0.1"
}
ports {
https = 8501
http = 8500
}
tls {
https {
ca_file = "/etc/consul.d/consul-agent-ca.pem"
cert_file = "/etc/consul.d/consul-agent.pem"
key_file = "/etc/consul.d/consul-agent-key.pem"
verify_incoming = false
verify_outgoing = true
}
internal_rpc {
ca_file = "/etc/consul.d/consul-agent-ca.pem"
cert_file = "/etc/consul.d/consul-agent.pem"
key_file = "/etc/consul.d/consul-agent-key.pem"
verify_incoming = true
verify_outgoing = true
verify_server_hostname = true
}
}
JSON:
{
"addresses": {
"https": "0.0.0.0",
"http": "127.0.0.1",
},
"ports": {
"https": 8501,
"http": 8500
},
"tls": {
"https": {
"ca_file": "consul-agent-ca.pem",
"cert_file": "consul-agent.pem",
"key_file": "consul-agent-key.pem",
"verify_incoming": false,
"verify_outgoing": true
},
"internal_rpc": {
"ca_file": "consul-agent-ca.pem",
"cert_file": "consul-agent.pem",
"key_file": "consul-agent-key.pem",
"verify_incoming": true,
"verify_outgoing": true,
"verify_server_hostname": true
}
}
}
지원되는 인증 기관(CA) 비교 (Compare supported Certificate Authorities (CAs))
Consul은 에이전트 통신 암호화를 위해 여러 인증 기관(CA)을 지원해요.
다음 표는 각 CA로 Consul 운영을 보호하기 위해 생성해야 하는 인증서를 나열해요:
| 인증 기관 | 서버 인증서 | 클라이언트 인증서 | Envoy 인증서 |
|---|---|---|---|
| Consul 내장 CA | ✅ | ✅ (수동) | ❌ |
| Consul 서비스 메시 CA | ❌ | ✅ (auto_config 또는 auto_encrypt) |
✅ |
| 타사 CA | ✅ | ✅ (수동) | ❌ |
| Vault | ✅ | ✅ (auto_config 또는 auto_encrypt) |
✅ |
아래 표는 다양한 CA에 대한 기본값과 저장 위치를 포함한 다양한 옵션의 개요를 제공해요.
| 기능 | Consul 에이전트 CA | Consul 서비스 메시 CA | 타사 CA |
|---|---|---|---|
| 인증서 생성 | 수동 | 자동 | 다양함 |
| 인증서 교체 | 수동 | 자동 | 다양함 |
| 인증서 저장 위치 | Raft 상태 저장소 | 에이전트 메모리 | Raft 상태 저장소 |
| CA 인증서 기본 만료 | 5년 | 10년 | 다양함 |
| 에이전트 인증서 기본 만료 | 1년 | 3일 | 다양함 |
다음 단계 (Next steps)
이제 에이전트가 암호화된 통신을 위한 mTLS로 구성되었어요. 자동 암호화 방법에서는 클라이언트 인증서가 서버에 의해 관리돼요. 운영자 방법에서는 모든 인증서를 수동으로 배포했지만 더 유연한 구성이 가능해요.
이 주제에서 사용된 명령에 대한 문서는 Consul 에이전트 구성 파일의 TLS 구성 매개변수와 consul tls CLI 명령 참조에서 확인할 수 있어요.
TLS 인증서 생성 및 교체를 자동화하는 방법은 Vault로 Consul용 mTLS 인증서 생성 튜토리얼을 참고해요.
Consul 배포 보안을 계속 강화하려면 가십 암호화를 추가하고 기본 거부 정책으로 액세스 제어 목록(ACL)을 활성화해요.