Comments 64
Если с репозиторием работают другие люди, переписывать историю может быть плохой идеей. Тогда можно просто поменять пароли/ключи, которые были упомянуты в файле, и добавить сам файл в .gitignore
А из истории пушей кто удалять будет?
Я работаю на VS Code, и я, to be honest, так и не понял, с какой стати
.gitignore
"не игнорирует".env.
Причем спокойно "игнорирует" другие файлы, директории.
А разгадка проста: это не .gitignore игнорирует "другие файлы, директории" сразу "из коробки", а VS Code. В IDE от JetBrains то же самое.
А .gitignore - просто текстовый файл. Он плюс .git/info/exclude плюс глобальный .gitignore - вот как определяется, будет проигнорирован файл/каталог или нет, если работать не через IDE.
(Надеюсь, ничего не пропустил?)
из статьи понятно что вы не русский, но неужели нельзя было проверить текст с помощью русского человека или каким-нибудь сервисом?
господи, как вас еще земля таких носит
Что конкретно вас смутило?
из статьи понятно что вы не русский
А вы?
Из вашего комментария тоже понятно, что вы не лингвист. Хотите помочь автору исправить ошибки - есть соответствующая кнопка. Не хотите - не позорьтесь.
как вы это поняли и в чём позор?
В раздельном написании прилагательного https://ru.wiktionary.org/wiki/нерусский в отсутствие противопоставления.
Преисполниться можно здесь.
фу таким быть
Человек выучил твой язык, а ты ведёшь себя как *, вместо того, чтобы похвалить
Смотря какой гит имеется ввиду: в самом гите он не остаётся навсегда, а до первого вызова сборщика мусора, который удалит коммиты, которые не имеют референсов - если говорить про "обычный" гит. Онлайн сервисы работают по-своему, например Github сборщик мусора не вызывает. Но тем не менее, чекаут с таким коммитом сделать будет невозможно.
Интересное решение. Я знаком ещё с одним: BFG repo cleaner.
Фиг с ним с gitignore. Зачем вы вообще изначально добавили .env в staging area перед коммитом? Или вы делали git commit -a? Это плохая привычка, надо избавляться. Или вы ничего не знаете про staging area и всё отдаёте на откуп IDE?
Вообще, конечно, правильный ответ это не переписывать историю (дичь!), а ротировать утёкшие ключи. Как их не чисти, а ключи уже фактически утёкшие.
Понятно, что ошибку проще не совершать, чем исправить. Но это не значит, что инструкция по исправлению ошибки не нужна.
Про мне автор дал не инструкцию по исправлению ошибки, а инструкцию по маскировке ошибки. Единственный способ что-то сделать это посыпав голову пеплом сообщить ответственному человеку, и уже он перегенерит все скопированные секреты.
Подход "Старший придёт он разберётся", конечно имеет право на жизнь, но иногда надо брать ответственность и на себя.
А если я в собственном проекте слил .env файл в гит, то кому "ответственному" мне сообщать?
Знаете, я четверть века назад проходил производственную практику на заводе, токарем. Там висели ещё советские плакаты с текстом: "Рабочий, не скрывай брак, покажи мастеру".
В вашем случае вам нужно перегенерить секреты. Потом можете, и описанное в статье сделать.
При чем тут сокрытие брака? И что делать если вы сам мастер? Разве нельзя самостоятельно исправить собственную ошибку и сказать команде - ребята, я там ошибся, поэтому все переделал, так-то и так хакнул репозиторий и перегенерил все ключи и пароли, например?
если вы сделали git push, НИКАКИЕ манипуляции на вашей стороне, в том числе push —force не помогут очистить историю на стороне удаленной
зная номер коммита этот файл всё равно можно достать
потому правильную аналогию привели — это попытка сокрытия брака
Это не исправление, вот в чём штука. Исправление – считать ключ утекшим (даже если сделать описанное в статье и сразу умудриться прогнать git gc на сервере – нет никаких гарантий, что кто-то не успел сделать pull) и перегенерить.
Если прав на перегенерацию нет – ну, можно использовать, как временное решение, пока это не сделает тот, кто отвечает за ключи (но в этотвремя находитесь под угрозой).
Ну и вообще git push --force – такое себе, создаёт на ровном месте геморрой тем, кто успел сделать git push, так что если есть возможность – лучше обойтись без этой игры в прятки.
Всё же ваш план работы включает перегенерацию ключей. Если включает, то ок. Хотя непонятно, зачем ритуальное действие с удалением .env файла
из репозитория.
В контексте нашей с вами беседы, у меня впечатление, что изначально перегенерация не предполагалась, то то что вы не пишете про взятие ответственности это декларация, вроде наклеивания шильдиков о том, что производство местное. Так делать не надо.
если репо публичное - да.
а если нет - ИМХО, вполне нормально просто удалить.
Есть варианты.
Пока пишем такую статью мы не должны:
1. считать что гит репозиторий живёт где-то на кошернохаляльном гихтабе или у на аналогичном сервисе. Наример вполне возможен вариант, что читатель воспользовался воспользовался статьёй 15 летней свежести с хабра же, (статья называлась "From Git to Deploy", почему то не гуглится, но есть сотни подобных) и хостит какой то гит у себя, возможно просто пушит в папочку доступную по ssh
. Возможно репозиторий ещё с тех времён живёт.
2. Или кто-то из коллег читателя делает бэкап репозитория, bare репозитория, просто на всякий случай. Возможно даже читатель сам 100 лет назад такое организовал, и забыл об этом.
3. возможно сервис корпоративный, который сопровождает корпоративный же девопс, возможно это "девопс после курсов" который знает как квалификационные тесты на этих курсах пройти, умеет проходить собеседования, и даже знает чем отличается симлинк от хардлинка. Но реальную задачу с которой не сталкивался на практике не сделает, условно, вроде такого, что сервис через systemd
не сможет запустить, даже если ему пример дать и совместно с ним пару раз этот пример разобрать. И репозиторий декларированный как скрытый на деле -- доступен любому достаточно сильно того желающему.
4. или окажется что сервис которым пользуетесь -- на деле решето.
5. моя личная паранойя в том, что мы на слово верим тому же MS, что их админы не мониторят репозитории на предмет ключей доступа и ещё каких нибудь вкусностей.
На мой взгляд, основной вопрос, это "что будет, если данные утекут". Если хакер упрёт рецепты с сайта до даты их запланированной публикации, наверное не страшно. Если данные там более ценные, я бы не рисковал. На деле, время неспокойное, и условный хакер может развлечься и разместить на сайте с рецептами материал, по поводу которого в одном регионе будут вопросы у властей, или в другом у "прогрессивной общественности". В любом случае, редактирование истории -- сомнительная практика, а в случае компрометации ключей -- это заметание мусора под ковёр.
Или вы делали git commit -a? Это плохая привычка, надо избавляться.
Чем? Проще все добавить и убрать что-то не нужное, посмотрев все файлы, чем каждый файл кликать, чтобы добавить в коммит, потому что добавляется как правило 90-95% файлов, так что работы в 10 раз меньше, чем идти от обратного.
добавляется как правило 90-95% файлов
От инструмента зависит. Если CMake + in source build, то она много файлов генерирует.
Без разницы, добавляете вы в индекс файлы по одному или убираете, всё равно вы просматриваете их (а вот git commit -a наводит на мысль, что коммиты слишком жирные, раз их не просматривают)
Я работаю на VS Code, и я, to be honest, так и не понял, с какой стати
.gitignore
"не игнорирует".env.
Причем спокойно "игнорирует" другие файлы, директории.
Всё отлично игнорируется:
пруф
![](https://habrastorage.org/getpro/habr/upload_files/b62/5da/3e1/b625da3e1d0aeecb1b920ede395826cf.png)
![](https://habrastorage.org/getpro/habr/upload_files/7ed/3a9/84f/7ed3a984fcd43a4d10082fce3523eec8.png)
![](https://habrastorage.org/getpro/habr/upload_files/649/2d4/a01/6492d4a01cb016158015f738d5f4048e.png)
Вы или закомитили .env до того как в .gitignore его добавили, еили правило кривое.
git push --force
Вот так лихо историю переписывать черевато многими проблемами, особенно при командной разработке. Вот сейчас насоветуете, не понимая чего, кто-то сделает, не понимая, а потом разгребай ...
Ну и к тому же в гитхабе, вроде это остается в истории ПР-ов, и т.д. Лучше просто поменять чувствительные данные.
От такого рекомендую добавить .env в глобальный гитигнор, и что самое главное и универсальное: проверять что коммитишь, добавляя в стейдж по файлику или по папке, хотябы оценив состав, если не содержание, а не "git commit -A" 😀
Нормальный способ, хотя я бы сделал --soft reset и потом залил уже без .env, не потому что так лучше, просто мне так быстрее. Ну и я не заливаю каждый коммит на сервер, долго работаю локально, но если предположить что всё таки залил, то опять же с фичей работают в отдельном бранче и сделать для него force push вполне приемлемо.
Те кто всё время повторяют что "ни в коем случае", посмотрите доку того же гитлаб по поводу разрешения конфликтов перед слиянием.
Ну а уж если из фичи попало в develop или того хуже залилась в master ... это форс мажор и что уж делать, а тому кто апрувил мердж реквест голову оторвать.
Это не работает. Гитхаб хранит коммит даже после изменения истории. Да, хеш этого коммита нужно знать, чтобы открыть его по ссылке. Но он там остается и я не нашел способа его убить
После чистки истории нужно запросить сброс кешей через саппорт: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository .
Но вообще, если секреты оказались в паблике, то лучше считать их скомпрометироваными и запускать план действий в таких ситуациях.
Если у вас бранч не один, то можно использовать утилиту Git BFG для автоматизации вычищения «лишней» информации из истории и файлов. Я пару раз пользовался для единоличных репозиториев.
Да, и присоединюсь к остальным комментаторам - обязательно напишите, что значит перезапись истории в командной разработке, что данная простая команда оторвёт историю у всех кто в данный момент ваш гит использует и подобные вещи должны быть согласованы.
Git filter branch считается устаревшим(не развивается) и не рекомендуется к использованию. Рекомендуеися использовать git filter repo.
Наличие файла с секретами на локальном диске - уже уязвимость, даже без передачи его в гит. Лучше менеджер секретов завести типа Hashicorp Vault.
При локальном запуске приложения вам все равно нужно из волта достать секреты. Это ничем не отличается от .env файла.
Но это не должно быть проблемой, т.к. разрабатывать вы должны приложение в тестовом окружении.
Это ничем не отличается от .env файла только в том случае, если секреты, добытые из волта, намеренно в файл складывать. А зачем это делать, если можно хранить их в ОЗУ, пока приложение выполняется?
Сам факт передачи секрета разработчику это компрометация. Доступ к секретам должен имееть ограниченный круг лиц. А как он там его хранит не важно.
В том-то и прикол, что, при грамотном использовании менеджера секретов, разработчик вообще секретов не видит :)
Ну как минимум секрет от менеджера секретов должен быть. А это ещё хуже, т.к. учетке может быть дан доступ к большему числу секретов, чем нужно разработчику.
Секрет от менеджера секретов можно через интеграцию с SSO доставать, и его тоже никто не увидит. А если учётке дают больше прав, чем надо, то это не проблема менеджера секретов. И если так, спустя рукава, подходить к информационной безопасности в организации, то менеджер секретов и правда не нужен. Храните в .env файле и не парьте мозг.
Как вариант, подгружать энв файлик из юзер директории, а не только папки гита. Тогда точно нет опасности его случайно закомитить.
А что, не храня свои секреты в чужом приложении с мутной лицензией, хорошо разрабатывать уже нельзя?
Смотря что вкладывать в смысл слова "хорошо". Авторитетные господа из OWASP, например, считают упомянутую софтину "с мутной лицензией" вполне хорошим решением с точки зрения ИБ. В отличие от хранения секретов в файле. И вообще, если у вас сервис, в котором нечего защищать, то можете его хорошо разрабатывать, храня секреты хоть в git, хоть на стикере на мониторе
Плохой способ. Если .env содержит секретные данные и попал с ними в репозиторий - он уже скомпрометирован. Боты злоумышленников регулярно шерстят гитхаб в поисках подобных подарков. Единственный возможный путь действий здесь - аккуратно заменить все скомпрометированные ключи, так, что бы наличие где-то в истории старого .env уже не было важным. А в таком случае, зачем портить историю?
Вообще, если что-то попало в git (а уж тем более в публичный github), то удалить это уже невозможно. Все эти переписывания истории, вызовы git-ового garbage collector'а для удаления осиротевших коммитов не помогут. Потому что кто-то уже успел склонировать репу к себе. Можно добавить в эту фразу "возможно", но лучше этого не делать, а просто сменить пароли, токены и другую секретную информацию в .env
В большинстве случаев суетиться с удалением чего-то из истории уже поздно, если она попала на сервер git, ибо протекшие логины/пароли оттуда уже кто-то мог скопировать.
Так что наиболее безопасное решение - сменить пароли. И (о ужас) был случай, когда кто-то в самом GitHub закомиттил что-то не то, из-за чего всех пользователей заставили менять сохранённые у себя публичные ключи.
Мне просто интересно, а что мешает в самом GitHub хранить все что нужно, и разворачивать экшеном при деплое на сервер?
Добавлю сюда ещё один нюанс - если вы удалили файл через git rm - - cached — Вы, конечно, оставили его локально. Но если другие ваши коллеги или сервера уже получили состояние с закомиченным файлом - после git pull этот файл удалится у них физически.
Вся статья могла состоять из той самой команды гита и ничего бы при этом не потерять. Зачем в ней столько информационного шума? Или это чатгпт?
Почему лайки, если на Хабре плюсы?
Зачем одна команда Гита (по первой ссылку из поисковика!) была превращена в статью на 7 экранов?
Зачем такие большие отступы вокруг скриншотов?
Почему `create-next-app` не создаёт .gitignore с .env?
Когда секреты утекли в GitHub то считайте что они уже скомпрометированы. Есть боты, которые мгновенно скачивают всё, поэтому тут в любом случае нужно менять пароли.
А раз вы аннулировали утекшие секреты, то ничего страшного в том, что они остались где-то в истории. Если же вы всё таки решили пересобрать новую историю, то не используйте filter-branch
Пакет filter-branch сейчас заявлен устаревшим и не рекомендуется к использованию, так как может повредить репозитории, созданные актуальной версией гита.
Пользуйтесь filter-repo – он быстрее и безопаснее.
Если вы быстро заметили проблему, то проще обойтись упомянутым выше reset --soft либо commit --amend чтобы поправить только последний коммит, а не пересобирать весь проект заново.
Вечный покой .env: как эффективнее удалять закомиченный файл .env из Git-репозитория