Git 민감한 파일 빼기

뾰족머리삼돌이·2025년 2월 1일

기타

목록 보기
6/7

프로젝트를 개발하다보면 여러가지 민감한 정보들을 프로퍼티 파일로 관리하게된다. 예를 든다면 DB정보, API key 등이 있을 수 있다. 이러한 민감정보들을 원격저장소 게시해버리면 외부에 노출되어 위험한상황(ex : 요금폭탄)이 발생할 수 있다.

이번 포스팅에서는 프로젝트를 진행할 때, 이 정보들을 관리하기 위해 고민했던 흔적들을 작성하려고 한다.

.gitignore

이 문제에 있어서 가장먼저 생각났던 방법이다.
Git에서는 .gitignore라는 파일을 통해 Git의 관리대상에서 제외될 항목들을 설정할 수 있다.

hello.*를 작성한다면 hello로 시작하는 모든 파일들을 Git의 관리대상에서 제외할 수 있고,
hello/를 작성한다면 hello 디렉토리 자체를 관리대상에서 제외할 수 있으며,
hello/*를 작성한다면 hello 디렉토리 바로 아래에 존재하는 모든 파일을 제외할 수 있다.

이를 이용하면 GitHub이나 GitLab같은 원격저장소에 원하느 파일들만 올라가도록 구성할 수 있다.
즉, 간단하게 전체 프로젝트에서 민감한 자료들을 제외시킬 수 있다.

예를들어, security 디렉토리 내의 모든 파일이 GitHub 에 올라가지 않도록 하고싶은 상황을 가정하자.

# .gitignore
security/

.gitignore 파일을 생성하고, 위 형태로 security 디렉토리에 해당하는 내용작성하면 Git의 관리대상에서 제외된다.

commit과 push를 해줬음에도 GitHub에는 security 디렉토리가 제외되는 것을 확인할 수 있다.

아쉬운 점

이 방법은 간단하지만, 아쉬운 점도 존재한다.
그 예로, 제외하고 싶은 파일이 Spring Boot의 프로퍼티 파일(.yml, .properties)인 경우가 있다.

.gitignore로 제외한 파일은 아예 GitHub에 게시되지 않으므로, 프로젝트와 동기화되는 프로퍼티 파일을 관리하기 번거로웠다.

개발과정에서 이 프로퍼티 파일이 수정되는 경우가 종종 있었는데,
이런 경우 GitHub에서 pull 이나 checkout 받는 것 만으로는 공유하는게 불가능하기 때문이다.

submodule

해결책을 찾던와중에 발견한 방법은 git의 submodule을 이용하는 것이었다.
서브모듈은 한 Repo안에 다른 Repo를 마운트 시키는 기능을 의미한다.

예를들어, A Repo와 B Repo가 존재한다고 가정해보자.
B를 A의 Submodule로 지정하면 A를 갱신할 때, 해당하는 버전의 B도 함께 가져오게된다.

예시

우선 서브모듈로 관리할 Repository를 하나 생성해주고, 명령어를 통해 기존의 Git 디렉토리와 연결해준다.


submodule 디렉토리와 .gitmodules라는 파일이 추가된 것을 확인할 수 있다.

Push를 해보면 Repository에 서브모듈이 제대로 추가된 것을 확인할 수 있다.
서브모듈 디렉토리 뒤의 Hash값은 해당 Repo의 커밋 Hash를 의미한다.

그런데 정작 서브모듈에는 아까 추가했던 security 디렉토리가 없다.
이를 위해서 서브모듈 디렉토리로 이동하여 commit과 push를 진행해준다.

서브모듈을 지닌 메인 Repo에는 바로 반영되지 않으므로, 명령어를 통해 최신화를 해줘야한다.

$ git submodule update --recursive
$ git submodule foreach git pull origin main

쓸모

Submodule을 이용하면 민감한 정보들만 관리하는 독립적인 Repository를 관리할 수 있다.
따라서, 팀원들과 공유하는 private Repository를 서브모듈로 설정하면 민감한 정보들을 안전하게 관리할 수 있다.

서브모듈이 설정된 경우, 일반적인 Clone을 했을 때 서브모듈이 함께 들어오지 않는다.

이미 Clone 한 경우에는

$ git submodule update --init --recursive

아직 Clone 하기 전이라면

$ git clone --recurse-submodules <repository-url>

명령을 통해 서브모듈 정보를 받아올 수 있다.

Spring 프로젝트 예시

yml 파일만 서브모듈로 관리하게 구성해둔 Spring 프로젝트다.
당연하게도 해당 Repo를 clone 하고 실행시키면 yml파일이 Spring 프로젝트 내부에 존재하지 않는다.

애플리케이션 동작을 위해서는 프로퍼티 파일이 필요하기 때문에 이 파일을 이동시키거나, 외부에 있음을 인식시켜줘야 한다.

tasks.register('update-properties', Copy){
	from("submodule/")
	into("src/main/resources")
	include("*.yml")
}

Gradle 기준으로, 위 형식처럼 서브모듈 폴더에 있는 파일을 Spring 프로젝트 내부로 이동시키는 Task를 작성하는 식으로 해결할 수 있다.

Task를 동작시키면 해당경로로 파일이 들어온다

참고

0개의 댓글