Reload SSL Certificates From HashiCorp Vault for Spring Boot

1. 개요

응용 프로그램과 장치는 SSL 인증서를 사용하여 연결을 보안합니다. 이들은 서버와 클라이언트 간의 통신을 안전하게 하는 데 도움을 줍니다. 이러한 인증서는 만료 시간이 있으며 교체해야 합니다.

이 교체를 수동으로 수행하는 것은 시간이 많이 소요되고 다운타임이나 나쁜 사용자 경험으로 이어질 수 있습니다. 이 기사에서는 이 인증서를 핫 리로드하는 방법을 배웁니다. 우리는 HashiCorp Vault를 사용하여 Spring Boot 애플리케이션에서 이 작업을 수행할 것입니다.

2. 주요 개념

이 섹션에서는 이후 섹션에서 유용한 몇 가지 기본 개념에 대해 배웁니다.

2.1. SSL 인증서

SSL은 웹 서버와 웹 브라우저 간에 암호화된 링크를 생성하는 보안 프로토콜인 Secure Sockets Layer의 약자입니다.

SSL 인증서는 웹사이트 또는 서버의 신원을 인증하고 암호화된 연결을 생성하는 디지털 인증서입니다. 이 인증서에는 발급자 기관 이름, 수신자, 공개 키, 만료 날짜 및 웹사이트나 서버의 진위를 확인하는 데 필요한 기타 세부 정보와 같은 정보가 포함됩니다.

위의 기사 전체에서 “인증서”라는 단어를 사용할 때 SSL 인증서를 지칭합니다.

2.2. X.509 인증서

X.509는 디지털 인증서를 정의하기 위한 표준 중 하나입니다. 인터넷에서 가장 일반적으로 사용되는 표준입니다. 웹사이트 또는 서버의 신원과 공개 키를 포함하며, 인증 기관에 의해 서명되거나 자체 서명됩니다.

2.3. 루트 CA

SSL 영역에는 널리 신뢰받는 몇몇 기관이 있으며, 이들은 인증서를 발급합니다. 이러한 기관을 루트 CA(인증 기관)라고 하며, 예를 들면 GeoTrust, DigiCert 등이 있습니다. 이들이 발급하는 인증서는 루트 인증서라고 합니다. 운영 체제와 브라우저는 이러한 신뢰하는 루트 CA를 인식하여 다른 인증서를 검증할 수 있도록 합니다. 이 시스템은 사용자가 웹사이트에 안전하게 연결하고 그 신원을 확인할 수 있도록 보장합니다.

2.4. 중간 CA

루트 CA 인증서를 직접 노출하는 것은 특정 보안 문제를 일으킬 수 있습니다. 이를 완화하기 위해 루트 CA와 최종 사용자 인증서 간의 링크 역할을 하는 중간 CA(인증 기관)를 생성합니다. 필요에 따라 가능한 한 많은 중간 CA를 생성할 수 있습니다. 각 중간 CA는 부모 CA를 대신하여 인증서를 발급하여 루트 CA의 개인 키를 직접 노출하지 않고 신뢰 체인을 만듭니다.

이 설정은 루트 CA를 안전하게 유지하면서 중간 CA가 인증서를 검증하고 발급할 수 있도록 하여 보안을 강화합니다. 브라우저와 장치는 이 신뢰 체인을 통해 웹사이트 및 서비스에 대한 안전한 연결을 보장합니다.

2.5. HashiCorp Vault

Vault는 토큰, 비밀번호, 키, 디지털 인증서와 같은 민감한 정보를 안전하게 저장하고 접근하기 위한 도구입니다. HashiCorp는 여러 제품을 보유한 회사이며, 그 중 하나가 Vault입니다. Vault는 비밀을 저장하고, 비밀을 회전시키며, 데이터를 암호화하고 인증서도 발급합니다.

2.6. PKI 비밀 엔진

HashiCorp Vault에서 우리는 동적 X.509 인증서를 생성하기 위해 PKI 비밀 엔진을 사용합니다. 이 비밀 엔진을 활용하면 서비스는 개인 키와 CSR(인증서 서명 요청)을 생성하고 CA에 제출하고 검증 및 서명 프로세스 완료를 기다리는 일반 수동 프로세스를 거치지 않고 인증서를 얻을 수 있습니다.

2.7. Vault 에이전트

Vault 서버와 통신하여 인증서의 발급을 요청하는 클라이언트 데몬입니다. 특정 디렉토리에서 정기적으로 인증서를 생성하도록 구성할 수 있습니다. Vault 에이전트를 이용하여 인증서의 핫 리로드를 구현할 것입니다.

지금까지 우리는 SSL 세계와 HashiCorp Vault에 관련된 몇 가지 기본 개념을 이해했습니다. 이제 이러한 구성 요소가 어떻게 함께 작동하여 Spring Boot 애플리케이션이 HashiCorp Vault에서 발급된 인증서를 핫 리로드할 수 있도록 하는지를 이해해 보겠습니다.

간단히 말해, 우리는 애플리케이션이 설정된 디렉토리에서 인증서의 만료 시 인증서를 다시 로드할 수 있도록 할 것입니다. 별도의 프로세스인 Vault 에이전트가 Vault 서버에 인증서 발급을 요청한 후 정기적으로 해당 디렉토리에 인증서를 기록합니다.

3. Vault 서버 구성

우리는 루트 CA보다 중간 CA를 사용하는 것이 낫다고 보았습니다. 이번 섹션에서는 Vault 서버를 설정하고 루트 CA와 중간 CA를 구성하겠습니다.

3.1. Vault 서버에서 루트 CA 구성

먼저, 이 가이드를 따라 Vault를 설치하고 vault -v 명령어를 실행하여 버전을 확인합니다.

이제 다음 명령어를 하나씩 실행하여 루트 CA를 설정합니다:


여기서는 개발 모드에서 Vault 서버를 시작합니다. 기본적으로 localhost:8200에서 실행됩니다. 우리는 root를 토큰으로 설정했습니다. 웹 브라우저에서 localhost:8200에서 Vault 서버의 GUI에 접근할 수 있습니다.

우리는 addresstoken을 내보내고, 이는 이후 명령어에서 사용됩니다. 그리고 만료 시간이 최대 24시간인 인증서를 발급하기 위해 경로 /pki에서 PKI 비밀 엔진을 활성화합니다.

또한 CRL 위치와 발급 인증서의 위치를 지정합니다. 마지막으로, 최대 만료 시간이 12시간인 루트 인증서를 발급할 수 있는 localhost-12라는 역할을 생성합니다.

3.2. Vault 서버에서 중간 CA 구성 

위 섹션과 같이 명령어를 실행하여 중간 CA를 설정하겠습니다:


여기서는 최대 만료 시간이 12시간인 PKI 비밀 엔진을 경로 /pki-int에서 활성화했습니다.

그런 다음 중간 인증서 서명 요청을 생성하여 파일 pki-intermediate.csr에 저장합니다. 이 서명 요청을 서명하고, 루트 CA를 사용하여 서명합니다. 이후 우리는 중간 인증서 기관의 서명 인증서를 루트 서명 인증서로 설정합니다.

마지막으로 3시간 만료되는 인증서를 발급할 수 있는 역할 localhost-3을 생성합니다.

이제 중간 인증서 기관이 구성되었습니다. 다음 명령어를 사용하여 이를 테스트할 수 있습니다:

vault write pki-int/issue/localhost-3 common_name="localhost" ttl=1h

이 명령어는 터미널에 만료 시간이 1시간인 인증서를 생성해야 합니다.

이것은 인증서를 생성하는 수동적인 방법입니다. 중간 CA에서 인증서를 자동으로 생성하려면 Vault 에이전트를 사용하겠습니다.

4. Vault 에이전트 구성

중간 CA를 사용하기 위해서는 역할 localhost-3에 정책을 연결하여 PKI 비밀 엔진을 사용할 수 있도록 해야 합니다:

path "pki-int/issue/localhost-3" {
 capabilities = ["update"]
}

위의 코드를 policy.hcl라는 파일에 저장하고 아래 명령어를 실행하여 이 정책을 생성합니다:

vault policy write vault-agent-policy path/to/policy.hcl

이제 AppRole와 같은 인증 방법을 활성화하겠습니다:

vault auth enable approle

vault write auth/approle/role/localhost-3 \                           
  token_policies="vault-agent-policy" \
  secret_id_ttl="24h" \
  token_ttl="1h" \
  token_max_ttl="4h"

위 명령어는 역할 localhost-3vault-agent-policy에 연결합니다.

역할 ID와 비밀 ID를 파일에 기록합니다.

vault read auth/approle/role/localhost/role-id

echo “role-id-from-above-command" > role-id

vault write -f auth/approle/role/localhost/secret-id

echo “secret-id-from-above-command" > secret-id

이제 템플릿을 구성하고 이를 template.tpl라는 파일에 저장합니다:

{{- with pkiCert "pki-int/issue/localhost-3"¨NBSP;"common_name=localhost" "alt_names=localhost" "ttl=5m" -}}
{{ .Cert }}{{ .CA }}{{ .Key }}
{{ .Key | trimSpace | writeToFile "/path/to/private_key.key" "" "" "0400" }}
{{ .CA | trimSpace | writeToFile "/path/to/ca.pem" "" "" "0644" }}
{{ .Cert | trimSpace | writeToFile "/path/to/certificate.crt" "" "" "0644" }}
{{- end -}}

이 템플릿에서 이전에 생성한 역할 localhost-3는 5분의 만료 시간을 가진 인증서를 생성하고 이를 파일에 저장합니다. 인증서 만료 전에 매번 Vault 서버에 인증서를 발급해 달라고 요청하고 해당 파일에 기록합니다.

마지막으로 Vault 에이전트의 구성 파일이 필요합니다:

pid_file = "/paht/to/pidfile.pid"

vault {
 address = "http://localhost:8200"
}

auto_auth {
 method {
   type = "approle"
   config = {
     role_id_file_path                   = "/path/to/role-id"
     secret_id_file_path                 = "/path/to/secret-id"
     remove_secret_id_file_after_reading = false
   }
 }
}

template {
 source       = "/path/to/template.tpl"
 destination  = "/path/to/all-certs"
}

이 구성을 vault_agent.hcl라는 파일에 저장합니다. 이 파일에서는 Vault 서버의 주소, 인증 방법, template.tpl 파일의 위치 및 Vault 에이전트가 모든 인증서와 키를 기록하는 대상 파일 all-certs에 대해 언급합니다. 그런 다음 Vault 에이전트가 자신의 프로세스 ID를 기록하는 데 사용할 pidfile.pid 파일을 생성합니다.

이제 아래 명령어를 실행하여 Vault 에이전트를 시작합니다:

sudo vault agent -config=/path/to/vault_agent.hcl

우리의 Vault 에이전트가 시작되었습니다. private_key.key, ca.pem, certificate.crt, all-certs 파일에서 인증서 생성 여부를 확인할 수 있습니다. 우리는 권한 문제를 피하기 위해 sudo 명령으로 실행하고 있습니다.

이제 Vault 서버와 Vault 에이전트를 구성했으니 Spring Boot 애플리케이션을 구성하겠습니다.

5. Spring Boot 애플리케이션 구성

먼저, spring-boot-starter-webspring-cloud-starter-vault-config를 포함한 Spring Boot 애플리케이션을 생성합니다:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>3.4.0</version>
</dependency>

둘째, 인증서를 읽고 핫 리로드하기 위해 application.properties 파일에 다음 Spring Boot 속성을 추가합니다:


위 속성은 template.tpl 파일에서 언급한 private_key.keycertificate.crt 파일의 위치를 참조합니다. Spring Boot는 콘텐츠가 변경될 때 이러한 위치에서 인증서를 자동으로 읽고 리로드합니다.

인증서가 유효할 때만 애플리케이션이 성공적으로 시작됩니다. 우리는 또한 로그를 통해 이를 확인할 수 있습니다. 5분 이상 로그를 모니터링하면 다음과 같은 로그를 볼 수 있습니다:

Connector [https-jsse-nio-8080], TLS virtual host [_default_], certificate type [UNDEFINED] configured from keystore [/Users/$HOME/.keystore] using alias [tomcat] with trust store [null]

위 로그는 인증서가 리로드될 때마다 계속 나타납니다.

6. 결론

이 기사에서는 많은 작업을 수행했습니다. 우리는 SSL 및 HashiCorp Vault와 관련된 기본 개념을 배우는 것으로 시작했습니다. 우리는 루트 CA와 중간 CA에 대해 배우고 중간 CA 인증서의 중요성도 이해했습니다.

다음으로 우리는 몇 가지 구성을 수행했습니다. Vault 서버를 실행하고 루트 CA를 구성하고 중간 CA를 설정하는 방법을 배웠습니다. 우리는 또한 Vault 에이전트를 탐색하고 그의 중요성과 인증서를 발급하기 위해 이를 구성하고 실행하는 방법을 배웠습니다.

마지막으로 우리는 Spring Boot 애플리케이션을 만들고 이를 인증서 핫 리로드에 맞게 구성했습니다.

원본 출처

You may also like...

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다