본문 바로가기
👾 Server/🏭 배포

secret, config 파일 관리 방법 소개(feat. SpringBoot의 application.*)

by kukim 2022. 7. 1.

잘못된 내용이나 다른 의견 있다면 편하게 말씀해주세요 🙏🏻

들어가며

SpringBoot 프로젝트를 GitHub public repo에서 작업 후 배포한다고 가정하자.

 

SpringBoot의 설정 파일은 application.* 또는 DB 초기 설정을 위한. sql 등이 있다.

application.* 파일에는 DB 접속 정보(url, username, password)나 secret key 관리 등 많은 파일이 들어있다.

이를 public repo에 공개하면 문제가 발생할 수 있다.

 

외부 노출을 막고 배포하는 방법 알아보자


방법

방법 1 : 로컬 개발 환경에서 application.* 설정 파일 그대로 사용하고 외부 저장소 노출을 막기 위해. gitignore 설정, 배포 시 application.yml 직접 넣어주기

로컬 개발 환경의 application.yml 파일엔 하드 코딩으로 설정값들을 넣고 사용한다.

.gitignore에 application.yml를 넣어 Git에서 버전 관리하지 않도록 설정한다.

// username, password가 노출된 application.yml 예 -> 해당 파일을 .gitignore로 지정하여 git에서 관리하지 않도록 설정한다.
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://10.10.10.10:3306/testDB
    username: kukim
    password: password1234

배포

- 배포 시 존재하지 않는 application.* 파일을 직접 넣어 배포한다.

 

단점

- 배포에 필요한 설정 파일을 직접 넣어야 한다.


방법 2 : 설정 값들을 ${} 환경변수로 지정한다. 배포 시 환경변수를 넣기 (Git Secrets)

설정값을 ${} 환경변수로 사용한다.

// 환경변수로 secret를 지정한 application.yml, 해당 환경변수는 배포 환경에 반드시 넣어줘야 한다.
spring:
    datasource:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://${MYSQL_HOST}:3306/airbnb
      username: ${MYSQL_USERNAME}
      password: ${MYSQL_PASSWORD}

배포

- CI 환경에서는 application.* 파일의 환경 변수를 GitHub secret를 사용한다.

- 배포 환경에서는 별도의 환경 변수를 지정하여 실행한다.

 

장점

- 외부 노출을 막을 수 있다.

- GitHub secrets에 환경 변수를 지정하여 GitHub Actions에서 사용할 수 있다.

단점

- 모든 배포 환경에 별도의 환경변수를 지정해줘야 한다. 


방법 3 : application.* 파일을 private repo의 Git Submodules으로 사용하기

Git Submodules란 저장소 안에 다른 저장소를 원하는 디렉토리를 복제하는 기능이다. 예를 들어 A,B 프로젝트에서 공통되게 사용하는 모듈(라이브러리, 설정 값 등) C가 있다고 하자. A,B,C 모두 저장소이다. 이때 A, B 저장소에 C 소스 코드가 중복될 수 있다. 이를 A,B 저장소에 C를 서브 모듈로 두어 공통되게 사용할 수 있다. C가 수정되면 A,B 모두 수정된 코드를 사용할 수 있다. (생활 코딩 : 저장소안에 저장소 - git submodules youtube) 

 

배포

- GitHub private repo를 만들고 repo에 application.* 파일들을 넣는다. (private repo 권한이 있는 사람만 확인할 수 있다)

- spring 프로젝트가 담겨있는 public repo에 private repo를 submoudles화 한다.

- 프로젝트 배포할 때 submodules의 설정 파일들을 /src/main/resources으로 복사하여 사용한다.

- 해당 파일들은 .gitignore 파일로 push하지 않는다.

- public repo 여도 config 파일은 서브 모듈로 private repo이기 때문에 권한이 없는 사용자들은 설정 파일에 접근할 수 없다.

- CI에서 사용한다면, private repo를 clone 할 수 있는 Github Key를 넘겨 설정 파일을 clone 할 수 있다.

 

장점

- 설정 파일을 별도의 환경 변수로 설정하지 않는다.

- GitHub와 연동이 쉽다.

 

단점

- private repo라고 해도 설정 값들이 암호화되어있는 것이 아니기에 private repo 노출 시 취약할 수 있다.

Git 서브모듈


방법 4 : 설정 파일 암호화

application.* 파일의 설정 값들을 암호화하여 사용한다. 외부 노출되어도 암호화되어있기 때문에 보안 문제를 방지할 수 있다.

Java의 Jasypt(Java Simplified Encryption) 패키지를 사용하여 설정 파일들을 암호화할 수 있다.

 

배포

- 암호화한 설정 파일을 사용한다.

 

장점

- 로컬,배포 환경의 설정파일을 동일하게 사용할 수 있다.

- 설정파일 외부 유출되어도 암호화 되어있기에 비교적 안전하다

 

단점

- 암호화 값을 추가해야 한다. (별도 관리 비용 발생)


방법 5 : 외부 서비스 연동(별도 Config Server 사용)

별도의 Config를 관리하는 Server를 사용하여 배포 시 Config server와 통신하여 설정 파일들을 가져온다. 

Spring Cloud Config 또는 Aws System Manager, AppConfig 를 사용할 수 있다.

 

배포 

- 배포 시 해당 서비스로부터 Config 파일들을 받아온다.

 

장점

- 여러 서버 설정 파일을 별도 서버에서 관리할 수 있다. (e.g. MSA))

- Spring Cloud Config 사용 시, 서버를 재배포하지 않고 런타임 시에 설정 파일을 교체할 수 있다.

 

단점

- 별도의 관리가 필요하다.

- 외부 서비스 사용 비용이 발생한다.


많은 서비스를 배포한다면 방법 5(외부 서비스 사용)가 좋아 보인다.

작은 서비스에선 방법 1,2,3,4를 고려할 수 있다. 이전 프로젝트들에 방법 1,2(application.* 생성, 환경 변수 사용)으로 배포했었으나 상당히 많은 시간적 비용 발생하거나 환경 변수 설정을 잊어 서버 문제를 한 번에 확인하기 어려웠다.

앞으로 크지 않은 개인 프로젝트, GitHub 저장소를 활용해 배포한다면 방법3, 4(Git Submodules, 설정 파일 암호화)를 고려하려 한다.

방법 4의 경우 별도의 암호화 과정이 들어가야 하기 때문에, 방법 3이 편해 보인다. 


⛓ Reference

생활 코딩 : 저장소안에 저장소 - git submodules youtube

Git Submodules

JASYPT(Java Simplified Encryption)

Aws System Manager, AppConfig

Spring Cloud Config

Spring Cloud Config 도입하기 

댓글