Ukrywanie hasła w skryptach powłoki

23

Jak mogę ukryć hasło w skryptach powłoki? Istnieje wiele skryptów uzyskujących dostęp do bazy danych. Jeśli otworzymy skrypt, inni znają również nazwę użytkownika i hasło. Więc jeśli ktoś wie, jak się ukryć, daj mi znać.

Mam jeden sposób: umieść hasło w pliku i ustaw plik jako ukryty, aby nikt nie miał dostępu do pliku (zmień uprawnienia i użyj pliku w skrypcie podczas uzyskiwania dostępu do bazy danych).

bieg
źródło

Odpowiedzi:

35

Po pierwsze , jak już powiedziało kilka osób, niezbędne jest oddzielenie poświadczeń od skryptu. (Oprócz zwiększonego bezpieczeństwa oznacza to również, że możesz ponownie użyć tego samego skryptu dla kilku systemów z różnymi poświadczeniami.)

Po drugie , należy wziąć pod uwagę nie tylko bezpieczeństwo poświadczeń, ale także wpływ, jeśli / kiedy dane poświadczenia zostaną naruszone. Nie powinieneś mieć tylko jednego hasła do całego dostępu do bazy danych, powinieneś mieć różne poświadczenia o różnych poziomach dostępu. Możesz na przykład mieć jednego użytkownika DB, który ma możliwość wyszukiwania w bazie danych - ten użytkownik powinien mieć dostęp tylko do odczytu. Inny użytkownik może mieć uprawnienia do wstawiania nowych rekordów, ale nie może ich usuwać. Trzeci może mieć uprawnienia do usuwania rekordów.

Oprócz ograniczenia uprawnień dla każdego konta, powinieneś mieć również ograniczenia, z którego można korzystać z każdego konta. Na przykład konto używane przez serwer sieciowy nie powinno mieć możliwości łączenia się z innego adresu IP niż adres serwera WWW. Konto z pełnymi uprawnieniami roota do bazy danych powinno być bardzo ograniczone pod względem miejsca, z którego może się łączyć i nigdy nie powinno być używane inaczej niż interaktywnie. Rozważ także użycie procedur przechowywanych w bazie danych, aby dokładnie ograniczyć możliwości każdego konta.

Ograniczenia te należy wdrożyć po stronie serwera DB, aby nawet po narażeniu strony klienta ograniczenia nie mogły zostać z niej zmienione. (I oczywiście serwer DB musi być chroniony zaporami ogniowymi itp. Oprócz konfiguracji DB ...)

W przypadku konta DB, które ma ograniczony dostęp tylko do odczytu i tylko z określonego adresu IP, możesz nie potrzebować żadnych dalszych danych uwierzytelniających, w zależności od wrażliwości danych i bezpieczeństwa hosta skryptu ucieka. Jednym z przykładów może być formularz wyszukiwania w Twojej witrynie, który można uruchomić z użytkownikiem, który może korzystać tylko z procedury składowanej, która wyodrębnia tylko informacje, które zostaną przedstawione na stronie internetowej. W takim przypadku dodanie hasła tak naprawdę nie zapewnia żadnego dodatkowego bezpieczeństwa, ponieważ informacje te są już przeznaczone do publicznego, a użytkownik nie może uzyskać dostępu do żadnych innych danych, które byłyby bardziej wrażliwe.

Upewnij się również, że połączenie z bazą danych zostało nawiązane przy użyciu TLS, w przeciwnym razie każdy, kto nasłuchuje w sieci, może uzyskać twoje poświadczenia.

Po trzecie , zastanów się, jakiego rodzaju poświadczeń użyć. Hasła są tylko jedną formą i nie są najbezpieczniejsze. Zamiast tego możesz użyć jakiejś formy pary kluczy publiczny / prywatny, AD / PAM lub tym podobnych.

Po czwarte , rozważ warunki, w których skrypt zostanie uruchomiony:

Jeśli jest uruchamiany interaktywnie, należy wprowadzić hasło lub hasło do klucza prywatnego lub klucza prywatnego lub zalogować się przy użyciu ważnego biletu Kerberos po uruchomieniu - innymi słowy, skrypt powinien uzyskać poświadczenia bezpośrednio od ciebie w momencie uruchomienia, zamiast odczytywania ich z jakiegoś pliku.

Jeśli jest uruchamiany z serwera WWW, rozważ skonfigurowanie poświadczeń w momencie uruchamiania serwera. Dobrym przykładem są tutaj certyfikaty SSL - mają certyfikat publiczny i klucz prywatny, a klucz prywatny ma hasło. Możesz przechowywać klucz prywatny na serwerze WWW, ale nadal musisz wprowadzić hasło do niego po uruchomieniu Apache. Możesz również mieć poświadczenia na jakimś sprzęcie, takim jak karta fizyczna lub HSM, które można usunąć lub zablokować po uruchomieniu serwera. (Oczywiście wadą tej metody jest to, że serwer nie może się zrestartować samodzielnie, jeśli coś się wydarzy. Wolę to niż ryzyko narażenia mojego systemu na szwank, ale przebieg może się różnić ...)

Jeśli skrypt jest uruchamiany z crona, jest to trudna część. Nie chcesz, aby poświadczenia znajdowały się w dowolnym miejscu w systemie, w którym ktoś może uzyskać do nich dostęp - ale chcesz, aby poświadczenia leżały tak, aby twój skrypt mógł uzyskać do nich dostęp, prawda? Cóż, niezupełnie dobrze. Zastanów się dokładnie, co robi skrypt. Jakich uprawnień potrzebuje do bazy danych? Czy można to ograniczyć, aby nie miało znaczenia, czy niewłaściwa osoba połączy się z tymi uprawnieniami? Czy możesz zamiast tego uruchomić skrypt bezpośrednio na serwerze DB, do którego nikt inny nie ma dostępu, zamiast z serwera, który ma innych użytkowników? Jeśli z jakiegoś powodu, o którym nie mogę pomyśleć, absolutnie musisz mieć skrypt działający na niepewnym serwerze i musi być w stanie zrobić coś niebezpiecznego / destrukcyjnego ... teraz jest dobry czas, aby przemyśleć swoją architekturę.

Po piąte , jeśli cenisz bezpieczeństwo swojej bazy danych, nie powinieneś uruchamiać tych skryptów na serwerach, do których mają dostęp inne osoby. Jeśli ktoś jest zalogowany w twoim systemie, będzie mógł uzyskać twoje dane uwierzytelniające. Na przykład w przypadku serwera WWW z certyfikatem SSL istnieje co najmniej teoretyczna możliwość uzyskania dostępu do katalogu głównego i uzyskania dostępu do obszaru pamięci procesu httpd i wyodrębnienia poświadczeń. W ostatnim czasie istniał przynajmniej jeden exploit, w którym można to zrobić za pomocą protokołu SSL, nawet nie wymagając zalogowania się atakującego.

Zastanów się również nad użyciem SELinuksa, aplikacji lub innej dostępnej dla twojego systemu, aby ograniczyć użytkowników, którzy mogą to robić. Umożliwią one użytkownikom zabronienie nawet próby połączenia się z bazą danych, nawet jeśli uda im się uzyskać dostęp do poświadczeń.

Jeśli to wszystko wydaje ci się przesadne i nie możesz sobie na to pozwolić lub nie masz czasu - to, moim zdaniem (arogancki i elitarny), nie powinieneś przechowywać w bazie danych niczego ważnego lub wrażliwego. A jeśli nie przechowujesz niczego ważnego lub wrażliwego, to miejsce, w którym przechowujesz swoje dane uwierzytelniające, również nie jest ważne - w takim przypadku, po co w ogóle używać hasła?

Na koniec , jeśli absolutnie nie możesz uniknąć przechowywania pewnego rodzaju poświadczeń, możesz mieć poświadczenia tylko do odczytu, a własność root i root może nadawać własność na wyjątkowo tymczasowy czas, gdy zostanie o to poproszony przez skrypt (ponieważ twój skrypt nie powinien być uruchom jako root, chyba że jest to absolutnie konieczne, a połączenie z bazą danych nie jest konieczne). Ale wciąż nie jest to dobry pomysł.

Jenny D.
źródło
9
W ogóle nie arogancki i elitarny. Albo ja też. „Jak mogę chronić swoją biżuterię na wypadek włamania się włamywacza?” „Umieść go w sejfie, który jest przykręcony / przyspawany”. „To zbyt duży problem, po prostu wezmę przenośny sejf i powiesię klucz na haczyku”. „Więc nie zawracaj sobie głowy używaniem sejfu”. Znakomicie rozsądna rada.
Wildcard
12

Przede wszystkim, jeśli istnieje jakikolwiek sposób na zmianę rzeczy, aby uniknąć konieczności przechowywania hasła wewnątrz lub obok skryptu, powinieneś dołożyć wszelkich starań, aby to zrobić. Odpowiedź Jenny D. zawiera wiele dobrych rad na ten temat.

W przeciwnym razie pomysł umieszczenia hasła w osobnym pliku z ograniczonymi uprawnieniami to właściwie wszystko. Możesz na przykład pobrać ten plik ze skryptu głównego:

. /usr/local/etc/secret-password-here

Możesz także ograniczyć uprawnienia do głównego skryptu, aby mogły go wykonywać tylko upoważnione osoby, ale prawdopodobnie lepiej zrobić to, co sugerujesz i przechowywać tylko hasło w ograniczonym pliku. W ten sposób możesz pozwolić na kontrolę samego kodu (bez poufnych tajemnic), kontrolę wersji i łatwiejsze kopiowanie skryptu itp.

Celada
źródło
@BasileStarynkevitch ah, ale widzę, że mówi również „ /usr/local/etcmoże być symbolicznym łączem do /etc/local”. Tęsknie za tym. Masz rację, ale MAJ, więc jest opcjonalny. Ale tak, nie ma to większego znaczenia i osobiste preferencje.
Celada,
1
Tyle że tworzę kopie zapasowe, /etc/ ale nie /usr/local/ (co, jak zakładam, może zostać odbudowane po awarii dysku)
Basile Starynkevitch
uczciwy punkt na temat kopii zapasowych
Celada
3

Inne odpowiedzi dotyczyły tego , ale zastanowię się, czy . W zależności od rodzaju bazy danych, z którą łączą się Twoi użytkownicy, możesz mieć już odpowiedni mechanizm, który jest już używany przez te programy klienckie, w takim przypadku pamiętaj o ich użyciu (mam na myśli ~/.mysqlrclub ~/.pgpass).

Jeśli dajesz kilku użytkownikom dostęp do bazy danych w celu wykonania określonych zapytań przy użyciu wspólnego konta, prawdopodobnie nie powinieneś. Zamiast tego upewnij się, że mają konta w bazie danych i że konta te nie mają więcej uprawnień niż potrzebują (prawdopodobnie czytają dużo z nich i bardzo mało dostępu do zapisu). Jeśli muszą zadać określone zapytania w niektórych tabelach, do których nie mogłyby uzyskać dostępu, zapewnij procedury składowane, SECURTY DEFINERaby im to umożliwić.

Jeśli żadna z powyższych unika potrzeby dodawania mandatów sklepowych, następnie przeczytać inne odpowiedzi tutaj.

Toby Speight
źródło
1

Twój pomysł ukrycia hasła w niedostępnym miejscu może być OK, w zależności od okoliczności.

Jeśli informacje są osobne, oznacza to prostą edycję pliku, np. Podczas recenzji kodu z kolegą nie będzie go wyświetlać. Ale zdaj sobie sprawę, że każdy, kto ma dostęp do twojego konta, może łatwo znaleźć taki plik. Użyłem podkatalogu ~/.sshdo takich celów, z tego prostego powodu, że sshnarzeka, jeśli prawa dostępu do ~/.sshnie są wystarczająco ograniczone.

Istnieją jednak inne rzeczy, które możesz zrobić, aby zapobiec przeglądaniu nazwy użytkownika i / lub haseł.

Obfuscating : Jeśli nie chcesz, aby ktokolwiek czytał nazwę użytkownika lub hasło podczas edycji skryptu, możesz umieścić go w tekście, ale nie jako zwykły tekst, ale zaciemnić. Jeśli zaciemniona wersja jest wystarczająco długa, aby uniemożliwić jej zapamiętanie przez kogoś, kto na nią patrzy, nie można jej poznać, nawet jeśli metoda deszyfrowania i klucz są widoczne. Oczywiście ktoś nadal miałby dostęp do twojego konta.

Korzystanie z GPG :

Nieco lepszym, ale wciąż nie pełnym dowodem na ataki użytkownika root w twoim systemie, jest szyfrowanie par nazwa-użytkownik / hasło w gpgpublicznym pliku i umożliwienie skryptu pobrania zawartości pliku (możliwe monitowanie o hasło, jeśli nie buforowane / wygasły). Używam karty ggp, więc kiedy zostawiam laptopa, ale wyciągam kartę, nie ma dostępu, nawet jeśli pin nadal byłby w pamięci podręcznej. Przynajmniej jeśli uruchomię coś 20 razy w ciągu kilku minut, muszę podać kod PIN tylko raz.

Bezpieczeństwo wydaje się zawsze odwrotnie związane z wygodą (konfigurowanie i używanie).

Anthon
źródło
0

Istnieje sposób na przechowywanie haseł w skrypcie bash, ale musisz zaszyfrować i zaciemnić skrypt , aby nikt nie mógł go odczytać ani uruchomić na nim żadnego debugera, aby zobaczyć dokładnie, co robi. Aby zaszyfrować i zaciemnić skrypt bash / shell i umożliwić jego wykonanie, spróbuj skopiować i wkleić go tutaj:

http://www.kinglazy.com/shell-script-encryption-kinglazy-shieldx.htm

Na powyższej stronie wystarczy, że prześlesz skrypt (możesz najpierw przesłać przykładowy skrypt, aby zachować spokój). Plik zip zostanie dla Ciebie wygenerowany. Kliknij prawym przyciskiem myszy link do pobrania i skopiuj podany adres URL. Następnie przejdź do pola UNIX i wykonaj następujące kroki.

Instalacja:

  1. wget link-to-the-zip-file

  2. rozpakuj nowo pobrany plik zip

  3. cd / tmp / KingLazySHIELD

  4. ./install.sh / var / tmp / KINGLAZY / SHIELDX- (twoja nazwa skryptu) / home / (twoja nazwa użytkownika) -force

Powyższe polecenie instalacji zrobi dla Ciebie:

  1. Zainstaluje zaszyfrowaną wersję twojego skryptu w katalogu / var / tmp / KINGLAZY / SHIELDX- (nazwa twojego skryptu).

  2. Umieści link do tego zaszyfrowanego skryptu w dowolnym katalogu, który określisz w miejsce / home / (twoja-nazwa użytkownika) - w ten sposób pozwala ci na łatwy dostęp do skryptu bez konieczności wpisywania ścieżki bezwzględnej.

  3. Zapewnia, ŻE JEDNA nie może modyfikować skryptu - wszelkie próby modyfikacji zaszyfrowanego skryptu sprawią, że nie będzie on działać ... dopóki próby te nie zostaną zatrzymane lub usunięte. Można go nawet skonfigurować tak, aby powiadamiał cię za każdym razem, gdy ktoś próbuje zrobić ze skryptem cokolwiek innego niż uruchomić go ... tj. Próby włamania lub modyfikacji.

  4. Zapewnia absolutnie, ŻE JEDEN nie może wykonać jego kopii. Nikt nie może skopiować twojego skryptu do ustronnej lokalizacji i spróbować go wkręcić, aby zobaczyć, jak to działa. Wszystkie kopie skryptu muszą być linkami do oryginalnej lokalizacji określonej podczas instalacji (krok 4).

UWAGA:

Nie sądzę, że to działa w przypadku interaktywnych skryptów, które pytają użytkownika o odpowiedź. Wartości powinny być zapisane na stałe w skrypcie. Szyfrowanie zapewnia, że ​​nikt tak naprawdę nie widzi tych wartości, więc nie musisz się tym martwić.

AncientMinds
źródło
0

Innym rozwiązaniem, bez względu na bezpieczeństwo (myślę też, że lepiej przechowywać poświadczenia w innym pliku lub bazie danych) jest zaszyfrowanie hasła za pomocą gpg i wstawienie go do skryptu.

Korzystam z pary kluczy gpg bez hasła, które trzymam w usb. (Uwaga: podczas eksportowania tej pary kluczy nie używaj opcji --armor, eksportuj je w formacie binarnym).

Najpierw zaszyfruj swoje hasło:

echo -n "pAssw0rd" | gpg --armor --no-default-keyring --keyring /media/usb/key.pub --recipient someone@mail.com --encrypt

Zostanie wydrukowane zaszyfrowane hasło gpg na standardowym wyjściu. Skopiuj całą wiadomość i dodaj to do skryptu:

password=$(gpg --batch --quiet --no-default-keyring --secret-keyring /media/usb/key.priv --decrypt <<EOF 
-----BEGIN PGP MESSAGE-----

hQEMA0CjbyauRLJ8AQgAkZT5gK8TrdH6cZEy+Ufl0PObGZJ1YEbshacZb88RlRB9
h2z+s/Bso5HQxNd5tzkwulvhmoGu6K6hpMXM3mbYl07jHF4qr+oWijDkdjHBVcn5
0mkpYO1riUf0HXIYnvCZq/4k/ajGZRm8EdDy2JIWuwiidQ18irp07UUNO+AB9mq8
5VXUjUN3tLTexg4sLZDKFYGRi4fyVrYKGsi0i5AEHKwn5SmTb3f1pa5yXbv68eYE
lCVfy51rBbG87UTycZ3gFQjf1UkNVbp0WV+RPEM9JR7dgR+9I8bKCuKLFLnGaqvc
beA3A6eMpzXQqsAg6GGo3PW6fMHqe1ZCvidi6e4a/dJDAbHq0XWp93qcwygnWeQW
Ozr1hr5mCa+QkUSymxiUrRncRhyqSP0ok5j4rjwSJu9vmHTEUapiyQMQaEIF2e2S
/NIWGg==
=uriR
-----END PGP MESSAGE-----
EOF)

W ten sposób tylko jeśli usb jest zamontowany w systemie, hasło można odszyfrować. Oczywiście możesz również zaimportować klucze do systemu (mniej bezpieczne lub w ogóle nie mieć bezpieczeństwa) lub możesz zabezpieczyć klucz prywatny hasłem (więc nie można go zautomatyzować).

Juanu
źródło
-2
#!/bin/bash
unset username
unset password
unset dbname
echo -n "username:"
read username
echo -n "dbname:"
read dbname
prompt="password:"

    while IFS= read -p "$prompt" -r -s -n 1 char
            do
                    if [[ $char == $'\0' ]]
                            then
                                    break
                    fi
                    prompt='*'
                    password+="$char"
            #       read -s -p "Enter Password: "  pswd
            #       echo -e "\nYour password is: " $pswd
            done
bieg
źródło
3
Wciszyłem twój kod, może mógłbyś wyjaśnić, co próbujesz zrobić?
Archemar
-6

Nie sądzę, że powinieneś kiedykolwiek przechowywać hasło. Nie mogę wymyślić żadnego dobrego powodu. Raczej powinieneś przechowywać solony hash tego hasła - jakiś ciąg, który jest wytwarzany niezawodnie przez jakąś funkcję, gdy oryginalne hasło jest przekazywane jako dane wejściowe, ale nigdy hasło .

mikeserv
źródło
5
Nie jestem pewien, jak to rozwiąże problem: a) możliwości połączenia się z usługą wymagającą hasła, oraz b) użytkowników, którzy mogą zobaczyć skrypt, a tym samym dowiedzieć się szczegółów uwierzytelniania, czy są to hasła czy nie
Jenny D
1
Twierdzisz, że znasz moją odpowiedź, zanim ją napisałem.
Jenny D.
1
Już napisałem odpowiedź. To, co próbowałem uzyskać od ciebie, było częściowo moją piątą kwestią - kiedy poświadczenia są przechowywane w pamięci, nie są one w pełni bezpieczne przed atakującym mającym dostęp do serwera. Również twoja zwięzła odpowiedź nie była zbyt pomocna, nawet jeśli nie była niepoprawna. Zastanawiam się nad tym, kiedy następnym razem ktoś narzeka, że ​​w ServerFault nie jesteśmy tak mili jak ludzie z Unix / Linux :-)
Jenny D
2
@JennyD - kiedy kredyt jest w pamięci - z pewnością nie musi tam pozostać - i to jest bardzo dobry powód, aby zamiast tego używać w / haszy. Mimo to chętnie będę reprezentować standardy uprzejmości społeczności jako ich przykład w ogóle - jestem bardzo dobrze znany z tej cechy.
mikeserv
4
Po waszej wielkiej dyskusji chciałbym tylko wspomnieć na wypadek nieporozumienia, że ​​to ja głosowałem, a nie Jenny. Powodem nie była opinia, czy warto używać certyfikatu i klucza prywatnego lub interaktywnie wprowadzonego hasła, czy robić to, czego chciał OP lub cokolwiek innego. Stało się tak, ponieważ obecna odpowiedź jest nieprawidłowa: przechowywanie solonego skrótu hasła jako poświadczenia klienta nie jest rzeczą: solone skróty to rzecz, którą trzymasz na końcu połączenia weryfikującego autoryzację, a nie strona, która to przesyła.
Celada