Czy pliki konfiguracyjne serwera/bazy danych, w tym hasła, powinny być przechowywane w kontroli źródła?

Szukam dobrych praktyk...

Zakładając, że aplikacja webowa współdziała z kilkoma różnymi serwerami produkcyjnymi (bazami danych itp.)... czy pliki konfiguracyjne zawierające hasła do bazy danych powinny być przechowywane w kontrolce źródłowej (np. git, svn)?

Jeśli nie, jaki jest najlepszy sposób na śledzenie bazy danych serwera (lub innych powiązanych) haseł, do których aplikacja potrzebuje dostępu?

Edit: dodano bounty, aby zachęcić do dalszej dyskusji i usłyszeć co więcej ludzie uważają za najlepsze praktyki.

Author: philfreo, 2010-11-22

13 answers

Nie ma tu ani jednej odpowiedzi "silver bullet" i wszystko zależy od szczegółów.

Po pierwsze, uważam za najlepszą praktykę oddzielanie całego kodu źródłowego od konfiguracji w osobnym repozytorium. Tak więc kod źródłowy pozostaje kodem źródłowym, ale jego instalacja lub wdrożenie (z konfiguracją, hasłami itp.) to zupełnie inna sprawa. W ten sposób możesz zdecydowanie oddzielić zadania programistów od zadań administratorów i ostatecznie zbudować 2 odrębne zespoły robiące to, co jest dobre at.

Jeśli masz osobne repozytorium kodu źródłowego + repozytorium wdrażania, najlepszym rozwiązaniem jest rozważenie opcji wdrażania. Najlepszym sposobem, jaki widzę tutaj, jest użycie procedur wdrażania typowych dla wybranego systemu operacyjnego (tj. budowanie autonomicznych pakietów dla wybranego systemu operacyjnego w sposób, w jaki robią to opiekunowie systemu operacyjnego).

Na przykład, procedury pakowania Red Hata lub Debiana zwykle oznaczają przechwycenie kulki oprogramowania z zewnętrznej strony (co byłoby eksportem źródeł z kodu źródłowego VCS), rozpakowanie go, kompilacja i przygotowanie pakietów gotowych do wdrożenia. Samo wdrożenie powinno oznaczać wykonanie szybkiego i prostego polecenia, które instalowałoby pakiety, takie jakrpm -U package.rpm, dpkg --install package.deb lub apt-get dist-upgrade (biorąc pod uwagę, że zbudowane Pakiety trafiają do repozytorium, w którym apt-get mógłby je znaleźć).

Oczywiście, aby to działało w ten sposób, będziesz musiał dostarczyć wszystkie pliki konfiguracyjne dla wszystkich komponentów systemu w stanie w pełni działającym, w tym wszystkie adresy i poświadczenia.

Aby być bardziej zwięzłym, rozważmy typową sytuację "małych usług": jedną aplikację PHP wdrożoną na serwerach aplikacji n z serwerami Apache / mod_php, dostęp do serwerów M MySQL. Wszystkie te serwery (lub wirtualne kontenery, co nie ma znaczenia) znajdują się w chronionej sieci prywatnej. Aby ułatwić ten przykład, załóżmy, że cała prawdziwa łączność z Internetem jest kierowana przez klaster K akceleratorów http / odwrotnych proxy (takie jak nginx / lighttpd / apache), które mają bardzo łatwą konfigurację(tylko wewnętrzne adresy IP do przekazania).

Co mamy dla nich, aby byli połączeni i w pełni działali?

    Serwery MySQL: konfigurowanie IPs/nazw hostów, konfigurowanie baz danych, dostarczanie loginów i haseł]}
  • aplikacja PHP: skonfiguruj IPs / nazwy hostów, Utwórz plik konfiguracyjny, który wspomni o IP serwerów MySQL, loginach, hasłach i bazach danych

Zauważ, że istnieją 2 różne" rodzaje " informacji tutaj: IPs / hostnames jest czymś stałym, prawdopodobnie chcesz je przypisać raz na zawsze. Z drugiej strony loginy i hasła (a nawet nazwy baz danych) służą wyłącznie do celów łączności - aby upewnić się, że w MySQL jest to naprawdę nasza aplikacja PHP, która się z nią łączy. Więc, moje zalecenia tutaj byłoby dzielenie tych 2 "typy":

    W 1996 roku, po raz pierwszy w Polsce, w 1999 roku, w Polsce i za granicą, w Polsce i za granicą, w Polsce i za granicą.]}
  • "Informacje przejściowe" , takie jak hasła między 2 aplikacjami, nie powinny być nigdy przechowywane, ale generowane podczas generowania pakietów wdrożeniowych.

Ostatnie i najtrudniejsze pytanie pozostaje tutaj: jak tworzyć pakiety wdrożeniowe? Istnieje wiele dostępnych technik, 2 główne sposoby to:

  • eksportowanie kodu źródłowego z VCS1 + konfiguracja" permanentna " z vcs2 + budowanie skryptu z VCS3 = Pakiety
  • kod źródłowy jest w VCS1; VCS2 jest rozproszoną kontrolą wersji (jak git lub hg), który zasadniczo zawiera "forki" vcs1 + informacje konfiguracyjne + Skrypty budowlane, które mogą generować . Osobiście podoba mi się to podejście bardziej, jest znacznie krótsze i ostatecznie łatwiejsze w użyciu,ale krzywa uczenia się może być nieco bardziej stroma, szczególnie dla adminów, którzy będą musieli opanować git lub hg.

Dla powyższego przykładu stworzyłbym Pakiety typu:

  • my-application-php - które zależałyby od mod_php, apache i zawierałyby wygenerowany plik typu /etc/my-php-application/config.inc.php, który będzie Dołącz IPs/hostnames bazy danych MySQL i login / hasło wygenerowane jako md5(current source code revision + salt). Pakiet ten będzie zainstalowany na każdym z N serwerów aplikacji. Idealnie, powinna być w stanie zainstalować na czysto zainstalowanym systemie operacyjnym i utworzyć w pełni działający węzeł klastra aplikacji bez żadnej ręcznej aktywności.
  • my-application-mysql - która zależałaby od serwera MySQL i zawierałaby skrypt post-instalacyjny, który:
    • uruchamia serwer MySQL i upewnia się, że uruchomi się on automatycznie na OS start
    • łączy się z serwerem MySQL
    • sprawdza, czy istnieje wymagana baza danych
    • Jeśli nie-tworzy bazę danych, uruchamia ją z zawartością i tworzy login z hasłem (te same loginy i hasła, które wygenerowano w /etc/my-php-application/config.inc.php, używając algorytmu md5)
  • jeśli tak-łączy się z bazą danych, stosuje migracje, aby przenieść ją do nowej wersji, zabija wszystkie starsze loginy / hasła i odtwarza nową parę login/hasło (ponownie, wygenerowaną za pomocą md5 (revision + salt) metoda)

Ostatecznie powinno to przynieść korzyści z aktualizacji Twojego wdrożenia za pomocą jednego polecenia, takiego jak generate-packages && ssh-all apt-get dist-upgrade. Ponadto nie przechowujesz haseł między aplikacjami w dowolnym miejscu i są one regenerowane przy każdej aktualizacji.

Ten dość prosty przykład ilustruje wiele metod, które można tutaj zastosować - ale ostatecznie to od Ciebie zależy, które rozwiązanie jest lepsze, a które jest przesadne. Jeśli umieścisz więcej szczegółów tutaj lub jako osobne pytanie, będę chętnie sięgam po szczegóły.

 26
Author: GreyCat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-30 22:34:22

Pomijając kwestię, że hasła nigdy nie powinny być przechowywane w zwykłym tekście w dowolnym miejscu (poza czyjąś czaszką lub zamkniętym skarbcem dostępnym tylko dla CEO, CFO i CIO (i potrzebującym wszystkich trzech kluczy jednocześnie)), powinieneś przechowywać wszystko w kontroli źródła, które jest wymagane do zbudowania Twojego produktu.

Oznacza to nie tylko twoje źródło, ale nawet specyfikacje maszyn budowlanych, opcje kompilatorów, same kompilatory i tak dalej.

If we could znajdź sposób, aby sprawdzić w fizycznym sprzęcie, my też to zrobimy: -)

Wszystko, co może być odtworzone przez sam proces budowania, lub cokolwiek dla Uruchamianie zamiast budowania oprogramowania (takiego jak twoje hasła), zazwyczaj nie podlega kontroli źródłowej, ale niektóre sklepy zrobią to dla swoich plików wykonywalnych, wygenerowanych dokumentów itp., tylko po to, aby mogli szybko uzyskać konkretne wydanie do instalacji.

 18
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-03 08:40:15

Hasła nie powinny być przechowywane w kontroli źródła. W ogóle. Nigdy. Zobacz Jak zachować tajemnice w tajemnicy

Hasła, Nazwy serwerów itp. są częścią konfiguracji wdrożenia wykonywanej przez administratora serwera. Konieczne jest udokumentowanie tej procedury i poddanie udokumentowanej procedury kontroli.

Alternatywnie konfiguracja wdrożenia może być wykonana przez skrypt, który sysadmin uruchomi, aby wykonać konfigurację, a podczas skryptu wykonanie poprosi sysadmin o podanie wymaganych informacji. Ponownie ten skrypt musi być utrzymywany w kontroli wersji.

Wszystko inne, poza konfiguracją serwera musi być pod kontrolą źródła.

Przechowywanie konfiguracji serwera w source control jest generalnie złym pomysłem, ponieważ przeszkadza to we wdrożeniach i może powodować małe katastrofy (np. gdy ktoś nie zdaje sobie sprawy, że jego wersja testowa wdrożona z source control komunikuje się z live serwis).

Zawsze przechowuj te pliki konfiguracyjne poza webrootem.

Zaufane połączenia mogą być opcją, pozwalającą znanym adresom IP łączyć się z usługami poprzez konfigurację tej usługi..

 11
Author: Richard Harrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-01 13:48:51

Ogólnie, zgadzam się z paxdiablo: umieścić wszystko, co możliwe pod kontrolą źródła. Obejmuje to pliki konfiguracyjne produkcji z poświadczeniami bazy danych.

Pomyśl o sytuacji, w której twój serwer ulega awarii, kopie zapasowe okazują się złe i musisz przywrócić ten serwer. Myślę, że ty i twój Klient (lub szef) zdecydowanie zgodzilibyście się, że posiadanie wszystkiego, co potrzebne do wdrożenia witryny w kontroli źródeł, jest dużym plusem.

Jeśli chcesz łatwo budować instalowalne pakiety z Twoich źródeł przy użyciu ciągłej integracji (Inna najlepsza praktyka) będziesz musiał umieścić pliki konfiguracyjne pod kontrolą źródeł.

Należy również wziąć pod uwagę, że w większości przypadków programiści, którzy mają dostęp do kontroli źródła, nie mogą uzyskać dostępu bezpośrednio do produkcyjnego serwera bazy danych. Hasła produkcyjne są dla nich bezużyteczne.

Jeśli niewłaściwi ludzie uzyskali dostęp do Twoich źródeł, nadal muszą uzyskać dostęp do serwera produkcyjnego, aby zaszkodzić hasła. Tak więc, jeśli twoje środowisko produkcyjne jest odpowiednio chronione, zagrożenia bezpieczeństwa związane z hasłami w kontroli źródeł są bardzo ograniczone.

 7
Author: Marnix van Valen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-22 08:07:49

Myślę, że to pytanie dotyczy bardziej własności informacji, zaufania i organizacji. Powinieneś zadać sobie pytanie, jakiej części twojej organizacji ufałbyś, aby Twoje hasła systemowe były bezpieczne przed ujawnieniem i nadużyciem?

Byłem w organizacjach, gdzie były trzymane przez ludzi odpowiedzialnych za biznes. W innych przypadkach zostały one przekazane zespołowi operacyjnemu, który posiadał również procesy związane z tworzeniem i użytkowaniem itp.

Najważniejsze jest to, że jest jasno określone w organizacji, kto powinien mieć dostęp do haseł systemowych. Następnie możesz zdecydować się na odpowiednie rozwiązania techniczne do ochrony haseł.

 3
Author: 8DH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-26 11:37:25

Nie. Hasło produkcyjne należy skonfigurować bezpośrednio na serwerze. Należy utworzyć instrukcje wdrażania dla zespołu wdrożeniowego/osoby, aby zmienić odpowiedni plik właściwości podczas wdrażania.

 1
Author: Jinesh Parekh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-22 07:27:04

Stwierdziłem, że użycie skryptu build (w moim przypadku Phing) było najlepszym sposobem wprowadzania haseł.

 1
Author: Matt Bostock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-29 09:38:26

W moim Subversion repos dla PHP, pliki konfiguracyjne zawierające hasła są sprawdzane jako config.php.sample ze wskazówkami do tego, co należy podać, a Skrypty opierające się na PHP wymagają obecności config.php w tym samym miejscu.

Repozytorium jest skonfigurowane tak, aby ignorować config.php dla tego katalogu, aby uniknąć "przypadkowych" dodawania lub sprawdzania.

 1
Author: Linus Kleen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-30 21:20:40

Przykładowy plik konfiguracji, oczywiście, poddałbym je kontroli wersji. Ale zazwyczaj nie z danymi dostępowymi realworld, takimi jak adresy serwerów lub hasła. More somethinglike

# program.conf
#
# mysql option for $myprog.
#
#SERVER_ADDR=127.0.0.1
#SERVER_USER=mysql
#SERVER_PASSWD=abcdef
 1
Author: user502515,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-30 22:40:01

Problemy z hasłami w kodzie źródłowym:

  • trudno się różnić od jednego wdrożenia do drugiego (nie chcę modyfikować kodu źródłowego w produkcji)
  • zwiększone prawdopodobieństwo przypadkowego uszkodzenia bazy danych produkcji podczas tworzenia
  • problem z bezpieczeństwem (w większości sklepów nie ma powodu, aby Kod/Programiści znali hasła prod)
  • zmiana hasła wymaga przesunięcia

To co znalazłem działa najlepiej to sprawdzanie config w tym wykorzystuje domyślne wartości mixture sane i symbole zastępcze dla danych specyficznych dla wdrożenia. Nasze aplikacje zawsze szukają konfiguracji systemowej, która pozwala na nadpisanie dowolnej zmiennej. Dzięki temu maszyna produkcyjna może mieć konfigurację odpowiednią do jej wdrożenia.

Uwaga: kiedy funkcjonuję jako administrator, zawsze zarządzam configami oddzielnie od kodu (nie bez powodu).

 1
Author: dietbuddha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-01 17:14:51

Zawsze wykluczałbym istotne pliki konfiguracyjne, które zawierają hasła lub inne szczegóły dostępu (jak w przypadku baz danych), to czysta najlepsza praktyka. Do tego Kontrola źródeł i wersji służy zwykle więcej niż jednemu użytkownikowi i nie wszyscy pracują z tymi samymi danymi bazy danych lub nawet z tym samym konfiguracją serwera (domeny itp.) i w tym celu pliki konfiguracyjne powinny pozostać wyłączone z tej całej partii.

 0
Author: Matthew Morek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-01 12:03:25

Bez odpowiedniego procesu budowania, używam tej strategii (dla aplikacji PHP):

  1. Stwórz folder /etc/companyname
  2. W nim umieść dwa pliki:

    <?php // env.php
    return 'prod'; 
    
    <?php // appname-prod.php
    return array(
      'db' => array( /* credentials */ ),
      /* other host-specific conf data */
    ); 
    
  3. Aby oba pliki były czytelne tylko przez proces PHP

Teraz plik konfiguracyjny Twojej aplikacji będzie wyglądał następująco:

<?php // config.php
$env = (require "/etc/companyname/env.php");
$creds = (require "/etc/companyname/appname-{$env}.php");

W tym miejscu środowisko definiuje używane poświadczenia i można przenosić Kod między wstępnie skonfigurowanymi środowiskami(i kontrolować niektóre opcje za pomocą $env). Oczywiście można to zrobić za pomocą zmiennych środowiskowych serwera, ale to a) jest prostsze w konfiguracji i b) nie ujawnia poświadczeń każdemu skryptowi na serwerze (nie pojawi się w bezpańskich śmieciach debugujących, takich jak phpinfo()).

Dla łatwiejszego czytania poza PHP możesz zrobić pliki uwierzytelniające JSON lub coś takiego i po prostu znosić mały hit wydajności (APC nie będzie ich buforować).

 0
Author: Steve Clay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-29 17:06:12

Wolę mieć plik local_settings obok głównego pliku settings . To local_settings nie powinno być dodawane do repozytorium, ale dodam próbkę .local_setting do repozytorium, aby pokazać strukturę tego pliku.

W czasie wykonywania, jeśli istnieje local_settings, jego wartości nadpisują wartości głównego pliku ustawień.

Na przykład w python:

Settings.py:

log='error.log'
db=lambda:None
db.host='localhost'
db.user=''
db.password=''

try:
    import local_settings
except ImportError:
    pass

Local_settings.py:

from settings import *

db.user='abcd'
db.password='1234'
 0
Author: iman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 07:14:16