Fejezet 13. Biztonság

13.1. Mi az a “járóka” (sandbox)?
13.2. Mi az a biztonsági szint (securelevel)?
13.3. A BIND (named) különféle nagyobb sorszámú portokat használ. Miért?
13.4. A sendmail a szabványos 25-ös port mellett az 587-es portot használja! Miért?
13.5. Kié az a nullás felhasználói azonosítójú toor fiók? Betörtek a gépre?
13.6. A suidperl parancs miért nem működik rendesen?

13.1. Mi az a “járóka” (sandbox)?

A járóka alapvetően egy biztonsági szakkifejezés. Két dolgot jelenthet:

  • Egy virtuális falak között futó programot, melyeket azért emeltek a program köré, hogy a feltörését követően megakadályozzák a rendszer többi részének elérését.

    A program csak a falon belül “játszhat”. Ilyenkor semmilyen olyan kódot nem képes futtatni, amellyel át tudna lépni a falakon, így a használatához nem kell előzetesen átvizsgálni a forrásait ahhoz, hogy meg tudjuk győződni a biztonságosságáról.

    Ez a fal lehet például egy felhasználói azonosító. A security(7) és named(8) man oldalakon is ezt a definíciót találjuk meg.

    Vegyük például az ntalk szolgáltatást (lásd inetd(8)). Ezt a szolgáltatást korábban a root felhasználó azonosítójával futtatták, de manapság viszont már a tty felhasználóval fut. A tty felhasználó lényegében egy olyan járóka, amely az ntalk szolgáltatás feltörésekor nem engedi, hogy a rendszer többi részéhez is hozzá lehessen férni.

  • A valódi gépet utánzó rendszerben futó programot. Ez már egy sokkal kifinomultabb megoldás. Ha ilyenkor valakinek sikerül betörnie a programba, akkor könnyen azt hiheti, hogy sikerült a rendszer többi részét is elérnie, de valójában csak egy szimulált gépen van, és semmilyen valós adatot nem képes módosítani.

    Leggyakrabban ezt úgy szokták elérni, hogy egy könyvtárban létrehoznak egy szimulált környezetet, majd itt futtatják az adott programot a chroot(8) segítségével. (Ekkor az iménti könyvtár lesz a gyökérkönyvtár az adott folyamat számára, nem pedig a rendszer igazi gyökere.)

    Másik szintén gyakori megoldás a használt állományrendszerek írásvédett csatlakoztatása, amely felett aztán kialakítanak a program számára egy látszólag írható réteget. Ilyenkor a program teljesen úgy érzékeli, hogy képes a rendszerben elérhető állományokat módosítani, azonban egyedül csak saját maga látja ezeket, a rendszerben futó többi program viszont nem feltétlenül.

    Ezeket a járókákat általában úgy szokták felépíteni, hogy a felhasználók (vagy a támadók) számára teljesen észrevétlenek legyenek.

A UNIX® két alapvető járókát valósít meg. Az egyik a futó programok, a másik pedig a felhasználói azonosítók szintjén működik.

Futása közben minden UNIX program teljesen elszigetelt minden más UNIX programtól, így az egyik nem képes módosítani a másik memóriában tárolt adatait. A Windows®-tól eltérően, ahol ugyebár az egyik program könnyedén el tudja érni egy másik memóriaterületét, ezért a program nem képesek egymásban kárt tenni.

A UNIX alatt futó programok mindig egy adott felhasználóhoz tartoznak. Ha ez nem a root felhasználó, akkor azzal lényegében egy tűzfalat hozunk létre a különböző felhasználók által birtokolt folyamatok között. A felhasználók azonosítói emellett segítenek a lemezen tárolt adatokat is elszigetelni egymástól.

13.2. Mi az a biztonsági szint (securelevel)?

A biztonsági szintek egy rendszermagon belül megvalósított védelmi módszert képviselnek. A pozitív értékű biztonsági szintek esetén a rendszermag korlátoz bizonyos feladatokat, amelyeket ilyenkor még a rendszeradminisztrátor (vagyis a root felhasználó) sem képes elvégezni. Az írás pillanatában a biztonsági szintek, több más dolog mellett, a következők szabályozására alkalmasak:

  • a különböző állományjelzők, például az schg (a “system immutable” jelzés) törlése;

  • a rendszermag memóriájának elérése a /dev/mem és /dev/kmem eszközökön keresztül;

  • a rendszermag moduljainak betöltése;

  • a tűzfal szabályainak módosítása.

A jelenleg futó rendszer biztonsági szintjét a következő parancs segítségével lehet lekérdezni:

# sysctl kern.securelevel

A parancs eredménye az adott sysctl(8) változó (vagyis esetünkben a kern.securelevel) és annak értéke lesz, amely egy szám. Ez utóbbi adja meg a biztonsági szint aktuális értékét. Amennyiben ez pozitív (vagyis nullánál nagyobb), akkor érvényben vannak a biztonsági szintekhez kapcsolódó bizonyos korlátozások.

Egy működő rendszer biztonsági szintjét nem lehet csökkenteni, hiszen ezzel tulajdonképpen hatástalanná tennénk. Ha olyan feladatot akarunk végrehajtani, amely nem pozitív biztonsági szintet igényel (például az alaprendszer frissítése vagy a dátum átállítása), akkor ahhoz először módosítanunk kell az /etc/rc.conf állományt (lásd kern_securelevel és kern_securelevel_enable változók), majd újraindítani a rendszert.

A biztonsági szintekkel és rájuk vonatkozó információkkal kapcsolatban olvassuk el az init(8) man oldalt.

Figyelem: A biztonsági szintek nem feltétlenül jelentenek minden problémára tökéletes megoldást. Rentegeg ismert hátulütővel rendelkeznek, és gyakran a biztonság hamis érzetét keltik.

Ezzel kapcsolatban az egyik legnagyobb gond, hogy csak abban az esetben működik rendesen a rendszer, ha a rendszerindítás során a biztonsági szintek beállításáig minden állományt levédünk. Ha a támadó képes lefuttatni a saját programját még a biztonsági szint beállítása előtt (amely viszont elég későn történik meg, hiszen a rendszerindítás során számos olyan dolog feladat van, amely nem végezhető el magasabb biztonsági szinteken), akkor azzal az egész védelmi módszer hatástalanítható. Habár a rendszerindítás folyamán felhasznált állományok biztonságba helyezése technikailag egyáltalán nem lehetetlen, nehezebbé válik tőle a rendszer karbantartása, mivel ilyenkor az egész rendszert át kell állítanunk legalább egyfelhasználós módba és úgy módosítani a konfigurációs állományokat.

Ezt és az ehhez hasonló problémák gyakran felmerülnek a levelezési listákon, különösen a FreeBSD security levelezési lista archívumaiban. Ezen a funkción keresztül nézhetünk után a téma részletesebb tárgyalásának. Néhányan reménykednek, hogy a biztonsági szinteket hamarosan leváltja valami sokkal finomabb beállítási lehetőségekkel rendelkező megoldás, azonban a dolgok még eléggé homályosak ebből a szempontból.

Figyelmeztettünk mindenkit!

13.3. A BIND (named) különféle nagyobb sorszámú portokat használ. Miért?

A BIND a kimenő kérésekhez véletlenszerűen kiválaszt egy nagyobb sorszámú portot. A legújabb változataiban már minden egyes kéréshez külön véletlenszerűen keres új UDP portot. Ez bizonyos hálózati konfigurációk esetén problémákhoz vezethet, különösen olyankor, amikor a beérkező UDP csomagokat egy tűzfal megállítja. A tűzfalak által blokkolt porttartományok használatát az avoid-v4-udp-ports vagy az avoid-v6-udp-ports beállítással tilthatjuk le a program számára.

Figyelem: Ha ezt a portot (mint például az 53) az /etc/namedb/named.conf állományban a query-source vagy a query-source-v6 beállításokkal adjuk meg explicit módon, akkor a program nem fogja véletlenszerűen váltogatni a portokat. Határozottan javasoljuk, hogy ezekkel az opciókkal ne adjunk meg előre rögzített portokat.

Mindenesetre örülünk, hogy ezt is valaki megkérdezte! Hiába, nem árt néha nézegetni a sockstat(1) kimenetét és észrevenni benne néhány furcsaságot.

13.4. A sendmail a szabványos 25-ös port mellett az 587-es portot használja! Miért?

A sendmail újabb verzióiban felfedezhető levélküldési lehetőségek az 587-es portot használják. Jelenleg ezt még nem sokan használják ki, de növekszik a népszerűsége.

13.5. Kié az a nullás felhasználói azonosítójú toor fiók? Betörtek a gépre?

Ne aggódjunk! A toor egy “alternatív” rendszergazdai hozzáférés (a “toor” a “root” visszafelé). Korábban csak a bash(1) parancsértelmező telepítésekor jött létre, azonban manapság már alapértelmezés szerint létrejön. A nem szabványos parancsértelmezők számára találták ki, így nem a root alapértelmezett parancsértelmezőjét kell megváltoztatnunk. Ez különösen olyan parancsértelmezők esetén fontos, amelyek nem részei az alaprendszernek (például a portként vagy csomagként telepített parancsértelmezők esetén) és ezért a /usr/local/bin könyvtárba fognak kerülni. Ez a könyvtár alapértelmezés szerint azonban egy külön állományrendszeren található. Ha a root parancsértelmezője viszont a /usr/local/bin könyvtárban lenne, miközben a /usr (vagy bármelyik más állományrendszer, amely az imént említett könyvtárat tartalmazza) nem csatlakoztatható valamilyen oknál fogva, akkor a root nem lenne képes bejelentkezni és kijavítani a problémát. (Noha amikor újraindítjuk a rendszerünket egyfelhasználós módban, akkor a rendszer rá fog kérdezni, hogy melyik parancsértelmezőt akarjuk használni.)

Egyesek nem szabványos parancsértelmezőn keresztül a toor felhasználóval végzik el a root mindennapi teendőit, így a szabványos parancsértelmezőt csak a vészhelyzetekre tartogatják. Alapértelmezés szerint a toor felhasználóval nem tudunk bejelentkezni, mivel nincs jelszava, ezért ha használni akarjuk, akkor először jelentkezzünk be a root felhasználóval, majd állítsunk be neki egy jelszót.

13.6. A suidperl parancs miért nem működik rendesen?

Biztonsági okokból a suidperl parancs alapértelmezés szerint nem kerül telepítésre. Ha forrásból frissítjük rendszerünket és azt szeretnénk, hogy ennek során a suidperl is leforduljon, akkor a perl fordításának megkezdése előtt vegyük fel a ENABLE_SUIDPERL=true sort az /etc/make.conf állományba.

Ha kérdése van a FreeBSD-vel kapcsolatban, a következő címre írhat (angolul): <freebsd-questions@FreeBSD.org>.
Ha ezzel a dokumentummal kapcsolatban van kérdése, kérjük erre a címre írjon: <gabor@FreeBSD.org>.