Jelszavak kezelése szkriptekben
2014. február 16.
by balo
Sokszor készítünk szkripteket azért, hogy a gyakran végzendő feladatokat automatizáljuk, ezekben néha különféle jelszavak bekérésére is szükség van. Lehetne, hogy egy konstansban elmentjük az érzékeny információt a szkriptben, de ez ugye amellett, hogy nem szép a verziókezelést is nehezíti. Ha a hívott alkalmazás támogatja a jelszófájlokat, akkor érdemes azt használni és a fájlt megfelelően titkosítani.
Ha az alkalmazás vagy erőforrás nem támogatja a jelszófájlokat (pl. jarsigner), akkor valamilyen módon be kell kérni és beadni parancssori paraméterben.
Példa egy konkrét utasításra, amikor a jelszó parancssori paraméterben szerepel:
$ jarsigner -keystore mystore.ks -storepass MySecretPass awesome.jar mycert
A fenti példa azért is nagyon rossz gyakorlat, mert a jelszó könnyen kiszivároghat a bash history-n vagy processzlistázó eszközökön (ps, top) keresztül.
A kulcsot érdemes úgy bekérni, hogy az ne írodjon ki a standard outputra gépeléskor ( echo ), erre mutatok megoldást bash-ben, Pythonban és Rubyban.
Bash
Használjuk a bash read parancsát a silent mode
és prompt
kapcsolókkal.
#!/bin/bash read -s -p "Store Password: " storepw jarsigner -keystore mystore.ks -storepass "$storepw" awesome.jar mycert
Python
from getpass import getpass pw = getpass("Password: ") print "Your password is", len(pw), "characters long"
Ruby
require "io/console" print "Password: " pw = STDIN.noecho(&:gets).chomp print "Your password is #{pw.length} characters long"
Kicsit mágikusnak tűnhet, de a 3. sor nem csinál mást, mint kikapcsolja az echo funkciót és beolvas egy sort, aminek a végéről levágja a sorvége karaktert. Csak ezért a funkcióért nem biztos, hogy megéri behúzni, de a highline gem is tudja ezt kicsit olvashatóbban.
Ha a szkriptünk egy integrált rendszer részeként fut (pl. cron), a linux terminál eszközeivel a fenti megközelítést bash-ban továbbra is használhatjuk. Egyszerűen mentsük el a jelszót egy védett fájlba és irányítsuk a szkriptünkbe.
$ myscript.sh < mypassw.txt
Ez a trükk az előzőekben ismertetett Python és Ruby kódokkal nem működik, de ilyen követelmény esetén találhatunk mindkét környezethez többféle megoldást (Tipp: Ruby ARGF)
Környezeti változók
Egy másik lehetőség a jelszavak kezelésére a környezeti változók használata, ezt a megközelítést használják az elterjedt PaaS felhőkben is (Heroku, OpenShift). A rendszer a jelszavakat és az olyan erőforrásokat, mint az adatbázis connection string, ebben a formában teszi elérhetővé, a kódban elég a változót megadni, így nem szükséges azt külön módosítani a fejlesztői és éles környezetben.
$ export MY_SECRET=myPassWord
Bash
#!/bin/bash jarsigner -keystore mystore.ks -storepass $MY_SECRET awesome.jar mycert
Python
import os pw = os.environ['MY_SECRET'] print "Your password is", len(pw), "characters long"
Ruby
pw = ENV['MY_SECRET'] print "Your password is #{pw.length} characters long"
A bash history miatt az export
még mindig aggályos, ezt áthidalhatjuk úgy, hogy a jelenlegi munkafolyamatban deaktiváljuk a történet mentését az unset HISTFILE
utasítással vagy egyszerűen elmentjük a változókat egy fájlba és futtatjuk.
$ cat myvars.sh #!/bin/bash export MY_KEY1=mysecret1 export MY_KEY2=mysecret2 $ source myvars.sh
A cikk szakmai felülvizsgálatáért és a javaslatokért köszönet night[w]-nak!
Happy scripting!