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!