OpenSSL로 TLS 암호화 활성화
OpenSSL로 TLS 암호화 활성화 (Enable TLS encryption with OpenSSL)
이 페이지에서는 OpenSSL을 사용하여 TLS 암호화를 활성화해 Consul 에이전트 통신을 보호하는 방법을 설명해요. Consul은 TLS를 사용하여 서버와 클라이언트의 신뢰성을 확인할 수 있어요. TLS를 활성화하려면 Consul은 모든 서버가 단일 CA(인증 기관)가 서명한 인증서를 보유해야 해요. 클라이언트도 동일한 CA로 인증된 인증서를 보유해야 해요.
출처: 문서
본문
이 페이지에서는 OpenSSL을 사용하여 TLS 암호화를 활성화해 Consul 에이전트 통신을 보호하는 방법을 설명합니다. Consul은 TLS를 사용하여 서버와 클라이언트의 신뢰성을 확인할 수 있습니다. TLS를 활성화하려면 Consul은 모든 서버가 단일 CA(인증 기관)가 서명한 인증서를 보유해야 합니다. 클라이언트도 동일한 CA로 인증된 인증서를 보유해야 합니다.
이 페이지는 OpenSSL에 대한 TLS 암호화 활성화 지침을 제공합니다. Consul의 기본 제공 CA를 사용하는 데 관심이 있다면 Enable TLS encryption with built-in CA를 참조하세요.
워크플로우 (Workflow)
다음 단계는 새 Consul 데이터센터에 대해 TLS 암호화를 활성화하는 일반적인 워크플로우를 설명합니다:
- 인증서 만들기
- 에이전트 구성
- 서버 인증서 배포
- 클라이언트 인증서 배포
- 서버 및 클라이언트 인증서용 SAN 구성
TLS 암호화를 활성화한 후 Consul CLI와 UI가 HTTPS를 사용하도록 구성할 수 있습니다.
인증서 만들기 (Create certificates)
Consul 데이터센터에 대해 TLS 암호화를 활성화하려면 각 에이전트가 인증서를 노출하도록 구성해야 합니다.
openssl이 있는 모든 머신에서 이러한 인증서를 만들 수 있습니다. 이 지침의 예제는 Consul 에이전트에 대해 server.dc1.consul, 클라이언트에 대해 client.dc1.consul을 사용합니다.
서버 인증서 서명 요청 만들기 (Create server certificate signing requests)
Consul 서버를 인증하려면 서버에 Common Name에 server.dc1.consul이 포함된 특수 인증서가 제공됩니다. verify_server_hostname을 활성화하면 이 인증서를 제공하는 에이전트만 서버로 부팅할 수 있습니다. verify_server_hostname = true가 없으면 공격자가 Consul 클라이언트 에이전트를 손상시키고 에이전트를 서버로 다시 시작하여 데이터센터의 모든 데이터에 액세스할 수 있습니다. 이러한 서버 인증서는 특수하며 서버만 프로비저닝해야 합니다.
개인 키로 인증서 서명 요청을 만듭니다. 다음 명령은 Common Name이 server.dc1.consul인 CSR을 생성합니다. 데이터센터 이름과 도메인을 사용하도록 CSR을 구성하세요.
$ openssl req -new -newkey rsa:2048 -nodes -keyout server1.dc1.consul.key -out server1.dc1.consul.csr -subj '/CN=server.dc1.consul'
Generating a RSA private key
.......................................................................+++++
...................+++++
writing new private key to 'server1.dc1.consul.key'
-----
이 명령은 두 개의 파일을 만듭니다.
$ ls -1
server1.dc1.consul.csr
server1.dc1.consul.key
CSR 서명 (Sign the CSR)
경고 (Warning)
이러한 서명 명령은 인프라에 적용되지 않을 수 있는 기본 매개변수와 구성에 기반합니다. 프로덕션 인증서를 발급하는 경우 조직의 CA 관리자나 내부 프로세스에 연락하여 요청에 서명하세요.
요청에 서명하세요. -CA 및 -CAkey 매개변수를 사용하여 인증서를 서명할 인증 기관 인증서와 키를 제공하세요.
CA를 처음 사용하여 인증서에 서명하는 경우 -CAcreateserial 옵션을 사용할 수 있습니다. 이 옵션은 일련번호가 포함된 .srl 확장자 파일을 만듭니다. 다음에 요청에 서명할 때는 일련번호가 포함된 파일 이름을 따라 -CAserial 옵션을 사용하세요.
$ openssl x509 -req -in server1.dc1.consul.csr -CA consul-agent-ca.pem -CAkey consul-agent-ca-key.pem -CAcreateserial -out server1.dc1.consul.crt
Signature ok
subject=CN = server.dc1.consul
Getting CA Private Key
이 명령은 새 파일 *.cst를 만듭니다.
$ ls -1
server.dc1.consul.crt
server1.dc1.consul.csr
server1.dc1.consul.key
인증서 정보가 올바른지 확인하세요.
$ openssl x509 -text -noout -in server1.dc1.consul.crt
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
08:11:59:bf:1f:a7:fd:f3:46:1c:fc:cb:a3:86:73:59:ee:6f:40:0b
Signature Algorithm: ecdsa-with-SHA256
Issuer: C = US, ST = CA, L = San Francisco, street = 101 Second Street, postalCode = 94105, O = HashiCorp Inc., CN = Consul Agent CA 110700113239230823036492076258083826915
Validity
Not Before: Jan 10 13:16:54 2020 GMT
Not After : Feb 9 13:16:54 2020 GMT
Subject: CN = server.dc1.consul
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
## ...
Signature Algorithm: ecdsa-with-SHA256
## ...
기본적으로 생성된 인증서는 한 달 동안 유효합니다. 서명 명령에서 -days 매개변수를 사용하여 이 값을 변경할 수 있습니다.
CA를 만든 동일한 서버에서 각 서버에 대해 개별 인증서가 있을 때까지 이 프로세스를 반복하세요.
클라이언트 인증서 만들기 (Create clients certificate)
다음 예제는 여러 클라이언트에서 공유할 수 있는 단일 클라이언트 인증서를 만듭니다. 더 세분화된 인증서 정책이 필요한 경우 아래 단계를 반복하여 여러 클라이언트 인증서를 만드세요.
CSR을 만드세요.
$ openssl req -new -newkey rsa:2048 -nodes -keyout client.dc1.consul.key -out client.dc1.consul.csr -subj '/CN=client.dc1.consul'
Generating a RSA private key
............................................................+++++
.........................................................+++++
writing new private key to 'client.dc1.consul.key'
-----
인증서에 서명하세요.
$ openssl x509 -req -in client.dc1.consul.csr -CA consul-agent-ca.pem -CAkey consul-agent-ca-key.pem -out client.dc1.consul.crt
Signature ok
subject=CN = client.dc1.consul
Getting CA Private Key
에이전트 구성 (Configure agents)
이제 인증서를 만들었으니 데이터센터에서 TLS를 활성화해야 합니다. 다음 단계는 새 Consul 배포에 대해 TLS를 구성하는 방법을 자세히 설명합니다.
인증서 배포 (Distribute the certificates)
Consul이 만든 인증서를 사용하도록 만든 인증서를 TLS로 보호하려는 에이전트에 복사하세요.
모든 Consul 에이전트는 구성을 완료하려면 3개의 파일이 필요합니다:
- CA 공개 인증서:
ca_file매개변수로 정의되며 다른 노드의 아이덴티티를 확인하는 데 사용됩니다. 이 지침에서 CA 공개 인증서는consul-agent-ca.pem이라고 합니다. - Consul 에이전트 공개 인증서:
cert_file매개변수로 정의됩니다. - Consul 에이전트 개인 키:
key_file매개변수로 정의됩니다.
Consul은 시작 디렉터리에서 이러한 인증서 파일을 찾습니다. 파일을 그곳에 저장했다면 이름만으로 에이전트 구성 파일에 추가할 수 있습니다. 인증서 파일이 시작 디렉터리에 없으면 에이전트 구성 파일에서 경로를 지정해야 합니다.
서버 구성 (Configure servers)
Consul이 구성을 로드하는 -config-dir 디렉터리에 제안된 매개변수를 별도의 파일로 추가할 수 있습니다. 이 접근 방식은 구성을 분리하는 데 도움이 되지만 옵션을 단일 구성 파일에 포함할 수도 있습니다.
다음 Consul 서버용 에이전트 TLS 구성 예제는 배포된 인증서 파일을 보여줍니다.
Consul server TLS configuration
HCL:
verify_incoming = true
verify_outgoing = true
verify_server_hostname = true
ca_file = "consul-agent-ca.pem"
cert_file = "server.dc1.consul.crt"
key_file = "server.dc1.consul.key"
ports {
http = -1
https = 8501
}
JSON:
{
"verify_incoming": true,
"verify_outgoing": true,
"verify_server_hostname": true,
"ca_file": "consul-agent-ca.pem",
"cert_file": "server.dc1.consul.crt",
"key_file": "server.dc1.consul.key",
"ports": {
"http": -1,
"https": 8501
}
}
Consul은 verify_outgoing 및 verify_server_hostname으로 서버의 신뢰성을 확인하기 위해 TLS를 사용할 수 있습니다. verify_incoming을 사용할 때 클라이언트 인증서를 선택적으로 확인할 수도 있습니다.
예제 구성은 암호화된 통신만 있도록 HTTP 포트도 비활성화합니다. HTTPS가 활성화되면 모든 CLI, API, UI 통신이 인증서로 아이덴티티를 확인해야 합니다. 이는 consul members 및 UI와 같은 기본 제공 도구에 영향을 줍니다.
클라이언트 구성 (Configure clients)
생성된 인증서와 키를 사용하도록 클라이언트 구성을 활성화하세요. 다음은 예제 에이전트 TLS 구성입니다.
Consul client TLS configuration
HCL:
verify_incoming = true
verify_outgoing = true
verify_server_hostname = true
ca_file = "consul-agent-ca.pem"
cert_file = "client.dc1.consul.crt"
key_file = "client.dc1.consul.key"
ports {
http = -1
https = 8501
}
JSON:
{
"verify_incoming": true,
"verify_outgoing": true,
"verify_server_hostname": true,
"ca_file": "consul-agent-ca.pem",
"cert_file": "client.dc1.consul.crt",
"key_file": "client.dc1.consul.key",
"ports": {
"http": -1,
"https": 8501
}
}
이 예제 구성은 암호화된 통신만 있도록 HTTP 포트를 비활성화합니다. HTTPS를 사용할 준비가 되지 않은 기존 클라이언트는 그 후에는 연결할 수 없습니다.
Consul 에이전트 시작 (Start Consul agents)
이제 Consul 에이전트를 구성했으니 Consul 서버를 시작하세요. 시작 로그가 TLS가 활성화되었음을 확인합니다: TLS-Outgoing: true 및 TLS-Incoming: true.
$ consul agent -config-dir=/etc/consul.d/
==> Starting Consul agent...
Version: 'v1.6.2+ent'
Node ID: '80933b30-f4ba-5ba2-64e0-4cf48014904e'
Node name: 'server-dc1-2'
Datacenter: 'dc1' (Segment: '<all>')
Server: true (Bootstrap: true)
Client Addr: [0.0.0.0] (HTTP: -1, HTTPS: 8501, gRPC: -1, DNS: 8600)
Cluster Addr: 10.20.10.12 (LAN: 8301, WAN: 8302)
Encrypt: Gossip: false, TLS-Outgoing: true, TLS-Incoming: true, Auto-Encrypt-TLS: false
서버 및 클라이언트 인증서용 SAN 구성 (Configure SANs for server and client certificates)
curl과 같은 도구가 같은 호스트에서 실행될 때 Consul의 HTTPS API와 통신할 수 있도록 서버 및 클라이언트 인증서에서 localhost와 127.0.0.1을 주체 대체 이름(Subject Alternative Names)으로 사용하는 것이 일반적입니다. 인증서 서명 요청에 SAN을 하나 이상 추가하려면 명령에 -config 옵션을 추가하세요:
$ openssl req -new -newkey rsa:2048 -nodes -keyout server1.dc1.consul.key -out server1.dc1.consul.csr -subj '/CN=server.dc1.consul' -config <(
cat <<-EOF
[req]
req_extensions = req_ext
distinguished_name = dn
[ dn ]
CN = *.dc1.consul
[ req_ext ]
basicConstraints=CA:FALSE
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = consul.example.com
DNS.2 = localhost
IP.1 = 127.0.0.1
EOF
)
SAN이 포함된 요청에 서명하려면 사용 중인 CA에 따라 다른 단계와 구성이 필요할 수 있습니다. CA 관리자나 내부 프로세스에 연락하여 요청에 서명하세요.
서명 후 인증서를 검사하여 DN과 SAN이 Subject: CN 및 X509v3 Subject Alternative Name 인증서 필드에 올바르게 나열되었는지 확인하세요.
$ openssl x509 -text -noout -in server1.dc1.consul.crt
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
2e:fa:94:75:21:c6:f7:d9:83:ad:3a:93:65:a8:98:0d:ed:2f:ae:5c
Signature Algorithm: ecdsa-with-SHA256
Issuer: C = US, ST = CA, L = San Francisco, street = 101 Second Street, postalCode = 94105, O = HashiCorp Inc., CN = Consul Agent CA 110700113239230823036492076258083826915
Validity
Not Before: Jan 13 11:07:49 2020 GMT
Not After : Jan 12 11:07:49 2021 GMT
Subject: CN = server.dc1.consul
Subject Public Key Info:
## ...
X509v3 extensions:
## ...
X509v3 Subject Alternative Name:
DNS:consul.example.com, DNS:localhost, IP Address:127.0.0.1
Signature Algorithm: ecdsa-with-SHA256
##...
경고 (Warning)
인프라에 SAN이 필요한 경우 모든 인증서 서명 요청 명령에 모든 도메인 이름과 함께
-config플래그를 포함해야 합니다.
인증서가 올바른 SAN으로 제대로 구성되지 않으면 명령을 실행할 때 오류가 발생할 수 있습니다.
$ consul members -http-addr="https://localhost:8501"
Error retrieving members: Get https://localhost:8501/v1/agent/members?segment=_all: x509: certificate is valid for server.dc1.consul, not localhost
Consul CLI 구성 (Configure the Consul CLI)
데이터센터가 HTTPS로만 통신하도록 구성된 경우 API와 Consul CLI 명령을 계속 액세스하려면 추가 인증서를 만들어야 합니다.
먼저 새 인증서를 생성하세요.
$ openssl req -new -newkey rsa:2048 -nodes -keyout cli.client.dc1.consul.key -out cli.client.dc1.consul.csr -subj '/CN=cli.client.dc1.consul'
Generating a RSA private key
....................................................+++++
...........................+++++
writing new private key to 'cli.client.dc1.consul.key'
-----
인증서를 제공하지 않으면 Consul CLI가 오류를 반환합니다.
$ consul members -http-addr="https://server.dc1.consul:8501"
Error retrieving members: Get https://server.dc1.consul:8501/v1/agent/members?segment=_all: remote error: tls: bad certificate
방금 만든 인증서를 사용하여 Consul을 쿼리하세요.
$ consul members \
-http-addr="https://server.dc1.consul:8501" \
-ca-file="consul-agent-ca.pem" \
-client-cert="cli.client.dc1.consul.crt" \
-client-key="cli.client.dc1.consul.key"
명령이 에이전트 목록을 반환합니다.
Node Address Status Type Build Protocol DC Segment
server-dc1-1 10.20.10.11:8301 alive server 1.6.2+ent 2 dc1 <all>
server-dc1-2 10.20.10.12:8301 alive server 1.6.2+ent 2 dc1 <all>
client-dc1-1 10.20.10.21:8301 alive client 1.6.2+ent 2 dc1 <default>
또한 매 명령마다 인증서 정보를 지정하지 않도록 다음 환경 변수를 설정할 수 있습니다:
CONSUL_HTTP_ADDR를 Consul 에이전트의 URL로 설정하고-http-addr의 기본값을 설정합니다.$ export CONSUL_HTTP_ADDR=https://server.dc1.consul:8501CONSUL_CACERT를 CA 인증서 위치로 설정하고-ca-file의 기본값을 설정합니다.$ export CONSUL_CACERT=consul-agent-ca.pemCONSUL_CLIENT_CERT를 CLI 인증서 위치로 설정하고-client-cert의 기본값을 설정합니다.$ export CONSUL_CLIENT_CERT=cli.client.dc1.consul.crtCONSUL_CLIENT_KEY를 CLI 키 위치로 설정하고-client-key의 기본값을 설정합니다.$ export CONSUL_CLIENT_KEY=cli.client.dc1.consul.key
서비스 등록 및 Consul 서비스 메시용 사이드카 프록시 시작을 포함한 모든 Consul CLI 및 API 명령에 인증서를 지정해야 합니다.
Consul UI를 HTTPS용으로 구성 (Configure the Consul UI for HTTPS)
HTTPS가 활성화되면 UI에 더 이상 액세스할 수 없습니다. UI를 실행하려는 Consul 에이전트 두 개를 선택하고 새 인증서를 만든 후 지침을 따라 UI를 다시 실행하는 것을 권장합니다.
$ openssl req -new -newkey rsa:2048 -nodes -keyout cli.client.dc1.consul.key -out cli.client.dc1.consul.csr -subj '/CN=cli.client.dc1.consul'
Generating a RSA private key
....................................................+++++
...........................+++++
writing new private key to 'cli.client.dc1.consul.key'
-----
바인딩할 인터페이스 선택 (Select an interface to bind to)
설정에 따라 바인딩할 인터페이스를 변경해야 할 수 있습니다. 기본적으로 UI는 127.0.0.1에 바인딩됩니다.
addresses.https 또는 client_addr를 사용하여 인터페이스를 업데이트하세요. 이러한 값을 업데이트할 때는 DNS 서버에도 영향을 주므로 주의하세요.
0.0.0.0에 바인딩하는 것을 권장합니다.
HCL:
ui = true
client_addr = "0.0.0.0"
enable_script_checks = false
disable_remote_exec = true
JSON:
{
"ui": true,
"client_addr": "0.0.0.0",
"enable_script_checks": false,
"disable_remote_exec": true
}
Consul 에이전트가 이제 네트워크에서 사용 가능하므로 enable_script_checks가 false이고 disable_remote_exec가 true인지 확인하세요.
Consul UI 액세스 (Access the Consul UI)
Consul UI에 액세스하는 방법은 두 가지가 있습니다.
- 브라우저에 클라이언트 인증서를 추가하고 CA 인증서를 신뢰합니다.
verify_incoming_rpc를 활성화하고verify_incoming을 비활성화합니다.
브라우저에 클라이언트 인증서 추가 (Add a client certificate to your browser)
UI 트래픽에도 상호 TLS를 사용하려면 브라우저에 클라이언트 인증서를 추가하세요. 이렇게 하면 인증서가 있는 브라우저로 UI 액세스가 제한됩니다. Consul CA를 제공하지 않으면 Consul UI에 액세스할 수 없습니다.
이 문제를 해결하려면 머신에서 Consul CA(consul-agent-ca.pem)를 신뢰하세요. CA를 신뢰한 후 UI에 액세스할 수 있습니다.
$ curl https://consul.example.com:8501/ui/ --resolve 'consul.example.com:8501:127.0.0.1' -I
HTTP/2 200
## ...
verify_incoming_rpc 활성화 및 verify_incoming 비활성화 (Enable verify_incoming_rpc and disable verify_incoming)
verify_incoming이 활성화되면 Consul은 모든 인바운드 연결이 TLS를 사용하고 클라이언트가 ca_file 또는 ca_path의 CA가 서명한 인증서를 제공하도록 요구합니다. 이 제한은 서버 RPC와 HTTPS API 모두에 적용됩니다.
브라우저는 CA가 서명한 인증서를 제시하지 않으므로 UI에 액세스할 수 없습니다. HTTPS UI를 curl하면 오류가 반환됩니다.
$ curl https://server.dc1.consul:8501/ui/ --cacert consul-agent-ca.pem -I
curl: (35) error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate
Consul HTTPS 서버는 Consul CA가 서명한 클라이언트 인증서를 제시하지 않으므로 연결을 거부합니다. HTTPS가 아닌 RPC에 verify_incoming을 사용하도록 Consul을 구성할 수 있습니다.
HCL:
verify_incoming = false
verify_incoming_rpc = true
JSON:
{
"verify_incoming": false,
"verify_incoming_rpc": true
}
이 예제 구성을 적용하면 UI에 액세스할 수 있습니다.
$ curl https://server.dc1.consul:8501/ui/ --cacert consul-agent-ca.pem -I
HTTP/2 200
## ...