본문 바로가기
  • 개발 삽질 블로그
TroubleShooting

[GitHub] BFG Repo-Cleaner를 이용하여 깃허브에 올라간민감 정보 지우기

by 갹둥 2024. 11. 2.

플젝을 진행하면서 계속 private repository로 진행했는데...코드 좀 다듬고(아직 멀었음)

1차 배포 테스트 후 public으로 바꿨습니다. 

 

근데...

바로 경고 이메일 날라왔어요...OAuth 로그인을 위해 사용하는 API Key가 노출되었다는 것 인데요...

현재는 바꾼 상태이지만, 초기에 팀원분이 로그인 구현하실 때 application-local.yml에 올리고 PR 날리셨고

그것을 제가 리뷰하면서 오케이했고...플젝 초기에 이런거 정말 유의해야하는데...다른 코드 보다가 놓쳤나보네요

 

 

어쨌든 개인정보를 소중하게 보호하기 위해서는 빨리 지워야합니다.

여러 가지 방법이 있습니다.

 

 

해결 방법 정리

  1. git rebase -i 사용하기:
    • 오래된 커밋의 메시지를 수정하거나 파일을 제거하려면, 인터랙티브 리베이스를 사용하여 커밋을 수정해야 합니다. 하지만 만약 수정할 커밋이 너무 오래 전이라면, 현재 브랜치의 HEAD에서 너무 멀리 떨어진 커밋을 직접 수정하기 어려울 수 있습니다.
  2. BFG Repo-Cleaner 사용하기:
    • 가장 손쉬운 방법은 BFG Repo-Cleaner를 사용하는 것입니다. 이 도구는 민감한 데이터를 제거하는 데 매우 효과적이며, 사용이 간편합니다. 아래는 간단한 사용 방법입니다:
     
  3. git filter-branch 사용하기:
    • 더 복잡하지만, 특정 커밋의 파일을 제거하려면 filter-branch를 사용할 수 있습니다. 그러나 이 방법은 상당히 복잡할 수 있으며, Git에 대한 경험이 필요합니다.

 

 

저는 BFG Repo-Cleaner를 사용하여 문제를 해결하였습니다.

 

 

BFG Repo-Cleaner 사용하기

 

1. 저장소 클론

먼저 Git 저장소를 미러 클론합니다.

git clone --mirror https://github.com/reponame
cd reponame​

 

 

* 미러 클론(mirror clone)은 Git에서 저장소를 완벽하게 복제하는 방식 중 하나입니다. 일반적인 git clone과는 다르게, 미러 클론은 저장소의 모든 참조(브랜치, 태그, 히스토리 등)를 그대로 가져오며, 이를 통해 원본 저장소의 완벽한 복제본을 만들 수 있습니다. 주로 원격 저장소 전체를 복제하거나 민감한 정보를 제거하는 등의 작업을 할 때 유용하게 사용됩니다.

 

2. BFG Repo-Cleaner 다운로드

아래 링크에서 jar 파일을 다운받았습니다. 

https://rtyley.github.io/bfg-repo-cleaner

 

BFG Repo-Cleaner by rtyley

$ bfg --strip-blobs-bigger-than 100M --replace-text banned.txt repo.git an alternative to git-filter-branch The BFG is a simpler, faster alternative to git-filter-branch for cleansing bad data out of your Git repository history: Removing Crazy Big Files Re

rtyley.github.io

 

 

3. BFG를 실행하여 삭제

공식 문서에서 볼 수 있듯이 여러가지 bfg 옵션이 있습니다.

  •  --replace-text:
    • 특정 텍스트(예: 비밀번호, API 키)를 이전 커밋 기록에서 찾아서 변경할 때 사용합니다. 이 옵션을 통해 원하는 값을 저장소의 모든 커밋에서 일괄 변경할 수 있습니다.
    • 사용법: 텍스트(ex. secrets.txt) 파일에 교체할 텍스트를 정의해두면, 해당 텍스트가 모든 커밋에서 새로운 값으로 대체됩니다.
      • secrets.txt 작성법: secrets.txt 파일에는 민감한 정보와 대체 텍스트를 입력합니다. 
      • password ==> ***  # password라는 문자를 ***로 대체
        apiKey ==> [REDACTED] # apiKey라는 문자를 [REDACTED]로 대체
        importantKey # importantKey라는 문자를 공백으로 대체
  •  --delete-files <file-pattern>
    • 특정 파일(예: application-local.yml)을 삭제할 때 사용하는 옵션입니다. 이전 커밋에 있는 파일도 이 옵션으로 제거할 수 있습니다.
  •  --delete-folders <folder-pattern>
    • 특정 폴더를 삭제할 때 사용하는 옵션입니다. 민감한 정보가 포함된 디렉토리 전체를 삭제할 수 있습니다.
  • --no-blob-protection
    • Git의 기본 보호 설정을 무시하고, 모든 블롭(blob)에 대해 명령을 적용하는 옵션입니다. 민감한 정보가 한 번도 커밋되지 않은 상태에서도 실수로 커밋된 경우 강제 삭제할 때 유용합니다.
    • 주의 사항: 이 옵션은 주의해서 사용해야 하며, 필요한 경우에만 사용하는 것이 좋습니다.
  • --protect-blobs-from
    • 특정한 커밋이나 브랜치를 보호하고 싶을 때 사용합니다.
    • 사용법: java -jar bfg.jar --protect-blobs-from HEAD <repository>
      HEAD를 보호 대상으로 지정하면, 최신 커밋을 보호하고 그 외 커밋의 정보만 변경합니다.
  •  --strip-blobs-bigger-than <size>
    • 지정한 크기보다 큰 파일을 커밋 내역에서 제거할 때 사용합니다. 저장소 용량을 줄이는 데 유용합니다.
  • --replace-text-all
    • 특정 텍스트를 모든 커밋에 걸쳐 삭제할 때 사용합니다. --replace-text와 달리, 모든 곳에서 해당 텍스트를 삭제하고 특정한 대체 텍스트로 변경하지 않습니다.

저는  --replace-text 옵션을 사용하여 특정 문자열들을 치환해주었어요

대치할 문자들을 정의한 텍스트 파일을 만들고 실행해주었습니다.

java -jar ../bfg-1.14.0.jar --replace-text replace.txt

 

 

 

application-local.yml이 성공적으로 수정되었습니다.

 

4. BFG 사용 후 가비지 수집 수행

git reflog expire --expire=now --all  # 모든 브랜치의 reflog를 즉시 만료(expire)시키는 명령
git gc --prune=now --aggressive  # Git의 가비지 컬렉터(garbage collector)를 실행하여 불필요한 파일과 데이터를 정리

 

 

 

5. 원격에 Push

git push

 

수정 반영된 커밋 history

깃허브에 들어가서 확인해보니 깔끔하게 수정이 되었네여

 

 

교훈: 커밋 하나하나 신중하게 작업하자