Dies ist eine alte Version des Dokuments!
Inhaltsverzeichnis
Wohin nur mit den Passwörtern in Windows und Linux Skripten? - Passwörter in Skripten verschlüsselt hinterlegen.
Das Problem:
In vielen Skripten rund um die tägliche Wartung unserer Systemumgebungen müssen Passwörter hinterlegt werden. Und nicht immer kann mit der Oracle Wallet oder SSL Zertifikaten bzw. Betriebssystem Rechten ganz auf Passwörter verzichtet werden.
Wie aber diese Passwörter so schützen, dass nicht jeder sofort die Passwörter auslesen und verwenden kann?
Wie die Skripte in einer Sourcecode Verwaltung so hinterlegen, dass dort sicher keine Passwörter mehr vorkommen? Wie Passwörter auf gehosteten Server Umgebungen hinterlegen und den Sicherheits-Regularien meines Unternehmens genügen?
Gerade in Umgebungen, die in die Jahre gekommen sind, wimmelt es nur so von Passwörtern. Jede Änderung bedingt meist umfangreiche Anpassungen an vielen Stellen. Werden Skripte kopiert und weitergegeben, besteht immer die Gefahr, dass ein Passwort in die falschen Hände gerät. Besonders in gehosteten Umgebungen, auf denen das Betriebssystem vom einen Hoster mit Root Rechten verwaltet wird, sollte sich der Kunde der Gefahr mit den offenen Passwörtern in Skripten sehr bewusst sein.
Diese Passwörter stellen trotz aller Bemühung auch heute noch eines der höchsten Sicherheitsrisiken für die meisten Systeme dar.
Um dieses Risiko zu bekämpfen, sollten die folgenden Vorgaben für alle Umgebungen gültig sein:
- Kein Passwort kommt im Skript vor, nur eine Variable wird verwendet, die mit dem Passwort gefüllt wird.
- Bei einer Passwort-Änderung muss das Skript nicht angepasst werden.
- Die Passwörter sind auf dem System verschlüsselt hinterlegt.
- Die verschlüsselten Passwörter können nur auf der Zielmaschine entschlüsselt gelesen werden.
- Alles was für die Umsetzung des Konzepts benötigt wird, muss auch in veralteten, bzw. gehosteten Umgebungen ohne besondere Systemrechte möglich sein.
Und nebenbei werden so ohne großen Aufwand meist schon die wichtigsten Sicherheits-Regeln eingehalten, ohne den Betrieb mit zu hohen Aufwänden zu belasten.
Vor welchen Szenarien schützt uns die Umsetzung des Konzepts?
- Skripte können nun problemlos per Mail / Git oder Web verteilt werden, keine Passwörter gehen aus Versehen verloren.
- Die verschlüsselten Passwörter sind keinem von Nutzen, der keinen Zugriff auf dem Zielserver hat.
- Unangenehme Gespräche mit dem Security Officer in der Kantine beim Mittagessen.
Vor welchen Szenarien schützt uns das NICHT?
- Vor den neugierigen Blicken der Kollegen mit Root Zugriff auf das System! Während das Skript läuft, ist im Speicher oder der /proc Umgebung das Passwort meist mit etwas Geschick auffindbar.
- Das Passwort lässt sich auf der Maschine per Skript auslesen, der Schlüssel für das Passwort lässt sich dort aber nie so verstecken, dass keiner den Schlüssel findet, das Skript benötigt diesen ja auch.
Denn wie bei jeder Verschlüsselung ist es eigentlich egal wie komplex oder sicher der Algorithmus ist, meist kann durch ein wenig Nachdenken und Ausprobieren der Schlüssel im System selber gefunden werden.
Den Schlüssel zu verstecken gelingt den wenigsten wirklich, denken wir nur an unsere Eltern, da liegt der Schlüssel auch immer hinten am Gartenzaun unter dem Blumentopf.
Werden diese einfachen Vorgaben konsequent umgesetzt, bedeutet dies für das Unternehmen meist schon eine dramatische Verbesserung der Sicherheitslage ohne großen Aufwand und viele Schwierigkeiten im Betrieb
Wie lässt sich das ganze nun aber unter Windows und Linux so bequem wie möglich umsetzen?
Unser Werkzeugkasten:
- Das Microsoft Credential Objects in der Windows PowerShell
- Verschlüsseltes Hinterlegen von Passwörtern auf Linux Systemen mit openssl
- Oracle Features wie der Oracle Wallet
Die ideale Lösung - Keine Passwörter verwenden .-)
Und nun zuerst die ideale Lösung für das Problem, wir verwenden gar keine Passwörter mehr.
D.h. in der Regel delegieren wir diese Aufgabe einfach an das Betriebssystem der Datenbank und überlassen diesem, bzw. dem Systemadministrator der Umgebung, die ganze Verantwortung, dass alles sicher betrieben wird.
Nachteil: Wer sich am System anmelden kann kommt nun ganz ohne Passwort aus.
Sehr einfach
Sehr einfach lässt sich das Umsetzen, wenn der OS User in der DBA Gruppe ist und alle Aufgaben mit dem SYS User durchgeführt werden können.
Geht aber nur, wenn der OS User in der DBA Gruppe ist und alles mit SYS auch durchgeführt werden kann/darf/will.
Etwas besser
Etwas sicherer ist es, „External authentification“ für die Datenbankzugänge einzusetzen.
Das heißt aber das auch etwas Technik dahinter funktionieren muss, oft schwer umzusetzen in gehostenen Umgebungen in denen jeder ja froh ist das es überhaupt noch irgendwie läuft.
Siehe ⇒ https://oracle-base.com/articles/misc/os-authentication
Oracle Wallet- Secure External Passwort Store
Sehr komfortabel ist die Oracle Wallet als Secure External Passwort Store Lösung, mehr dazu unter
⇒ Secure External Passwort Store
Passwörter unter Windows schützen
Unter Windows ist das verschlüsselte Hinterlegen der Passwörter so trivial, dass jeder der es nicht nützt, sich eigentlich fast grob fahrlässig verhält.
Das Erstellen eines Passwort-Containers inkl. des Aufrufes der Pflegeoberfläche sind im Prinzip nur 2 Zeilen Code.
# PWD $db_user = "system" $oracle_credential = "$scriptpath\ORACLE_CREDENTIAL.xml" # # To store the password we use the PSCredential object # if the serialized object of the password not exists # prompt the user to enter the password # if (!(test-path -path $oracle_credential)) { $user_credential=GET-CREDENTIAL -credential "$db_user" export-clixml -InputObject $user_credential -Path $oracle_credential } else { $user_credential=Import-Clixml -Path $oracle_credential } #get the clear type password $db_password=$user_credential.GetNetworkCredential().Password
Source Code ⇒ https://github.com/gpipperr/RedStack_Magazin_2018_encrypt_password/blob/master/ms_powershell/simpleExample.ps1
Ein praktisches Beispiel siehe hier ⇒ Oracle Apex Source Code automatisch exportieren und einchecken mit Git unter Windows mit der PowerShell
Passwort über GET-CREDENTIAL eingeben
GET-CREDENTIAL -credential "oralce"
Mit
$user_credential=GET-CREDENTIAL -credential "$db_user"
erzeugen wir uns in der Variablen user_credential ein Credential Object mit unsern Password. Der Schlüssel das ganzen ist die eindeutige ID des OS.
Serialisern des Objektes mit export-clixml
Um nun unseren Passwort Store auf der Platte abzulegen (wir wollen ja nicht bei jedem Skript Aufruf das Passwort neu eingeben), serialisieren wir das Objekt mit „export-clixml -InputObject $user_credential -Path $oracle_credential”. Es entsteht eine XML Datei mit dem Objekt in einer Art BASE64 Codierung.
export-clixml -InputObject $user_credential -Path $oracle_credential
Es entsteht eine XML Datei mit den Objekt in einer Art BASE64 Codierung.
Einlesen des Passworts aus dem Store
Beim nächsten Lauf ist das Passwort bereits hinterlegt, und das Objekt wird wieder in den Speicher geladen mit „$user_credential=Import-Clixml -Path $oracle_credential„”.
$user_credential=Import-Clixml -Path $oracle_credential" geladen.
Nun kann das Passwort im Script in Klarschrift ausgelesen werden über „$db_password=$user_credential.GetNetworkCredential().Password“.
$db_password=$user_credential.GetNetworkCredential().Password
Password Dialog in der Konsole starten
Wer lieber das Password über die Console setzt, kann mit dem Registry Eintrag (HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\ConsolePrompting) =$True den graphischen Dialog vermeiden.
Key setzen:
$key = “HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds” Set-ItemProperty $key ConsolePrompting True
Password in der Console hinterlegen:
Get-Credential cmdlet Get-Credential at command pipeline position 1 Supply values for the following parameters: Credential User: oracle Password for user oracle: ****** UserName Password -------- -------- oracle System.Security.SecureString
siehe auch:
Passwörter unter Linux sicher verwahren
Unter Linux wird das ganze deutlich schwieriger, gerade in gehosteten Umgebungen muss der Kunde mit dem Vorlieb nehmen, was der Hoster unter Sicherheit versteht, und das heißt meist, möglichst Kosten optimiert zu arbeiten.
SSH und damit openssl steht aber überwiegend zur Verfügung , bzw. spricht sehr wenig dagegen das nach installieren zu lassen.
D.h. wir haben mit openssl schon mal ein Werkzeug zur Verfügung, dass die kompliziertesten Verfahren beherrscht.
Jetzt müssen wir nur noch einen Schlüssel finden, der länger ist als das Passwort.
Der Schlüssel muss erfüllen:
- Muss auf jeden Server dieser Welt eindeutig sein
- Sollte länger als das Passwort sein um das Entschlüsseln ohne Schlüssel spannend zu machen
- Sollten so verborgen sein, dass es sich nicht so mit einem Blick erkenne lässt was wir uns da ausgesucht haben.
- Sollte sich mit Linux Board mitteln auslesen lassen (wie gesagt, alle neue Software ist dem Hoster ein Graus)
Solche Schlüssel können sein:
- WWN oder UUID einer Devices, dass sich nicht so schnell ändert
- MAC Adresse
- Prozessor ID
Meist verwende ich einfach die UUI von /dev/sda1 als Schlüssel oder die Seriennummer des OS unter HP UX. Hier ist der Phantasie überlassen durch Obfuscation das ganze etwas intransparenter zu erstellen.
Über Openssl wird der Password Store verschlüsselt:
openssl des3 -salt -in ${PWDFILE} -out ${PWDFILE}.des3 -pass pass:"${SYSTEMIDENTIFIER}"
Auch hier lässt sich dann mit ein paar Zeilen Code ein Ergebnis erzielen
# where to store the password store PWDFILE=${SCRIPTS_DIR}/password.conf export PWDFILE # get SYSTEMIDENTIFIER for the encryption of the password SYSTEMIDENTIFIER=`ls -l /dev/disk/by-uuid/ | awk '{ print $9 }' | tail -1` export SYSTEMIDENTIFIER ########################################################################### # Password file handling encryptPWDFile () { if [ -f "/usr/bin/openssl" ]; then openssl des3 -salt -in ${PWDFILE} -out ${PWDFILE}.des3 -pass pass:"${SYSTEMIDENTIFIER}" > /dev/null #debug printf "%s encrypt file :: \n%s to \n%s.des3 \n" "--" "${PWDFILE}" "${PWDFILE}" # remove the clear password file rm ${PWDFILE} else printError "Openssl not exits - password file will be not encrypted" fi } dencryptPWDFile() { if [ -f "/usr/bin/openssl" ]; then openssl des3 -d -salt -in ${PWDFILE}.des3 -out ${PWDFILE} -pass pass:"${SYSTEMIDENTIFIER}" > /dev/null #debug printf "%s decrypt file :: \n%s.des3 to \n%s \n" "--" "${PWDFILE}" "${PWDFILE}" else printError "Openssl not exits - password file will be not dencrypted" fi } ## Read encrypted password conf it exits in to memory ######################### # Check if the des3 file exits if [ -f "${PWDFILE}.des3" ]; then dencryptPWDFile # Source the pwd to a enviroment variable . ${PWDFILE} # remove the clear type file rm ${PWDFILE} else if [ -f "${PWDFILE}" ]; then . ${PWDFILE} encryptPWDFile rm ${PWDFILE} else printLine "no preconfiguration file =>password.conf<= found" echo "export REPOS_PASSWORD=" > ${PWDFILE} printLine "no preconfiguration password.conf found - edit the file =>password.conf<= and set password and start again" exit 1 fi fi
Sourcecode Beispiele
Beispiele im Detail auf https://github.com/gpipperr/RedStack_Magazin_2018_encrypt_password
Härten
Ist das nicht genug kann die Zielumgebung über Techniken wie einen Logon Trigger natürlich zusätzlich gehärtet werden.
Quellen
MS Windows Powershell:
Linux Openssl:
Siehe zum Thema bei mir auf der Seite: