Skip to main content

Removing sensitive data from a repository(리포지토리에서 중요한 데이터 제거)

암호 또는 SSH 키와 같은 중요한 데이터를 Git 리포지토리에 커밋하는 경우 기록에서 제거할 수 있습니다.

리포지토리에서 중요한 데이터 제거 정보

git filter-repo 같은 도구 또는 BFG 리포지토리 클리너를 사용하여 리포지토리의 기록을 변경할 때는, 특히 열린 끌어오기 요청 및 중요한 데이터와 관련된 의미를 이해하는 것이 중요합니다.

git filter-repo 도구와 BFG Repo-Cleaner는 리포지토리의 기록을 다시 씁니다. 이로 인해 사용자가 변경하는 기존 커밋과 거기에 종속된 커밋의 SHA가 변경됩니다. 변경된 커밋 SHA는 리포지토리에서 열려 있는 끌어오기 요청에 영향을 줄 수 있습니다. 리포지토리에서 파일을 제거하기 전에 모든 열려 있는 끌어오기 요청을 병합하거나 닫는 것이 좋습니다.

git rm을 사용하면 마지막 커밋에서 파일을 제거할 수 있습니다. 최신 커밋으로 추가된 파일을 제거하는 방법에 대한 자세한 내용은 ‘GitHub의 대용량 파일 정보’을(를) 참조하세요.

중요한 데이터 노출 정보

이 문서에서는 GitHub.com의 리포지토리에 있는 분기 또는 태그에서 중요한 데이터에 연결할 수 없도록 커밋하는 방법에 대해 설명합니다. 그러나 이러한 커밋은 다른 곳에서도 계속 액세스할 수 있습니다.

  • 리포지토리의 모든 클론 또는 포크에서
  • GitHub Enterprise Cloud의 캐시된 뷰에서 SHA-1 해시를 통해 직접
  • 이를 참조하는 끌어오기 요청을 통해.

다른 사용자의 클론 또는 리포지토리 포크에서 중요한 데이터를 제거할 수는 없지만 GitHub 지원 포털 사용.에 문의하여 GitHub Enterprise Cloud에 대한 끌어오기 요청에서 캐시된 뷰 및 중요한 데이터에 대한 참조를 제거할 수 있습니다.

Important

GitHub 지원은(는) 중요하지 않은 데이터를 제거하지 않으며 영향을 받는 자격 증명을 순환하여 위험을 완화할 수 없다고 판단되는 경우에 중요한 데이터를 제거하는 데 도움이 됩니다.

GitHub Enterprise Cloud에 커밋을 푸시했으면 중요한 커밋 데이터의 손상을 고려해야 합니다. 암호를 커밋한 경우 암호를 변경해야 합니다. 키를 커밋한 경우 새 키를 생성하세요.

중요한 데이터를 도입한 커밋이 모든 포크에 있는 경우 계속 액세스할 수 있습니다. 포크 소유자와 조정하여 중요한 데이터를 제거하거나 포크를 완전히 삭제하도록 요청해야 합니다. GitHub은(는) 이러한 소유자에 대한 연락처 정보를 제공할 수 없습니다.

리포지토리의 기록을 다시 작성하기로 결정할 때 이러한 제한 사항을 고려하세요.

리포지토리의 기록에서 파일 제거

git filter-repo 도구 또는 BFG Repo-Cleaner 오픈 소스 도구를 사용하여 리포지토리의 기록에서 파일을 제거할 수 있습니다.

Note

중요한 데이터가 이진 파일로 식별된 파일에 있는 경우, 데이터를 제거하거나 바꾸기 위해 그 파일을 수정할 수 없으므로, 기록에서 파일을 제거해야 합니다.

BFG 사용

BFG Repo-Cleaner는 오픈 소스 커뮤니티에서 빌드하고 유지 관리하는 도구입니다. 원치 않는 데이터를 더 빠르고 간단하게 제거하기 위해 git filter-repo에 대한 대안을 제공합니다.

예를 들어, 중요한 데이터를 포함하는 파일을 제거하고 최근 커밋을 그대로 두려면 다음을 실행합니다.

bfg --delete-files YOUR-FILE-WITH-SENSITIVE-DATA

리포지토리의 기록에서 passwords.txt에 나열된 모든 텍스트를 바꾸려면 다음을 실행합니다.

bfg --replace-text passwords.txt

중요한 데이터가 제거된 후에는 변경 내용을 GitHub Enterprise Cloud로 강제 푸시해야 합니다. 강제 푸시하면 리포지토리 기록이 다시 작성되어 커밋 기록에서 중요한 데이터가 제거됩니다. 강제 푸시하는 경우 다른 사용자가 작업을 기반으로 한 커밋을 덮어쓸 수 있습니다.

git push --force

자세한 사용법과 다운로드 지침은 BFG Repo-Cleaner 설명서를 참조하세요.

git filter-repo 사용

Warning

변경 내용을 스태시한 후에 git filter-repo를 실행할 경우 다른 스태시 명령을 사용하여 변경 내용을 가져올 수 없습니다. git filter-repo를 실행하기 전에, 적용한 모든 변경 내용을 스태시 해제하는 것이 좋습니다. 스태시한 마지막 변경 내용 세트를 스태시 해제하려면 git stash show -p | git apply -R을 실행합니다. 자세한 내용은 Git 도구 - 스태시 및 정리를 참조하세요.

git filter-repo가 작동하는 방식을 설명하기 위해, 리포지토리 기록에서 중요한 데이터를 포함하는 파일을 제거한 다음 실수로 다시 커밋되지 않도록 .gitignore에 추가하는 방법을 보여 드리겠습니다.

  1. git filter-repo 도구의 최신 릴리스를 설치합니다. git-filter-repo는 수동으로 설치하거나 패키지 관리자를 사용하여 설치할 수도 있습니다. 예를 들어, HomeBrew를 사용하여 도구를 설치하려면 brew install 명령을 사용하세요.

    brew install git-filter-repo
    

    자세한 내용은 newren/git-filter-repo 리포지토리의 INSTALL.md를 참조하세요.

  2. 기록에 중요한 데이터가 포함된 리포지토리의 로컬 복사본이 아직 없다면 로컬 컴퓨터에 리포지토리를 복제합니다.

    $ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
    > Initialized empty Git repository in /Users/YOUR-FILE-PATH/YOUR-REPOSITORY/.git/
    > remote: Counting objects: 1301, done.
    > remote: Compressing objects: 100% (769/769), done.
    > remote: Total 1301 (delta 724), reused 910 (delta 522)
    > Receiving objects: 100% (1301/1301), 164.39 KiB, done.
    > Resolving deltas: 100% (724/724), done.
    
  3. 리포지토리의 작업 디렉터리로 이동합니다.

    cd YOUR-REPOSITORY
    
  4. 아래의 명령에서 PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA(파일 이름이 아닌) 제거할 파일의 경로로 바꾸어서 실행합니다. 이 인수를 사용하면 다음과 같은 작업이 수행됩니다.

    • Git이 모든 분기와 태그의 전체 기록을 강제로 처리합니다(체크아웃하지 않음).

    • 지정된 파일과 그 결과로 생성된 빈 커밋을 제거합니다.

    • .git/config 파일에 저장된 일부 구성(예: 원격 URL)을 제거합니다. 이 파일은 나중에 복원할 수 있도록 미리 백업해두는 것이 좋습니다.

    • 기존 태그 덮어쓰기

        $ git filter-repo --invert-paths --path PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA
        Parsed 197 commits
        New history written in 0.11 seconds; now repacking/cleaning...
        Repacking your repo and cleaning out old unneeded objects
        Enumerating objects: 210, done.
        Counting objects: 100% (210/210), done.
        Delta compression using up to 12 threads
        Compressing objects: 100% (127/127), done.
        Writing objects: 100% (210/210), done.
        Building bitmaps: 100% (48/48), done.
        Total 210 (delta 98), reused 144 (delta 75), pack-reused 0
        Completely finished after 0.64 seconds.
      

      Important

      중요한 데이터를 포함하는 파일이 이동되었거나 이름이 바뀌어서 다른 경로에 있다면 변경된 경로에 대해서도 이 명령을 실행해야 합니다.

  5. 중요한 데이터를 포함하는 파일을 실수로 다시 커밋하지 않도록 .gitignore에 추가합니다.

    $ echo "YOUR-FILE-WITH-SENSITIVE-DATA" >> .gitignore
    $ git add .gitignore
    $ git commit -m "Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore"
    > [main 051452f] Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore
    >  1 files changed, 1 insertions(+), 0 deletions(-)
    
  6. 리포지토리의 기록에서 제거하려는 모든 항목을 제거했고 모든 분기가 체크아웃되었는지 재차 확인합니다.

  7. git filter-repo 도구는 구성된 원격을 자동으로 제거합니다. git remote set-url 명령을 사용하여 원격을 복원합니다. 여기서 OWNERREPO를 리포지토리 세부 정보로 바꿉니다. 자세한 내용은 "원격 리포지토리 관리"을(를) 참조하세요.

    git remote add origin https://github.com/OWNER/REPOSITORY.git
    
  8. 리포지토리의 상태에 만족하고 적절한 원격을 설정했다면 로컬 변경 내용을 강제로 푸시하여 푸시한 모든 분기 및 GitHub.com에 리포지토리를 덮어쓰세요. 커밋 기록에서 중요한 데이터를 제거하려면 강제 푸시가 필요합니다.

    $ git push origin --force --all
    > Counting objects: 1074, done.
    > Delta compression using 2 threads.
    > Compressing objects: 100% (677/677), done.
    > Writing objects: 100% (1058/1058), 148.85 KiB, done.
    > Total 1058 (delta 590), reused 602 (delta 378)
    > To https://github.com/YOUR-USERNAME/YOUR-REPOSITORY.git
    >  + 48dc599...051452f main -> main (forced update)
    
  9. 태그된 릴리스에서 중요한 파일을 제거하려면 Git 태그에 대해서도 강제로 푸시해야 합니다.

    $ git push origin --force --tags
    > Counting objects: 321, done.
    > Delta compression using up to 8 threads.
    > Compressing objects: 100% (166/166), done.
    > Writing objects: 100% (321/321), 331.74 KiB | 0 bytes/s, done.
    > Total 321 (delta 124), reused 269 (delta 108)
    > To https://github.com/YOUR-USERNAME/YOUR-REPOSITORY.git
    >  + 48dc599...051452f main -> main (forced update)
    

GitHub에서 데이터 완전히 제거

BFG 도구를 사용하거나 git filter-repo를 사용하여 중요한 데이터를 제거하고 변경 내용을 GitHub Enterprise Cloud에 푸시한 후에는 GitHub Enterprise Cloud에서 데이터를 완전히 제거하려면 몇 가지 단계를 더 수행해야 합니다.

  1. GitHub 지원 포털 사용에 문의하여 GitHub Enterprise Cloud에 대한 끌어오기 요청에서 캐시된 뷰 및 중요한 데이터에 대한 참조를 제거하도록 요청합니다. 리포지토리의 이름 및/또는 제거해야 하는 커밋에 대한 링크를 제공하세요.

    Important

    GitHub 지원은(는) 중요하지 않은 데이터를 제거하지 않으며 영향을 받는 자격 증명을 순환하여 위험을 완화할 수 없다고 판단되는 경우에 중요한 데이터를 제거하는 데 도움이 됩니다.

  2. 협력자에게 이전(오염된) 리포지토리 기록에서 만든 분기를 병합하지 ‘않고’ 다시 지정하도록 지시합니다.__ 하나의 병합 커밋은 방금 제거했던 오염된 기록의 일부 또는 전부를 다시 도입할 수 있습니다.

  3. 시간이 지났고 BFG 도구 / git filter-repo에 의도하지 않은 부작용이 없다고 확신하면 로컬 리포지토리의 모든 개체를 역참조하고 다음 명령(Git 1.8.5 이상 사용)을 사용하여 가비지 수집하도록 강제할 수 있습니다.

    $ git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
    $ git reflog expire --expire=now --all
    $ git gc --prune=now
    > Counting objects: 2437, done.
    > Delta compression using up to 4 threads.
    > Compressing objects: 100% (1378/1378), done.
    > Writing objects: 100% (2437/2437), done.
    > Total 2437 (delta 1461), reused 1802 (delta 1048)
    

    Note

    필터링된 기록을 새 리포지토리 또는 빈 리포지토리로 푸시한 다음 GitHub Enterprise Cloud에서 새로 복제하여 이를 수행할 수도 있습니다.

향후 실수로 인한 커밋 방지

기여자가 실수로 커밋하지 못하게 하면 중요한 정보가 노출되지 않도록 방지할 수 있습니다. 자세한 내용은 "조직에서 데이터 유출을 방지하기 위한 모범 사례"을(를) 참조하세요.

커밋하지 않으려는 항목을 커밋하지 않도록 하는 몇 가지 간단한 트릭이 있습니다.

  • GitHub Desktop 또는 gitk와 같은 시각적 프로그램을 사용하여 변경 내용을 커밋합니다. 시각적 프로그램을 사용하면 일반적으로 각 커밋을 통해 추가, 삭제 및 수정할 파일을 정확하고 쉽게 확인할 수 있습니다.
  • 대신 catch-all 명령 git add .와 명령줄의 git commit -a을 사용하지 말고 git add filenamegit rm filename을 사용하여 파일을 개별적으로 스테이징하세요.
  • 각 파일 내에서 변경 내용을 개별적으로 검토하고 스테이징하는 데 git add --interactive를 사용합니다.
  • 커밋을 위해 스테이징한 변경 내용을 검토하는 데 git diff --cached를 사용합니다. -a 플래그를 사용하지 않는 한 git commit에서 생성되는 정확한 차이입니다.
  • 리포지토리에 대한 푸시 보호를 사용하도록 설정하여 하드 코딩된 비밀이 포함된 푸시가 코드베이스에 커밋되지 않도록 탐지하고 방지합니다. 자세한 내용은 "리포지토리 및 조직에 대한 푸시 보호"을(를) 참조하세요.

추가 참고 자료