Jak bezpiecznie umieszczać swoje „sekrety” w skrypcie PowerShell? W jaki sposób używać loginów i haseł w naszych skryptach? Czy można bezpiecznie umieścić nasze hasła w skrypcie? Jak zarządzać swoim hasłami w skryptach PowerShell?
Microsoft przygotował doskonałe rozwiązanie które pozwola nam używać „sekretów” w skryptach, bezpiecznie się do nich odwoływać nie zależenie od tego gdzie są przechowywane. Poniżej znajdziecie przykład użycia Microsoft PowerShell SecretManagement Module.
Posiadamy skrypt w którym chcemy umieścić wrażliwe dane np login i hasło do dysku sieciowego. Pisałem już o tym wcześniej ale co gdy mamy takich poświadczeń kilka a skryptów kilkadziesiąt? Umieszczenie tych danych jawnie nigdy nie jest bezpiecznym rozwiązaniem, zwłaszcza gdy do środowiska gdzie je trzymamy ma dostęp kilka osób. Kolejnym problemem mogą być dziesiątki narzędzi i skryptów w których używamy kilku poświadczeń, id, subskrypcji czy tokenów API. Jeszcze większym problemem może być zmiana hasła użytego w kilku skryptach jednocześnie! Rozwiązaniem naszych problemów będzie modułu Microsoft PowerShell SecretManagement i odpowiedni moduł SecretStore.
Mechanizm działania przedstawia w uproszczeniu poniższy schemat.
Posiadamy skrypt w którym chcemy użyć zapisanych poświadczeń czyli naszego sekretu.
W skrypcie poleceniami odwołujemy się do modułu zarządzania naszym magazynem sekretów – tzw skarbcem.
Następnie kolejny moduł np Secret Store uzyskuje dostęp do przechowywanego w skarbcu sekretu. Modułów jest sporo i cały czas powstają nowe.
Zajmiemy się konkretnym przykładem: skrypt + moduł zarządzania + system plików
Zaczynamy od instalacji moduł Microsoft SecretManagemnet i moduł Microsoft SecretStore (ten ostatni przechowuje sekrety w zaszyfrowanym pliku w naszym profilu użytkownika).
Zacznijmy od instalacji modułów, instalujemy je dla wszystkich użytkowników:
Install-Module Microsoft.PowerShell.SecretManagement, Microsoft.PowerShell.SecretStore -Scope AllUsers
Mamy moduły ale jak ich używać? Sprawdzamy jakie polecenia pojawiły się w naszym systemie, używamy do tego Get-Command
Get-Command -Module Microsoft.PowerShell.SecretManagement
Get-Command -Module Microsoft.PowerShell.SecretStore
Mamy dodany moduł zarządzający oraz moduł który będzie obsługiwał nasz skarbiec (vault) do przechowywania sekretów. Nasz SecretStore akceptuje następujące typy danych jako sekrety:
- PSCredential
- HashTable
- SecureString
- String
- byte[]
w przykładzie skupimy się na klasie PSCredential (interesują nas jej dwie główne właściwości UserName i Password).
Mamy moduły, w kolejnym kroku musimy nasz skarbiec zarejestrować w systemie (tak naprawdę utworzyć), zrobimy to poleceniem Register-SecretVault (nadamy nazwę MySecretStore i ustawimy go domyślnym – dzięki temu nie będziemy musieli w niektórych poleceniach podawać jego nazwy):
Register-SecretVault -Name MySecretStore -ModuleName Microsoft.PowerShell.SecretStore -DefaultVault
Po rejestracji naszego skarbca warto sprawdzić czy jest dostępny w systemie, w tym celu użyjemy polecenia Get-SecretVault (skarbców możemy mieć kilka):
Get-SecretVault
Mamy już gdzie przechowywać sekrety więc dodajmy do niego nasz pierwszy sekret. Będzie to login i hasło dlatego, zrobimy to z użyciem polecenia Set-Secret, wcześniej jednak pobierzemy ten sekret do zmiennej, wykorzystamy Get-Credential
#pobieramy login i hasło do zmiennej
$Cred = Get-Credential
#dodajemy poświadczenia do pod określoną nazwą do naszego Vault
Set-Secret -Name AdminLoginNas -Secret $Cred -Vault MySecretStore
Uwaga!
Nasz skarbiec został przed chwilą zarejestrowany ale nie ustawiliśmy do niego jeszcze hasła – zatem przed dodaniem pierwszego sekretu zostaniemy poproszeni o utworzenie hasła:
tradycyjnie wprowadzamy nasze hasło dwukrotnie:
od tej pory nasz skarbiec jest chroniony hasłem i zawiera w sobie nasz pierwszy sekret (login i hasło).
Jak zauważyliście wiele razy powtarza się słowo NASZ – należy bowiem pamiętać, że skarbiec jest dostępny tylko dla konta użytkownika, z które go utworzono! Skarbiec będzie dostępny, dopóki skrypt lub sesja programu PowerShell będzie działać w kontekście danego konta użytkownika.
Do tworzenia naszego skarbca użyliśmy modułu który bazuje na systemie plików, zatem nasze sekrety znajdują się fizycznie w pliku i tej lokalizacji:
C:\Users\user\AppData\Local\Microsoft\PowerShell\secretmanagement\localstore
natomiast jego konfiguracja w postaci pliku JSON jest tutaj:
C:\Users\user\AppData\Local\Microsoft\PowerShell\secretmanagement
Mamy skarbiec, mamy w nim sekret w postaci loginu i hasła. Przed użyciem w skrypcie spróbujmy jeszcze te dane odczytać.
Nasz skarbiec ma określony czas odblokowania – o ile wykonaliśmy czynności dość szybko to przed kolejnym użyciem nie musimy go odblokować. W innym wypadku pomoże nam w tym polecenie Unlock-SecretStore
Unlock-SecretStore
po odblokowaniu sprawdźmy jakie mamy w nim sekrety używając Get-SecretInfo
Get-SecretInfo
zapytajmy więc o nasz sekret szczegółowo z użyciem polecenia Get-Secret
Get-Secret -Name AdminLoginNas
widzimy dwie główne właściwości PSCredential czyli UserName i Password, o ile login odczytujemy bez problemowo, o tyle hasło jest zaszyfrowane, spróbujmy zamienić SecureString na coś bardziej czytelnego używając polecenia ConvertFrom-SecureString:
$secret = (Get-Secret -Name AdminLoginNas)
$secret.UserName
$secret.Password | ConvertFrom-SecureString
Nie udało się password ma nadal formę która nie jest dla nas jawna, jeżeli naprawdę chcemy je odczytać musimy użyć klasy systemowej: System.Net.NetworkCredential
[System.Net.NetworkCredential]::new("", ($secret.Password)).Password
albo w ten sposób:
(Get-Secret -Name AdminLoginNas).GetNetworkCredential() | Select-Object *
Udało się! Możemy odczytać to co schowaliśmy w skarbcu.
Na szczęście w naszym skrypcie wystarczy sam obiekt typu PSCredential więc nie będziemy musieli odszyfrowywać hasła, wystarczy taki obiekt wywołać. Aby go wywołać musimy otworzyć skarbiec, pobrać sekret (np do zmiennej) i użyć go tak jak chcemy czyli np jako poświadczeń. Doskonały przykład znajdziecie poniżej.
$cred = (Get-Secret -Vault MySecretStore -Name AdminLoginNas)
Invoke-Command -ComputerName nas.sprawdzone.it -Credential $cred {Get-ChildItem c:\dane -Recurse}
O czym warto pamiętać używając PowerShell SecretManagement Module:
- skarbców (vault) możemy mieć kilka (w tym różnych typów) po prostu odwołujemy się do konkretnego i z niego wybieram sekret
- warto dodawać do naszych sekretów metadane np własne informacje czy opisy. Poniżej przykład dodający metadane w postaci zmiennej tablicowej z ważnością hasła:
$cred = Get-Credential
$metadata = @{ExpirationDate = "$((Get-Date).AddDays(180))"}
Set-Secret -Name DomainMaster -Secret $cred -Metadata $metadata
Get-SecretInfo -Name DomainMaster | Select-Object Name, Type, Metadata
- mając na uwadze ten warunek że skarbiec jest TYLKO dla jednego użytkownika (i jego kontekstu), wyłączenie wymagań dotyczących hasła do odblokowania może nie być złym rozwiązaniem. W ten sposób skrypty automatyzacji nie potrzebują dodatkowej logiki do obsługi hasła głównego. Jeżeli chcecie to zrobić to w pierwszej kolejności sprawdzamy konfiguracje naszego SecretStore z użyciem polecenia Get-SecretStoreConfiguration
Get-SecretStoreConfiguration
następnie zmieniamy jego konfiguracje z użyciem polecenia Set-SecretStoreConfiguration
Set-SecretStoreConfiguration -Authentication None -Interaction None
Jak widzicie rozwiązanie oparte o Microsoft PowerShell SecretManagement to sprawdzony sposób do zarządzania danymi których nie chcemy jawnie umieszczać w skryptach.
Opisałem przykład który dotycz poświadczeń jednak z powodzeniem używam skarbca do przechowywania kluczy API (string) czy innych niestandardowych loginów (HashTable). Mam kilkadziesiąt bardzo zbliżonych skryptów w których używam tych samych poświadczeń, a ich zmiana (np z powodu ważności hasła) to teraz czysta przyjemność – zmieniam sekret w jednym skarbcu z którego korzystają skrypty.
Microsoft SecretStore to tylko jeden z modułów, w galerii znajdziecie inne między innymi KeePass, Chromium cza Azure Key Vault. Pomysłów ich zastosowań jest tyle ile skryptów 🙂
Jeżeli mój wpis Ci się spodobał, pomógł w pracy? Chcesz mnie wspierać? Postaw kawę! To dzięki waszemu wsparciu nie ma reklam! Poniżej kod QR do płatności który jest jednocześnie linkiem do PayPal możesz też wpłacić BLIK z użyciem Przelewy24.pl