Czy bezpieczne jest przechowywanie krytycznych haseł w zmiennych środowiskowych serwera?

23

Mam klaster serwerów, każdy z plikami konfiguracyjnymi, które obecnie zawierają hasła w postaci zwykłego tekstu dla wrażliwych systemów o kluczowym znaczeniu (kolejki komunikatów, magazyny danych i inne usługi).

Niektóre osoby przenoszą krytyczne hasła z plików konfiguracyjnych do zmiennej środowiskowej kont użytkowników, na których działają procesy serwera. W ten sposób pliki konfiguracyjne można przypisać do kontroli wersji, a administrator systemu musi tylko utworzyć odpowiednią zmienną środowiskową, gdy system serwera jest skonfigurowany. Oczywiście dostęp do kont prowadzących te usługi jest bardzo ograniczony.

Czy to naprawdę najlepszy sposób na uniknięcie haseł w plikach konfiguracyjnych w postaci zwykłego tekstu, czy jest lepszy sposób?

Steve HHH
źródło
3
Cóż, pamiętaj, że jeśli przechowujesz ją jako zmienną, jest ona w postaci zwykłego tekstu zarówno w spoczynku, jak i podczas zapytania użytkownika. oznacza to, że jeśli stracisz trochę kontroli nad poziomem serwera, podałeś atakującemu hasło. Prawdopodobnie użyłbym crypto i w razie potrzeby odszyfrowałbym hasło.
Frank Thomas
Miłe myśli, Frank. Jeśli miałbyś użyć krypto, jakiego systemu używałbyś? Coś opartego na kluczu RSA / SSH, narzędziu pęku kluczy lub czymś innym? Obecnie używamy systemów Linux> 2.6, takich jak CentOS i Amazon.
Steve HHH

Odpowiedzi:

11

Jeśli korzystasz z systemu Linux, spójrz na / proc / * / environment i zdecyduj, czy zmienne środowiskowe są dobrym miejscem do przechowywania poufnych informacji, czy nie. / proc / self to bieżący proces:

$ tr '\0' '\n' < /proc/self/environ
USER=me
LOGNAME=me
HOME=/home/me
PATH=/usr/bin:/bin:/usr/sbin:/sbin
MAIL=/var/mail/me
SHELL=/usr/bin/sh
SSH_CLIENT=1.2.3.4 58195 22
SSH_CONNECTION=1.2.3.4 58195 7.8.9.0 22
SSH_TTY=/dev/pts/1
TERM=xterm

Nieważne, że ustawianie zmiennej środowiskowej prawdopodobnie gdzieś czyta plik.

Należy pamiętać, że użycie hasła oznacza, że ​​hasło jest dostępne dla programu. Jeśli hasło nie jest podawane przez użytkownika, który wpisuje je za każdym razem, gdy program go potrzebuje, hasło to musi być dostępne tylko na podstawie dostępu do programu. Możesz zaszyfrować hasło lokalnie i pozwolić programowi odszyfrować za pomocą klucza, ale wszystko, co to robi, to zasłania hasło przed przypadkowym ujawnieniem; ktoś, kto ma taki sam dostęp jak program, może wykonywać te same czynności, co program, w tym czytać klucz szyfrujący.

Właściwy sposób to uruchomić aplikację jako konto z ograniczeniami i przechowywać hasło w pliku chronionym uprawnieniami na poziomie systemu plików. Mamy nadzieję, że możesz „dołączyć” plik lub podobny plik, aby utrzymać hasło poza systemem kontroli wersji (zakładając, że VCS nie ma kontroli bezpieczeństwa). Aby zabezpieczyć się przed nieumyślnym ujawnieniem, ukryj hasło w dowolny sposób - koduj kod base64, użyj pgp do szyfrowania, cokolwiek ma sens w zestawie opcji programu serwera. Jeśli piszesz program, aby to zrobić, najlepiej jest poprosić użytkownika o hasło tylko w razie potrzeby, a następnie usunąć hasło z pamięci, gdy tylko zostanie użyte.

dannysauer
źródło
3
Tak, plik w trybie 0600 należący do użytkownika uruchamiającego program jest dostępny dla tych samych osób, które mogą uzyskać dostęp do środowiska programu. Ale, jak wspomniałem, środowisko prawdopodobnie konfiguruje się poprzez odczyt pliku, więc kopiowanie danych do środowiska tylko zwiększa liczbę miejsc, w których dane są dostępne. Środowisko jest domyślnie duplikowane do procesów potomnych. A wiele programów ma zewnętrzne sposoby na zapytanie o zmienne środowiskowe z powodu błędów lub celowych decyzji projektowych (think phpinfo ()). Jeśli plik zostanie zaangażowany w jakikolwiek sposób, po co zwiększać powierzchnię ataku?
dannysauer
1
Polecenie tr, które podałeś, nie działało dla mnie - to:cat /proc/self/environ | tr '\0' '\n'
robocat
Jestem w telefonie, więc trudno powiedzieć ... To powinno być zero; czy wpisałeś literę „o”?
dannysauer
8

Ostatecznie, jeśli masz jakieś dane, które muszą zostać odczytane, a także zapisane , ostatecznie zabezpieczysz coś hasłem (lub jeśli naprawdę jesteś paranoikiem, z fizyczną sprzętową kartą inteligentną i kodem PIN), nie niezależnie od tego, ile masz warstw szyfrowania.

Sprowadza się to do podstawowej kwestii bezpieczeństwa systemu a wygody. Możesz dodać „głębszą obronę”, mając wiele warstw kontroli bezpieczeństwa, które złośliwy aktor musiałby złamać, aby dostać się do „towarów”, ale wtedy, gdy legalny aktor chce odczytać lub zmienić niektóre dane, muszą przejść przez kilka obręczy. Alternatywą są hasła w postaci zwykłego tekstu w plikach tekstowych.

Co zrobiłbym, gdybym naprawdę chciał chronić niektóre informacje w systemie o kluczowym znaczeniu:

  1. Użyj pełnego szyfrowania dysku, aby zawartość całego trwałego magazynu była szyfrowana.

  2. Ogranicz fizyczny dostęp do maszyn. Zablokuj podwozie maszyny za pomocą bezpiecznego mechanizmu blokującego i kontroluj fizyczny dostęp do kluczy. Zatrudnij mięśni (uzbrojonych strażników), aby byli strażnikami dostępu.

  3. Wymuszaj drobiazgową obowiązkową kontrolę dostępu (MAC) w systemie operacyjnym urządzenia. Możesz zacząć od czegoś takiego jak SELinux na GNU / Linux i ustawić go na wymuszanie, a następnie dostosować politykę do dokładnych potrzeb oprogramowania produkcyjnego, pozwalając tym kontom dokładnie (i tylko) uprawnienia, których potrzebują do potrzebnych plików.

  4. Jeśli masz hasła systemowe i kontrolę wersji dla plików konfiguracyjnych, naprawdę chcesz uniknąć możliwego błędu polegającego na błędnym przypisaniu hasła jawnego do kontroli wersji, ponieważ usunięcie wyciekającego hasła z pliku może być trudne Pamięć podręczna VCS. Zmienne środowiskowe są jedną z kilku wykonalnych opcji. Drugim jest monit o podanie hasła przy uruchamianiu programu, ale ponowne uruchomienie komputera i przywrócenie stanu operacyjnego to ręczny wysiłek i nie można go wykonać autonomicznie, więc znów jest to wygoda kontra bezpieczeństwo.

  5. Upewnij się, że masz pod ręką specjalistów od sieci, którzy zajmą się uprawnieniami zapory sieciowej, aby zminimalizować ryzyko ataku przez sieć. Audyt (test penetracji oraz test kodu whitebox) każdego oprogramowania, które współpracuje z systemami zewnętrznymi, zwłaszcza publicznym Internetem. „Interfejsy” obejmują nie tylko bezpośrednie połączenia sieciowe, ale także odczytywanie lub zapisywanie „niezaufanych” danych (danych, których bajty pochodzą spoza pamięci RAM / dysku / procesora bezpiecznego serwera).

Nie jest to pełna lista, ale szczególnie punkt 4 jest prawdopodobnie dla ciebie odpowiedni, chociaż jeśli nie wykonasz co najmniej kroków od 1 do 3, rozważenie punktów 4 i 5 nie pomoże ci bardzo, ponieważ twoje system nie jest bezpieczny na dość podstawowym poziomie.

allquixotic
źródło
Pominąłbym # 1. Jeśli system jest uruchomiony, system plików jest podłączony i niezaszyfrowany. Jeśli nie działa, fizyczna kontrola dostępu powinna być odpowiednia. Jeśli trzeba go zrestartować, potrzebujesz kogoś, kto dostarczy klucz deszyfrujący przy każdym rozruchu (co jest denerwujące), lub potrzebujesz, aby komputer to zapewnił - w takim przypadku poświadczenia są zwykle dostępne dla każdego, kto ma dostęp do dysku twardego . Większość maszyn „serwerowych” zazwyczaj nie używa szyfrowania dysku z powodu tego kosztu kompromisu. :)
dannysauer
„Sprowadza się to do podstawowego pytania o bezpieczeństwo systemu a wygodę” - zacytowane z mojej odpowiedzi - które dotyczy w równym stopniu twojego komentarza. Nie można jednocześnie zmaksymalizować bezpieczeństwa i wygody.
allquixotic
1
# 1 jest ważne w przypadku, gdy jakaś część pamięci uderza w dysk (zamiana) lub jeśli uderza w sektor ssd, który później staje się „zły” i jest odsunięty od systemu operacyjnego, ale nadal trzyma ten fragment pamięci. nawet gdy dysk jest obecnie odblokowany, ta część danych ostatecznie zakodowana jest na talerzach.
akira
3

Przekazanie hasła do zmiennej środowiskowej jest tak samo bezpieczne, jak odczytanie go przez program z pliku. Tylko procesy działające jako ten sam użytkownik mogą odczytywać środowisko procesu , a procesy te i tak mogą odczytywać te same pliki.

Pamiętaj, że różni się to od podania hasła w wierszu poleceń. Argumenty wiersza poleceń są odczytywane przez wszystkie procesy uruchomione na tym samym komputerze (pomiary hartowania), a nie tylko procesy uruchomione jako ten sam użytkownik.

Jeśli przekazujesz zmienną przez środowisko, strzeż się, jeśli program uruchomi inne programy. Te inne programy odziedziczą środowisko swoich rodziców. Nie rób tego, jeśli obawiasz się, że inne programy mogą przypadkowo wyciec zawartość swojego środowiska.

Wadą tego scenariusza jest „utworzenie odpowiedniej zmiennej środowiskowej podczas konfiguracji systemu serwera”. Zmienna środowiskowa jest dynamiczną właściwością procesu. Nie możesz go utworzyć podczas konfigurowania systemu, nie jeśli przez konfigurację masz na myśli coś, co przetrwa restart. To, co masz na myśli, to przypuszczalnie, że administrator zaaranżował, aby ta zmienna była obecna w środowisku, gdy loguje się określony użytkownik. Odbywa się to poprzez plik konfiguracyjny (zwykle ~/.pam_environmentlub ~/.profileplik odczytany ~/.profile). To rozwiązanie nie przenosi hasła z plików konfiguracyjnych.

Konfigurowanie haseł w środowisku logowania użytkownika nie jest dobrym pomysłem. Oznacza to, że każdy proces działający jako ten użytkownik będzie miał sekret, więc jest podatny na wyciek w dowolnym miejscu.

Hasło należy umieścić w pliku innym niż pliki konfiguracyjne podlegające kontroli wersji i normalnym mechanizmom wdrażania. Można w pewnym momencie umieścić hasło w środowisku, jeśli jest to wygodne, ale należy to zrobić dla możliwie najmniejszego zestawu programów.

Gilles „SO- przestań być zły”
źródło