Skip to main content

Удаление конфиденциальных данных из репозитория

При фиксации конфиденциальных данных, таких как пароль или ключ SSH, в репозиторий Git, его можно удалить из журнала.

Удаление конфиденциальных данных из репозитория

При изменении журнала репозитория с помощью таких средств, как git filter-repo или BFG Repo-Cleaner, важно понимать последствия, особенно в отношении открытых запросов на вытягивание и конфиденциальных данных.

Средство git filter-repo и BFG Repo-Cleaner перезаписывают журнал репозитория, что меняет агенты работоспособности системы для существующих фиксаций, которые вы изменяете, и всех зависимых фиксаций. Измененные агенты работоспособности системы фиксации могут затронуть открытые запросы на вытягивание в репозитории. Перед удалением файлов из репозитория рекомендуется объединить или закрыть все открытые запросы на вытягивание.

Файл можно удалить из последней фиксации с помощью git rm. Сведения об удалении файла, добавленного с последней фиксацией, см. в разделе "Сведения о больших файлах на GitHub".

Сведения о воздействии конфиденциальных данных

В этой статье описывается, как сделать фиксации конфиденциальными данными недоступными из любых ветвей или тегов в репозитории на ваш экземпляр GitHub Enterprise Server. Однако эти фиксации по-прежнему могут быть доступны в другом месте:

  • В любых клонах или вилках репозитория
  • Непосредственно через хэши SHA-1 в кэшированных представлениях на GitHub Enterprise Server
  • Через все запросы на вытягивание, ссылающиеся на них.

Вы не можете удалить конфиденциальные данные из клонов других пользователей репозитория, но вы можете окончательно удалить кэшированные представления и ссылки на конфиденциальные данные в запросах на вытягивание GitHub Enterprise Server путем обращения к ваш администратор сайта.

После отправки фиксации в GitHub Enterprise Server любые конфиденциальные данные в фиксации следует рассматривать как скомпрометированные. Если вы зафиксировали пароль, его следует изменить. Если вы зафиксировали ключ, создайте новый ключ.

Если фиксация, введенная конфиденциальными данными, существует в любых вилках, она будет по-прежнему доступна там. Вам потребуется координировать работу с владельцами вилок, запрашивая их удалить конфиденциальные данные или полностью удалить вилку.

Рассмотрим эти ограничения и проблемы в решении переписать журнал репозитория.

Очистка файла из журнала репозитория

Вы можете очистить файл из журнала репозитория с помощью средства 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 Server. В этом случае выполняется перезапись журнала репозитория, в результате которой конфиденциальные данные удаляются из журнала фиксации. При принудительной отправке могут быть перезаписаны фиксации, над которыми работают другие пользователи.

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
    

    Дополнительные сведения см. в файле INSTALL.md в репозитории newren/git-filter-repo.

  2. Если у вас еще нет локальной копии репозитория с конфиденциальными данными в журнале, клонируйте репозиторий на локальный компьютер.

    $ git clone https://HOSTNAME/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 обработать, но не извлечь весь журнал каждой ветви и тега;

    • удалить указанный файл, а также все пустые фиксации, сформированные в результате;

    • удалить некоторые конфигурации, например удаленный URL-адрес, хранящийся в файле .git/config. Возможно, потребуется заранее выполнить резервное копирование этого файла для последующего восстановления.

    • Перезапись существующих тегов

        $ 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 Используйте команду для восстановления удаленных данных, замены OWNER и REPO сведений о репозитории. Дополнительные сведения см. в разделе Управление удаленными репозиториями.

    git remote add origin https://github.com/OWNER/REPOSITORY.git
    
  8. После того как вы удовлетворены состоянием репозитория, и вы настроили соответствующие удаленные, принудительно отправьте локальные изменения, чтобы перезаписать репозиторий на ваш экземпляр GitHub Enterprise Server, а также все ветви, которые вы отозваны. Для удаления конфиденциальных данных из журнала фиксаций требуется принудительная отправка.

    $ 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://HOSTNAME/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://HOSTNAME/YOUR-USERNAME/YOUR-REPOSITORY.git
    >  + 48dc599...051452f main -> main (forced update)
    

Полное удаление данных с сайта GitHub

После удаления конфиденциальных данных с помощью средства BFG или git filter-repo и отправки изменений в GitHub Enterprise Server необходимо выполнить ряд действий, чтобы полностью удалить данные из GitHub Enterprise Server.

  1. Обратитесь к ваш администратор сайта, а затем попросите удалить кэшированные представления и ссылки на конфиденциальные данные в запросах на вытягивание GitHub Enterprise Server. Укажите имя репозитория и (или) ссылку на фиксацию, необходимую вам. Дополнительные сведения о том, как администраторы сайта могут удалять недоступные объекты Git, см. в разделе "Служебные программы командной строки".

  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 Server.

Предотвращение случайных фиксаций в будущем

Запрет участников делать случайные фиксации может помочь предотвратить предоставление конфиденциальной информации. Дополнительные сведения см. в разделе "Рекомендации по предотвращению утечки данных в организации".

Существует несколько простых приемов, позволяющих избежать фиксации данных, которые не хотите фиксировать:

  • Используйте для фиксации изменений визуальную программу, такую как GitHub Desktop или gitk. Как правило, визуальные программы упрощают просмотр файлов, которые будут добавляться, удаляться и изменяться при каждой фиксации.
  • Избегайте использования в командной строе команд catch-all git add . и git commit -a — используйте git add filename и git rm filename, чтобы подготовить каждый файл по отдельности.
  • Используйте git add --interactive для проверки и подготовки каждого отдельного изменения в каждом файле.
  • Используйте git diff --cached для проверки изменений, подготовленных для фиксации. Это точное несовпадение, которое git commit будет производить до тех пор, пока вы не используете флаг -a.
  • Включите защиту push-уведомлений для репозитория, чтобы обнаруживать и предотвращать отправки, содержащие жестко закодированные секреты, не фиксируются в базе кода. Дополнительные сведения см. в разделе Отправка защиты для репозиториев и организаций.

Дополнительные материалы