Hogyan kezeljük HTTP hitelesítő jelszavainkat a htpasswd fájlban a htpasswd parancs segítségével

botond küldte be 2018. 11. 26., h – 14:03 időpontban

Tartalom

 

Bevezető

Weboldalunk könyvtárstruktúráját, alkönyvtárait könnyen jelszó védetté tehetjük a HTTP hitelesítés segítségével. Ennek működtetéséhez szükségünk van egy Apache HTTP szerverre, egy megfelelően beállított .htaccess fájlra és egy felhasználókat és jelszavaikat tároló .htpasswd fájlra.

Ebben a kis leírásban nézzük át, hogyan hozhatunk létre új felhasználókat, módosíthatjuk jelszavaikat vagy törölhetjük őket a .htpasswd fájlból az erre a célra szolgáló htpasswd parancs segítségével.

 

 

Szükséges programcsomag telepítése

Amennyiben még nem került fel a gépünkre az apache2-utils csomag, telepítsük az alábbi paranccsal:

sudo apt-get install apache2-utils

A programcsomag tartalmazza a leírás tárgyát képező htpasswd parancsot is.

 

Új felhasználó létrehozása

A HTTP hitelesítéssel az egyes web alkönyvtárakat külön kell levédenünk, ezért lépjünk be abba az alkönyvtárba, amit jelszóval szeretnénk védeni.

A könyvtárban futtassuk a következő parancsot, hogy létrehozhassunk egy "felhasznalo" nevű felhasználót:

htpasswd -c ./.htpasswd felhasznalo

A -c kapcsolóval jelezzük a htpasswd parancsnak, hogy új kimeneti fájlt kell létrehoznia. Ha nem létező kimeneti fájlt adunk meg, és a -c kapcsoló nélkül hívjuk meg, akkor a következő hibát adja:

htpasswd: cannot modify file ./.htpasswd; use '-c' to create it

(Ilyenkor a parancs futtatása után $? változóban 1-es hibakódot kapunk, így scriptekben is szépen le tudjuk kezelni.)

Ha pedig a -c kapcsolóval futtatjuk, akkor pedig mindenképpen új fájlt fog létrehozni. Így tehát a használat előtt meg kell győződni a kimeneti fájl létezéséről, nehogy felülírjunk egy korábbit, amiben esetleg már lehetnek felhasználók.

A parancs ezután bekéri az új jelszót, majd egy ismétlést is kér, hogy kiküszöbölhessük a félregépelést. Ezután sikeres létrehozás után a következőt adja:

Adding password for user felhasznalo

Tehát a htpasswd parancs használata roppant egyszerű. Ezután ha belenézünk a létrehozott .htpasswd fájlunkba, akkor ezt találjuk benne ("12345" jelszó megadásával):

felhasznalo:$apr1$o3UQr8fo$QGMuDGbSC0TPha6ud8KGW0

Most, hogy már létezik a fájlunk, a -c kapcsoló nélkül hozzuk létre a második felhasználónkat:

htpasswd ./.htpasswd felhasznalo2

Itt is ugyanúgy az "12345" jelszót adtam meg.

És most a .htpasswd fájlunk tartalma pedig:

felhasznalo:$apr1$o3UQr8fo$QGMuDGbSC0TPha6ud8KGW0
felhasznalo2:$apr1$2E9j3TXC$75bLkOfYpAIK4YJWBkbd60

Ami még itt szembetűnik, hogy a kódolási algoritmus alapból az MD5. Persze lehet választani többféle kódolási algoritmus közül is, de ez teljesen jó.

 

Jelszó módosítása

Jelszó módosításához csak újra kell futtatni a parancsot a meglévő .htpasswd fájlon egy meglévő felhasználónévvel és az új fájl létrehozási opció nélkül. Tehát ha módosítani szeretnénk például a felhasznalo2 jelszavát, akkor adjuk ki a következő parancsot:

htpasswd ./.htpasswd felhasznalo2

Ilyenkor a kimenet:

Updating password for user felhasznalo2

A fájl tartalma pedig:

felhasznalo:$apr1$o3UQr8fo$QGMuDGbSC0TPha6ud8KGW0
felhasznalo2:$apr1$CrIm8Kkj$BvmxRhvQp4A2m8e.3agFa0

Itt tehát látszik, hogy míg az első felhasználó rekordja érintetlenül maradt, a második módosult.

 

Felhasználó törlése

Felhasználót a htpasswd parancs -D kapcsolójával törölhetünk:

htpasswd -D ./.htpasswd felhasznalo2

(Ügyeljünk a kapcsolónál, hogy nagy D betű. A kicsi d kapcsoló másik titkosítást állít be, tehát más funkciója van)

A válasz kimenet:

Deleting password for user felhasznalo2

Fájl tartalma pedig:

felhasznalo:$apr1$o3UQr8fo$QGMuDGbSC0TPha6ud8KGW0

 

Jelszó ellenőrzése

Lehetőség van arra is, hogy ellenőrizzük a .htpasswd fájljainkban lévő felhasználók jelszavait. Ez pedig -v kapcsolóval történik:

htpasswd -v ./.htpasswd felhasznalo

Itt a megadott jelszófájlban ellenőrizzük a "felhasznalo" felhasználó jelszavát.

A parancs futtatásakor több lehetséges variáció van:

Megegyező jelszó

Ha minden stimmel (jelszó fájl, felhasználó létezik és a jelszó is jó), akkor ezt a kimenetet kapjuk:

Password for user felhasznalo correct.

$? hibakód: 0

Jelszófájl nem található

Ha nem létező fájlt adunk meg, például elgépeltük, akkor itt is rögtön hibaüzenet és leáll (itt most direkt elgépeltem):

htpasswd: cannot modify file ./.htpasswda; use '-c' to create it

$? hibakód: 1

Rossz jelszó

Ha megvan a jelszófájl és benne a megadott felhasználó is, de nem jó a jelszó, akkor pedig ezt adja:

password verification failed

$? hibakód: 3

Nem létező felhasználó

Ha pedig olyan felhasználóra próbálunk ráellenőrizni, ami nem létezik, akkor ez a kimenet:

User felhasznalo2 not found

$? hibakód: 6

 

Tehát itt ezek a lehetséges kimenetek és hibakódok.

A hibakódokat kiválóan felhasználhatjuk például az automatizáló scriptjeinkben.

 

HTTP felhasználók kezelésének automatizálása

A htpasswd parancs lehetőséget kínál a scriptekből történő automatizált felhasználásra is. Erre kétféle mód is van:

Parancssori mód

A parancssori módnál a -b kapcsoló használatával a parancs nem a billentyűzetről kéri be a jelszavakat, hanem paraméterként várja azt. Így egyetlen parancs futtatásával elvégezhető a kívánt felhasználói művelet a .htpasswd fájlban.

Például adjunk hozzá a korábbi jelszófájlunkhoz egy "autouser1" nevű felhasználót, aminek "123 45" jelszót adunk meg:

htpasswd -b ./.htpasswd autouser1 "123 45"

A parancs futása innentől ugyanaz, mint a begépelős módszernél. Így a kimenet és az eredmény is ugyanaz.

Idézőjelek használatára csak akkor van szükség, ha szóköz is szerepel a jelszóban. Azonban célszerű mindig használni amikor scriptekkel dolgozunk, mert sosem lehet előre tudni, hogy milyen jelszavak fognak átmenni a programunkon.
A jelszavak parancssorban történő használata egyáltalán nem biztonságos, ezért ezt a felhasználási módot inkább csak érdekességként kezeljük, automatizálási célokra helyette a csővezeték módot használjuk!

Csővezeték mód

Most így hirtelen ezt az elnevezést találtam ki erre a használati módra, melynek a lényege, hogy a parancs a -i kapcsoló hatására a szabványos bemenetről (stdin) várja a jelszót, megerősítés nélkül. Így tehát csővezetéken kaphatja a jelszót egy másik programtól. Ez a módszer biztonságos, mivel a jelszó sosem kerül ki a parancssorba. Ezt a kapcsolót az Apache 2.4.4 verziójától lehet használni.

Lássunk egy példát erre is:

echo "abc def" | htpasswd -i ./.htpasswd autouser2

Folytatva a korábbi jelszó fájlunkat, most egy echo parancs kimenetét adjuk a csővezetéken a htpasswd programnak, hogy az jelszóként használhassa fel a -i kapcsoló segítségével egy "autouser2" nevű felhasználó létrehozásához.

Az echo parancs helyén természetesen bármilyen program lehet, ami előállítja a szabványos kimeneten a megfelelő jelszót. Így akár egy MySQL adatbázisból dolgozó rendszertől is kaphatja a jelszavakat.

A felhasználó sikeres létrehozása után belenézünk a fájlba:

felhasznalo:$apr1$o3UQr8fo$QGMuDGbSC0TPha6ud8KGW0
autouser1:$apr1$xrVnm4S4$.Zkv28XTKb/Jp2tdtuSky.
autouser2:$apr1$Wbfjq/E1$95qLB8jbqemxGs5RCB5hV1

Bele is került az autouser2, most még tesztelhetjük is, hogy valóban jól működik-e szóközökkel rendelkező jelszavunk:

htpasswd -v -b ./.htpasswd autouser2 "abc def"

Itt most csak a teszt kedvéért használtam a -b kapcsolót, hogy egy parancssorban letudjuk a tesztet.

És a kimenet is megfelelő:

Password for user autouser2 correct.

 

 

Teszteljük a HTTP hitelesítést!

Ha már ennyit babráltunk a jelszófájl kezelésével, akkor próbáljuk is ki kreálmányunkat működés közben.

A jelszóval levédendő webkönyvtárban hozzunk létre egy .htaccess nevű fájlt, vagy ha már van ilyen, akkor nyissuk meg szerkesztésre.

Tegyük bele az alábbi pár sort (ha már van benne valami, akkor célszerű a legelejére tenni):

AuthName "Jelszo vedett terulet!"
AuthType Basic
AuthUserFile /abszolut/utvonal/a/jelszofajlhoz/.htpasswd
require valid-user

Majd behívva az oldalt a böngészőben, ahol elhelyeztük a .htaccess fájlt, szépen beadja a beléptető ablakot, ahol a fájlunkban lévő felhasználókkal és jelszavaikkal be tudunk lépni.

Persze kell valami célfájl is, amit be szeretnénk tölteni, mondjuk egy index.php vagy index.html, stb, hogy ne adjon 404-es hibát.

Itt még megjegyzendő, hogy a jelszó fájl bárhol lehet, csak a pontos abszolút címét adjuk meg (relatív útvonalakkal nem működik).
Ezzel az is kivitelezhető, hogy egy közös jelszófájban tároljuk az összes felhasználót, és a levédendő könyvtárakban lévő .htaccess fájlokban ugyanarra a .htpasswd fájlra hivatkozunk. Így központilag tudjuk kezelni HTTP felhasználóinkat.
Fontos!
Az első sorban, ahol megadjuk a beléptető ablak szövegét, valamint a felhasználóneveknél is, csak ASCII karaktereket használhatunk, így az ékezetes karaktereket rossz kódolással jeleníti meg az ablak tetején, a felhasználónevekkel pedig nem fog működni a beléptetés, így kerüljük őket. Erről itt találtam egy leírást.

Hibaelhárító

Ha ugyanazon a domain néven két külön védett könyvtárban ugyanazt a felhasználót adjuk meg, de eltérő jelszavakkal, akkor azok "összeakadnak", mivel nem alkönyvtárakra bontva jegyzi meg a hitelesítési adatokat a böngésző, hanem domain névhez társítja őket.

Példa:
Ha egy weboldal egyik alkönyvtárában van egy webstatisztika és egy másikban pedig egy phpMyAdmin rendszer, vagy bármi egyéb, és mondjuk mindkettő alkönyvtárban az admin felhasználót adjuk meg a HTTP hitelesítéshez, de más jelszavakat adunk meg, akkor a belépés ugyan működni fog először mindkettőnél, de miután beléptünk a második helyen, akkor a böngésző kidob az első helyről, mivel ott már nem egyezik meg korábban megadott jelszó.

Ilyenkor az Apache error.log fájljába a következő hasonló sor kerül:

[Sat Nov 10 00:18:30.658843 2018] [auth_basic:error] [pid 3679] [client xxx.xxx.xxx.xxx:31173] AH01617: user admin: authentication failure for "/": Password Mismatch, referer: https://www.domainnév/védett_könyvtár/

Mindezt csak azért írtam le, mert eléggé alattomos hiba, nehéz észrevenni és kibogozni. Pláne, ha a szerverünkön Fail2Ban is üzemel akkor az még ki is tilt minket, amennyiben bekapcsoltuk az Apache szűrőket. Nekem már sikerült átesnem ezen nagyjából ugyanígy.

Erre tehát az ezt megelőző  megoldás az, ha minden védett könyvtárban másik HTTP felhasználónevet használunk. Vagy ha mindenképpen ugyanazt szeretnénk használni, akkor a jelszavaknak is meg kell egyezniük, hogy ne dobáljon ki a böngésző.

Ha véletlenül kitiltanánk magunkat a HTTP hitelesítések próbálgatása során, akkor ebben a leírásban találhatunk rá gyógymódot.

 

Konklúzió

Ennyi lenne tehát a HTTP hitelesítéshez szükséges felhasználók és jelszavak kezelése a .htpasswd fájlokban. Ezzel a legegyszerűbb könyvtár védelemtől a komplex, adatbázisalapú, felhasználókezeléses, parancssori scriptekkel támogatott hitelesítési rendszerig bármit összehozhatunk, csak ügyeljünk a korlátozott karakterkódolási lehetőségekre, valamint hogy kerüljük a jelszavak parancssorban paraméterként történő továbbítását.

 

Kapcsolódó tartalom, hasznos linkek: