Удаление конфиденциальных данных из репозитория
При изменении журнала репозитория с помощью таких средств, как 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
и убедиться, что он не был случайно зафиксирован повторно.
-
Установите последнюю версию средства git filter-repo. Можно установить
git-filter-repo
вручную или с помощью диспетчера пакетов. Например, чтобы установить средство с помощью HomeBrew, используйте командуbrew install
.brew install git-filter-repo
Дополнительные сведения см. в файле INSTALL.md в репозитории
newren/git-filter-repo
. -
Если у вас еще нет локальной копии репозитория с конфиденциальными данными в журнале, клонируйте репозиторий на локальный компьютер.
$ 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.
-
Перейдите в рабочую папку репозитория.
cd YOUR-REPOSITORY
-
Выполните следующую команду, заменив
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
Если файл с конфиденциальными данными существовал в других путях (в результате перемещения или переименования), необходимо также выполнить данную команду для этих путей.
-
-
Добавьте файл с конфиденциальными данными в
.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(-)
-
Внимательно проверьте, удалили ли вы все, что требуется, из журнала репозитория и все ли ветви извлечены.
-
Средство
git filter-repo
автоматически удаляет настроенные удаленные приложения.git remote set-url
Используйте команду для восстановления удаленных данных, заменыOWNER
иREPO
сведений о репозитории. Дополнительные сведения см. в разделе Управление удаленными репозиториями.git remote add origin https://github.com/OWNER/REPOSITORY.git
-
После того как вы удовлетворены состоянием репозитория, и вы настроили соответствующие удаленные, принудительно отправьте локальные изменения, чтобы перезаписать репозиторий на ваш экземпляр 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)
-
Чтобы удалить конфиденциальный файл из выпусков с тегами, потребуется также выполнить принудительную отправку в теги 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.
-
Обратитесь к ваш администратор сайта, а затем попросите удалить кэшированные представления и ссылки на конфиденциальные данные в запросах на вытягивание GitHub Enterprise Server. Укажите имя репозитория и (или) ссылку на фиксацию, необходимую вам. Дополнительные сведения о том, как администраторы сайта могут удалять недоступные объекты Git, см. в разделе "Служебные программы командной строки". Дополнительные сведения о том, как администраторы сайта могут определять доступные фиксации, см. в разделе "Определение доступных фиксаций".
-
Сообщите участникам совместной работы о необходимости переместить изменения из одной ветви в другую и не объединять, какие-либо ветви, созданные из старого (испорченного) журнала репозитория. Одна фиксация слияния может снова вернуть некоторые или все испорченные журналы, которые вам только что пришлось очистить.
-
Если вы использовали
git filter-repo
, этот шаг можно пропустить.Если вы использовали средство BFG после перезаписи, вы можете очистить ссылки в локальном репозитории в старом журнале, чтобы быть разыменовываемой и сборкой мусора со следующими командами (с помощью Git 1.8.5 или более поздней версии):
$ 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.
Определение доступных фиксаций
Чтобы полностью удалить нежелательные или конфиденциальные данные из репозитория, фиксация, которая впервые представила данные, должна быть полностью разорвана в ветвях, тегах, запросах на вытягивание и вилках. Одна ссылка в любом месте не позволит сбору мусора полностью очистить данные.
Можно проверить наличие существующих ссылок с помощью следующих команд при подключении к устройству через SSH. Вам потребуется SHA фиксации, которая первоначально представила конфиденциальные данные.
ghe-repo OWNER/REPOSITORY -c 'git ref-contains COMMIT_SHA_NUMBER'
ghe-repo OWNER/REPOSITORY -c 'cd ../network.git && git ref-contains COMMIT_SHA_NUMBER'
Если любая из этих команд возвращает любые результаты, необходимо удалить эти ссылки, прежде чем фиксация может быть успешно собрана мусор. Вторая команда определит ссылки, которые существуют в вилках репозитория (если репозиторий не имеет вилок, вы можете пропустить его).
- Результаты, начинающиеся с
refs/heads/
refs/tags/
ветвей и тегов соответственно, которые по-прежнему содержат ссылки на обиженную фиксацию, предполагая, что измененный репозиторий не был полностью очищен от фиксации или что он не был принудительно отправлен. - Результаты, начинающиеся с
refs/pull/
refs/__gh__/pull
запроса на вытягивание, ссылающиеся на обиженную фиксацию. Эти запросы на вытягивание необходимо удалить, чтобы разрешить сбор мусора фиксации. Запрос на вытягивание можно удалить на панели мониторингаhttps://HOSTNAME/stafftools/repositories/OWNER/REPOSITORY/PULL_REQUESTS/<PULL-REQUEST-NUMBER>
администратора сайта, заменив<PULL-REQUEST-NUMBER>
номером запроса на вытягивание.
Если ссылки найдены в каких-либо вилках, результаты будут выглядеть примерно так же, но начнется с refs/remotes/NWO/
. Чтобы определить вилку по имени, можно выполнить следующую команду.
ghe-nwo NWO
Та же процедура с помощью средства BFG или git filter-repo
может использоваться для удаления конфиденциальных данных из вилок репозитория. Кроме того, вилки можно удалить полностью, и при необходимости репозиторий можно повторно вилировать после завершения очистки корневого репозитория.
После удаления ссылок фиксации повторно запустите команды для двойной проверки.
Если из любой ref-contains
из команд нет результатов, можно запустить сборку мусора с флагом --prune
, чтобы удалить фиксации без ссылки, выполнив следующую команду.
ghe-repo-gc -v --prune OWNER/REPOSITORY
После успешного удаления фиксации сборки мусора перейдите на панель мониторинга https://HOSTNAME/stafftools/repositories/OWNER/REPOSITORY
администратора сайта репозитория, выберите "Сеть", а затем нажмите кнопку "Недопустимый кэш Git", чтобы удалить все кэшированные данные.
Предотвращение случайных фиксаций в будущем
Запрет участников делать случайные фиксации может помочь предотвратить предоставление конфиденциальной информации. Дополнительные сведения см. в разделе "Рекомендации по предотвращению утечки данных в организации".
Существует несколько простых приемов, позволяющих избежать фиксации данных, которые не хотите фиксировать:
- Используйте для фиксации изменений визуальную программу, такую как 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-уведомлений для репозитория, чтобы обнаруживать и предотвращать отправки, содержащие жестко закодированные секреты, не фиксируются в базе кода. Дополнительные сведения см. в разделе Сведения о защите push-уведомлений.