Zachowuję ważne ustawienia, takie jak nazwy hostów i porty serwerów programistycznych i produkcyjnych w moim systemie kontroli wersji. Ale wiem, że trzymanie tajemnic (takich jak klucze prywatne i hasła do baz danych) w repozytorium VCS jest złą praktyką .
Jednak hasła - jak każde inne ustawienie - wydają się być wersjonowane. Więc co to jest właściwy sposób kontrolowania wersji haseł?
Wyobrażam sobie, że wymagałoby to trzymania sekretów w ich własnym pliku „ustawień sekretów” oraz szyfrowania tego pliku i kontrolowania wersji. Ale jakie technologie? A jak to zrobić poprawnie? Czy jest na to lepszy sposób?
Generalnie zadaję pytanie, ale w moim konkretnym przypadku chciałbym przechowywać tajne klucze i hasła do witryny Django / Python za pomocą git i github .
Również, idealnym rozwiązaniem byłoby zrobić coś magicznego kiedy wciskam / pull z git - na przykład, jeśli zaszyfrowany plik haseł zmienia skrypt jest uruchamiany, które pyta o hasło i deszyfruje go na miejsce.
EDIT: Dla jasności, ja jestem z prośbą o miejsce przechowywania produkcji tajemnice.
źródło
Odpowiedzi:
Masz rację, chcąc zaszyfrować swój poufny plik ustawień, zachowując jednocześnie kontrolę wersji. Jak wspomniałeś, najlepszym rozwiązaniem byłoby takie, w którym Git w sposób przejrzysty zaszyfruje niektóre poufne pliki po ich wysłaniu, aby lokalnie (tj. Na dowolnym komputerze, który ma Twój certyfikat), możesz użyć pliku ustawień, ale Git lub Dropbox lub ktokolwiek jest przechowywanie plików w VC nie daje możliwości odczytania informacji w postaci zwykłego tekstu.
Samouczek dotyczący przezroczystego szyfrowania / deszyfrowania podczas wypychania / ściągania
W tym streszczeniu https://gist.github.com/873637 pokazano samouczek dotyczący korzystania z sterownika smudge / clean filter Git z openssl do przezroczystego szyfrowania przesłanych plików. Musisz tylko przeprowadzić wstępną konfigurację.
Podsumowanie tego, jak to działa
Zasadniczo będziesz tworzyć
.gitencrypt
folder zawierający 3 skrypty bash,które są używane przez Git do deszyfrowania, szyfrowania i obsługi różnic Git. Główne hasło i sól (naprawione!) Są zdefiniowane w tych skryptach i MUSISZ upewnić się, że plik .gitencrypt nigdy nie zostanie przesłany. Przykładowy
clean_filter_openssl
skrypt:Podobnie dla
smudge_filter_open_ssl
idiff_filter_oepnssl
. Zobacz Gist.Twoje repozytorium z poufnymi informacjami powinno mieć plik .gitattribute (niezaszyfrowany i zawarty w repozytorium), który odwołuje się do katalogu .gitencrypt (który zawiera wszystko, czego Git potrzebuje do zaszyfrowania / odszyfrowania projektu w sposób przejrzysty) i który jest obecny na twoim lokalnym komputerze.
.gitattribute
zawartość:Na koniec musisz również dodać następującą zawartość do swojego
.git/config
plikuTeraz, gdy wypychasz repozytorium zawierające poufne informacje do zdalnego repozytorium, pliki zostaną zaszyfrowane w sposób przezroczysty. Podczas ściągania z komputera lokalnego, który ma katalog .gitencrypt (zawierający Twoje hasło), pliki zostaną odszyfrowane w sposób przezroczysty.
Uwagi
Powinienem zauważyć, że ten samouczek nie opisuje sposobu tylko zaszyfrowania poufnego pliku ustawień. Spowoduje to przezroczyste zaszyfrowanie całego repozytorium, które jest przesłane do zdalnego hosta VC i odszyfrowanie całego repozytorium, aby zostało całkowicie odszyfrowane lokalnie. Aby osiągnąć pożądane zachowanie, możesz umieścić poufne pliki dla jednego lub wielu projektów w jednym sensitive_settings_repo. Możesz zbadać, jak ta przezroczysta technika szyfrowania działa z podmodułami Git http://git-scm.com/book/en/Git-Tools-Submodules, jeśli naprawdę potrzebujesz, aby poufne pliki znajdowały się w tym samym repozytorium.
Użycie stałego hasła mogłoby teoretycznie prowadzić do luk w zabezpieczeniach siłowych, gdyby atakujący mieli dostęp do wielu zaszyfrowanych repozytoriów / plików. IMO, prawdopodobieństwo tego jest bardzo niskie. Jak wspomniano na dole tego samouczka, nieużywanie stałego hasła spowoduje, że lokalne wersje repozytorium na różnych maszynach będą zawsze pokazywać, że zmiany zaszły ze statusem „git”.
źródło
Heroku popycha użycie zmiennych środowiskowych dla ustawień i tajnych kluczy:
Dzięki
.env
Foremanowi i plikom Heroku zapewnia godny pozazdroszczenia zestaw narzędzi do eksportu, importu i synchronizacji zmiennych środowiskowych.Osobiście uważam, że zapisywanie tajnych kluczy obok kodu jest niewłaściwe. Jest to zasadniczo niezgodne z kontrolą źródła, ponieważ klucze są przeznaczone dla usług zewnętrznych w kodzie . Jedynym dobrodziejstwem byłoby to, że programista może sklonować HEAD i uruchomić aplikację bez żadnej konfiguracji. Załóżmy jednak, że programista sprawdza historyczną wersję kodu. Ich kopia będzie zawierała hasło do bazy danych z zeszłego roku, więc aplikacja nie będzie działać w przypadku dzisiejszej bazy danych.
Dzięki powyższej metodzie Heroku programista może pobrać zeszłoroczną aplikację, skonfigurować ją przy użyciu dzisiejszych kluczy i pomyślnie uruchomić ją w dzisiejszej bazie danych.
źródło
Moim zdaniem najczystszym sposobem jest użycie zmiennych środowiskowych. Na przykład nie będziesz musiał zajmować się plikami .dist , a stan projektu w środowisku produkcyjnym byłby taki sam, jak na komputerze lokalnym.
Polecam przeczytanie rozdziału poświęconego konfiguracji aplikacji Twelve-Factor , pozostałe też, jeśli jesteś zainteresowany.
źródło
export MY_ENV_VAR=
, a podczas wdrażania po prostu wypełnij go odpowiednimi wartościami isource
gotowe. Jeśli przez trzymanie masz na myśli wersję ustawień, nie powinieneś tego robić w pierwszej kolejności.Opcją byłoby umieszczenie poświadczeń związanych z projektem w zaszyfrowanym kontenerze (TrueCrypt lub Keepass) i przesłanie go.
Zaktualizuj jako odpowiedź z mojego komentarza poniżej:
Przy okazji ciekawe pytanie. Właśnie znalazłem to: github.com/shadowhand/git-encrypt, który wygląda bardzo obiecująco w przypadku automatycznego szyfrowania
źródło
git-encrypt
brzmi jak dokładnie to, czego szukam. „Podczas pracy ze zdalnym repozytorium git, które jest hostowane na serwerze pamięci masowej innej firmy, poufność danych czasami staje się problemem. W tym artykule przedstawiono procedury konfigurowania repozytoriów git dla których lokalne katalogi robocze są normalne (niezaszyfrowane), ale zatwierdzona zawartość jest zaszyfrowana. " (Oczywiście chcę tylko zaszyfrować część moich treści ...)Sugeruję użycie do tego plików konfiguracyjnych i nie wersjonowanie ich.
Możesz jednak wersjonować przykłady plików.
Nie widzę problemu z udostępnianiem ustawień programistycznych. Z definicji nie powinien zawierać żadnych wartościowych danych.
źródło
Czarna skrzynka został niedawno wydany przez StackExchange i chociaż jeszcze go nie używałem, wydaje się, że dokładnie rozwiązuje problemy i obsługuje funkcje wymagane w tym pytaniu.
Z opisu na https://github.com/StackExchange/blackbox :
źródło
Odkąd zadałem to pytanie zdecydowałem się na rozwiązanie, z którego korzystam przy tworzeniu małej aplikacji z małym zespołem ludzi.
git-crypt
git-crypt używa GPG do przezroczystego szyfrowania plików, gdy ich nazwy pasują do określonych wzorców. Na przykład, jeśli dodasz do
.gitattributes
pliku ...... potem plik taki jak
config.secret.json
będzie zawsze przesyłany do zdalnego repozytorium z szyfrowaniem, ale pozostanie niezaszyfrowany w lokalnym systemie plików.Jeśli chcę dodać nowy klucz GPG (osobę) do twojego repozytorium, który może odszyfrować chronione pliki, uruchom
git-crypt add-gpg-user <gpg_user_key>
. Tworzy to nowe zatwierdzenie. Nowy użytkownik będzie mógł odszyfrować kolejne zatwierdzenia.źródło
Nie, po prostu nie rób tego, nawet jeśli jest to twoje prywatne repozytorium i nigdy nie zamierzasz go udostępniać, nie rób tego.
Powinieneś stworzyć plik local_settings.py, umieścić go na VCS ignore iw swoim settings.py zrobić coś takiego
Jeśli ustawienia twoich sekretów są tak wszechstronne, chętnie powiem, że robisz coś nie tak
źródło
EDYCJA: Zakładam, że chcesz śledzić poprzednie wersje haseł - powiedzmy, dla skryptu, który uniemożliwiłby ponowne użycie hasła itp.
Myślę, że GnuPG jest najlepszym rozwiązaniem - jest już używany w jednym projekcie związanym z git (git-Annex) do szyfrowania zawartości repozytorium przechowywanej w usługach w chmurze. GnuPG (gnu pgp) zapewnia bardzo silne szyfrowanie oparte na kluczach.
Teraz, jeśli twój plik „moje hasło” nie zmienił się, zaszyfrowanie da ten sam zaszyfrowany tekst i nie zostanie dodany do indeksu (brak redundancji). Najmniejsza modyfikacja mypassword skutkuje radykalnie innym zaszyfrowanym tekstem i mypassword.gpg w obszarze pomostowym bardzo różni się od tego w repozytorium, dlatego zostanie dodany do zatwierdzenia. Nawet jeśli napastnik zdobędzie twój klucz gpg, nadal musi złamać hasło. Jeśli atakujący uzyska dostęp do zdalnego repozytorium z zaszyfrowanym tekstem, może porównać kilka zaszyfrowanych tekstów, ale ich liczba nie będzie wystarczająca, aby dać mu jakąkolwiek istotną przewagę.
Później możesz użyć .gitattributes, aby zapewnić deszyfrowanie w locie w celu zakończenia git diff hasła.
Możesz także mieć oddzielne klucze dla różnych typów haseł itp.
źródło
Zwykle oddzielam hasło jako plik konfiguracyjny. i oddal je.
A kiedy uruchomię
main.py
, umieść prawdziwe hasło wdefault.cfg
skopiowanym.ps. kiedy pracujesz z git lub hg. możesz zignorować
*.cfg
pliki do utworzenia.gitignore
lub.hgignore
źródło
Zapewnij sposób na zastąpienie config
Jest to najlepszy sposób zarządzania zestawem rozsądnych ustawień domyślnych dla sprawdzanej konfiguracji bez konieczności jej kompletności lub zawierającej takie elementy, jak nazwy hostów i poświadczenia. Istnieje kilka sposobów na zastąpienie domyślnych konfiguracji.
Zmienne środowiskowe (jak już wspominali inni) są jednym ze sposobów na zrobienie tego.
Najlepszym sposobem jest poszukanie zewnętrznego pliku konfiguracyjnego, który zastępuje domyślne wartości konfiguracyjne. Pozwala to na zarządzanie zewnętrznymi konfiguracjami za pośrednictwem systemu zarządzania konfiguracją, takiego jak Chef, Puppet lub Cfengine. Zarządzanie konfiguracją jest standardową odpowiedzią w przypadku zarządzania konfiguracjami niezależnie od bazy kodu, więc nie musisz wykonywać wydania, aby zaktualizować konfigurację na jednym hoście lub w grupie hostów.
Do Twojej wiadomości: Szyfrowanie danych nie zawsze jest najlepszą praktyką, szczególnie w miejscach o ograniczonych zasobach. Może się zdarzyć, że szyfrowanie kredytów nie zapewni Ci dodatkowego ograniczenia ryzyka i po prostu doda niepotrzebną warstwę złożoności. Upewnij się, że wykonałeś odpowiednią analizę przed podjęciem decyzji.
źródło
Zaszyfruj plik haseł, używając na przykład GPG. Dodaj klucze na komputerze lokalnym i na serwerze. Odszyfruj plik i umieść go poza folderami repozytoriów.
Używam pliku passwords.conf, znajdującego się w moim folderze domowym. Przy każdym wdrożeniu ten plik jest aktualizowany.
źródło
Nie, klucze prywatne i hasła nie podlegają kontroli wersji. Nie ma powodu, aby obciążać wszystkich dostępem do odczytu do repozytorium znajomością poufnych danych uwierzytelniających usług używanych w produkcji, podczas gdy najprawdopodobniej nie wszyscy powinni mieć dostęp do tych usług.
Począwszy od Django 1.4, Twoje projekty Django są teraz dostarczane z
project.wsgi
modułem, który definiujeapplication
obiekt i jest to idealne miejsce, aby zacząć wymuszać użycieproject.local
modułu ustawień, który zawiera konfiguracje specyficzne dla witryny.Ten moduł ustawień jest ignorowany podczas kontroli wersji, ale jego obecność jest wymagana podczas uruchamiania instancji projektu jako aplikacji WSGI, co jest typowe dla środowisk produkcyjnych. Tak to powinno wyglądać:
Teraz możesz mieć
local.py
moduł, którego właściciela i grupę można skonfigurować tak, aby tylko upoważniony personel i procesy Django mogły odczytywać zawartość pliku.źródło
Jeśli potrzebujesz VCS dla swoich sekretów, powinieneś przynajmniej przechowywać je w drugim repozytorium oddzielonym od twojego rzeczywistego kodu. Możesz więc dać członkom swojego zespołu dostęp do repozytorium kodu źródłowego, tak aby nie widzieli Twoich poświadczeń. Ponadto umieść to repozytorium w innym miejscu (np. Na własnym serwerze z zaszyfrowanym systemem plików, a nie na github) i aby sprawdzić je w systemie produkcyjnym, możesz użyć czegoś takiego jak git-submodule .
źródło
Innym podejściem mogłoby być całkowite uniknięcie zapisywania sekretów w systemach kontroli wersji i zamiast tego użycie narzędzia takiego jak repozytorium z hashicorp , tajnego magazynu z rolowaniem klucza i audytem, z interfejsem API i wbudowanym szyfrowaniem.
źródło
Tym się właśnie zajmuję:
Pliki szablonów zawierają symbol zastępczy dla klucza tajnego, na przykład:
my.password = ## MOJE_HASŁO ##
Podczas wdrażania aplikacji uruchamiany jest skrypt, który przekształca plik szablonu w plik docelowy, zastępując symbole zastępcze wartościami zmiennych środowiskowych, na przykład zmieniając ## MY_PASSWORD ## na wartość $ MOJE_HASŁO.
źródło
Możesz użyć EncFS, jeśli twój system to zapewnia. W ten sposób możesz zachować zaszyfrowane dane jako podfolder repozytorium, jednocześnie zapewniając aplikacji odszyfrowany widok danych zamontowanych na bok. Ponieważ szyfrowanie jest przezroczyste, nie są potrzebne żadne specjalne operacje w przypadku ściągania lub wypychania.
Wymagałoby to jednak zamontowania folderów EncFS, co może zrobić Twoja aplikacja na podstawie hasła przechowywanego w innym miejscu poza wersjonowanymi folderami (np. Zmienne środowiskowe).
źródło