Jelszavak kezelése szkriptekben

2014.02.16. | írta: 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!
Facebook Twitter Google+
comments powered by Disqus