Vault를 적용하게된 계기는 application.yml 파일에 DB접속 URL 등 다양한 개인정보들이 git에 노출되는것이 문제여서 적용하게 되었다. 기존에는 Jasypt 를 이용해서 암호화 하였는데 이것 역시 secret 키값이 프로젝트 코드속에 있어서 마음만 먹으면 secret 키값을 알아내서 암호화를 풀수 있다.
Vault는 분산시스템에서 사용되고 시크릿한 정보들을 스프링 클라우드에서 데이터를 가져온다. 지금 프로젝트에서는 분산 시스템이 아니지만 나중에 분산시스템으로 변경 했을때 사용될수 있을것 같아서 미리 도입해 보았다.
그리고 환경변수에 값을 인입하는 방법도 있지만 그 많은 개인정보들을 환경변수에서 관리하면 데이터들이 늘어날수록 관리의 복잡성이 늘어나서 한계가 있다.
환경변수에는 비밀정보가 아닌 애플리케이션 실행 환경값만을 사용하는것이 좋다.
ex) 스프링 프로필명, 포트번호, JVM 힙메모리 설정
Spring Cloud란
Vault를 적용하기 앞서 Spring Cloud를 알아야 한다.
Spring Cloud란 스프링부트를 기반으로한 분산 시스템을 개발하기 위한 일련의 도구를 제공하는 프레임워크이다.
Spring Cloud Config는 분산 시스템중에서 외부화된 구성에 대한 서버측 및 클라이언트를 제공하는것이다. 대표적으로 구성정보를 관리하는 서버는 git과 vault가 있고 프로젝트에는 vault를 사용하였다.
BootStrap
application.yml에 비밀 구성정보를 기입하려면 서버가 application.yml 로드전에 Vault 정보를 불러와야 하는데 이것을 해주는게 bootstrap 이다. 아래 그림에서 보듯이. bootstrap.yml 정보를 가지고 Vault를 접속하여 정보를 가져오고 application.yml에 정보를 기입하는 구조이다.
Vault 적용
build.gradle.kts 파일에 의존성 추가.
위에서 설명한 Spring Cloud Config, Vault, Bootstrap을 사용하기위해서 3가지 의존성을 추가한다.
//vault
implementation("org.springframework.cloud:spring-cloud-starter-bootstrap:4.1.4")
implementation("org.springframework.cloud:spring-cloud-config-server:4.1.3")
implementation("org.springframework.cloud:spring-cloud-starter-vault-config:4.1.3")
Vault 설치
AWS EC2 Ubuntu 서버에 설치하였다. 공식사이트에서 제공해주는 설치방법으로는 설치가 안돼서 wget 명령어로 설치파일을 가져와서 설치하는 방법으로 설치하였다.
wget으로 zip 파일을 가져오고 unzip으로 압축을 풀어서 /usr/local/bin/ 으로 이동시키면 전역에서 vault 명령어를 사용할 수 있다.
wget https://releases.hashicorp.com/vault/1.14.1/vault_1.14.1_linux_amd64.zip
unzip vault_1.14.1_linux_amd64.zip
sudo mv <Vault 바이너리 경로> /usr/local/bin/
Vault 운영서버 구축
vault server -dev 명령어를 통해서 개발 서버로 구축하면 Valut 서버를 로컬서버에서 밖에 접속할수 밖에 없다 그리고 설정정보를 가진 데이터들이 인메모리에 저장되기 때문에 서버를 중지시키면 데이터들이 다 날라가는 단점이 있다. 그래서 운영으로 구축하였다.
운영서버로 구축하려면 설정정보가 있는 파일을 생성해야 한다.
$ sudo mkdir -p /etc/vault
$ sudo mkdir -p /srv/vault/data
$ sudo vi /etc/vault/config.hcl
[config.hcl 파일내용]
아래 구성내용은 공식 홈페이지의 Vault 기본 구성 매뉴얼 을 참고하여 작성한것이다. 만약 https 를 사용한다면 이 Vault 공식 홈페이지를 참고하면 된다.
storage "raft" {
path = "/srv/vault/data"
node_id = "node1"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = "true"
}
api_addr = "http://127.0.0.1:8200"
cluster_addr = "https://127.0.0.1:8201"
ui = true
storage "raft" 방식은 HA Cluster 방식 이라고도 하는데 하나의 서버가 다운되거나 장애가 생거더라도 자동으로 복구가 가능하다. 그리고 각 서버들에 대해서 데이터들의 일관성들을 보장한다.
listener은 Vault가 API 요청을 수신하는 방식을 구성한다. address = "0.0.0.0:8200" 으로 세팅하여 모든 IP에서 요청이 가능하고 tls_disable 하여 https 가 아니더라도 요청을 수락한다. Vault는 기본적으로 보안상 tls를 활성화 하는데 tls를 활성화 하려면 키파일이 필요하다.
api_addr은 로컬에서 API에 접속할수 있는 주소이고, cluster_addr은 노드간의 접속을 할수 있게 하는 주소이다.
ui = true 로 하면 Vault UI 웹으로 접속할 수 있다.
Vault 백그라운드 실행
-config 로 설정파일 경로와 파일을 지정하고 백그라운드로 실행을 한다.
$ sudo sh -c 'vault server -config=/etc/vault/config.hcl >> /var/log/vault_sys.log 2>&1 &'
그리고 아래 명령어로 vault 최초 사용을 위해 초기화 시킨다.
$ vault operator init
그러면 아래 처럼 unseal key 5개와, token 이 주어진다. 이거는 잊어버리지 않고 개인보관해야 한다.
Vault UI 접속
그리고 IP:8200번 포트로 접속하면 아래 UI 화면이 들어가진다.
Unseal Key Portion에 위에서 받은 Unseal key를 3번 입력하면 오른쪽 화면으로 변경되고 위에서 받은 Token 값을 인입해주고 Sign in 해주면된다.
Vault KV 데이터 생성
맨처음 접속된 Secrets Engines 에서 Enable new engine + 버튼을 클릭하고
KV를 만들어준다. 이름은 secret 으로 만들었다.
그리고 application 이름으로 Create secret을 만들어주고
아래와 같이 application.yml 에 필요한 정보들을 기입해주면된다.
스프링부트 Vault 연동
프로젝트로 돌아가서 bootstrap.yml 파일을 만들고 아래 정보들을 기입해주면된다.
spring.cloud.vault.uri에 주소를 넣어주고, spring.cloud.vault.token에 발급받은 token값을 기입해주면 된다.
kv.backed: 값과, default-context 값으로 위에 Vault UI에서 만든 secret/application의 값들을 가져올수 있다.
Vault 데이터 적용
그리고 application.yml 에 application에 만든 값을 ${} 로 통해서 쓸수있다.
Vault 데이터 확인
값이 제대로 가져왔는지는 테스트 코드를 통해서 확인하면 된다.
참고
- https://wlsdn3004.tistory.com/11
'Project > B2C-Side-Project(third)' 카테고리의 다른 글
[SpringBoot] 포트원 API 이용한 결제 기능 추가 (0) | 2024.09.23 |
---|---|
[SpringBoot] 회원가입 구조 퍼사드 패턴 적용과 SRP 원칙 적용 (0) | 2024.09.17 |
[SpringBoot] 3차 프로젝트 자바에서 코틀린 전환 회고 (0) | 2024.08.20 |