A ZORP alapkoncepciója

A ZORP egy komponensalapú, objektumorientált, eseményvezérelt, moduláris proxy tűzfalrendszer, mely támogatja a protokollok egymásba ágyazását, a felhasználók protokollon kívüli (ún. outband) authentikációját, a több tűzfalon átmenő adatutak kialakítását, és számos protokoll részletes elemzését.

Alapvetően három, viszonylag független, részből épül fel:

A döntési mechanizmus a proxykkal szorosan együttműködik, ezért terveink szerint egy programban, közös címterületen kapnak helyet, viszont egymástól teljesen elkülönülnek. A kettő közti kapcsolódási felület pontosan definiált, azok betartásával mindkét oldal szabadon implementálható.

Az alkalmazásszintű proxyk C-ben íródnak, és mivel a kapcsolódási felületük előre definiált - szükség esetén - dinamikusan betölthetőek. A betöltött proxy modulok összekapcsolásáért, és az eldöntendő kérdéseknél a döntés meghozataláért a döntési mechanizmus felel.

A döntési mechanizmus egy objektumorientált, könnyen bővíthető, tanulható és beágyazható scriptnyelven, Pythonban íródott.

Komponensalapú

A komponensalapú fejlesztésnek számos előnye mutatkozott az elmúlt időben: újrafelhasználhatóság, kisebb kódméret, magasabb szintű nyelvek használatának lehetősége.

A ZORP tűzfalrendszer is komponenseket használ, bár nem függ a komponensalapú rendszerek hatalmas infrastruktúrájától, mint amilyen az OMG csoport CORBA-, vagy a Microsoft DCOM implementációja. Ezek tűzfalon való használhatósága biztonsági okok miatt megkérdőjelezhető.

A komponensek a ZORP-on belül tulajdonképpen hívási felületek, melyeket futásidőben betölthető pluginek implementálnak. Ezeket a felületeket a ZORP scriptnyelvén íródott program kapcsolja össze.

ZORP-ban 4 különböző komponens (interface) létezik:

A hálózatra való kapcsolódást, valamint a beérkező kapcsolatra a megfelelő proxy modul indítását a scriptnyelv végzi. A fenti felületekre a Pythonban segédosztályokat definiáltunk (ezek körét természetesen bővíthetjük), melyeket felparaméterezve elérhetjük a megfelelő funkcionalitást, így adminisztrátorként nem kell Pythonban programozási feladatokat elvégeznünk.

Objektumorientált

Bár a komponensekből való építkezés is alapvetően OOP szemléletű, az igazi erő a döntést végő rész, a policy leíró nyelvében rejlik. A konfigurációt, és döntési feltételeket Pythonban kell megfogalmazni, és lehetőségünk van olyan általános, paraméterezhető osztályok elkészítésére, melyeket a későbbiekben egyszerű származtatás útján felhasználhatunk.

Nem kell viszont programozni ahhoz, hogy a tűzfal policy-ját leírjuk. A leggyakrabban használt beállításoknak megfelelő osztályokat felparaméterezve, illetve a létrehozott példákat követve is eljuthatunk a szükséges működéshez. A lehetőségünk azonban megvan arra is, hogy ennél sokkal többet érjünk el.

A hozzáférésvezérlést, és a proxyk megfelelő láncba való kapcsolását python végzi, de miután a lánc kialakult, már lefordított natív kód fut. A hozzáférések engedélyezése/tiltása alapvetően a TCSEC B osztályában ill. A Common Criteria LSPP védelmi profiljában leírt MAC-et (mandatory access control) valósítja meg.

A Python, egyszerű szintaxisával könnyen tanulható, gazdag eszközkészletével gyosan lehet benne fejleszteni. Lehetőség van teljes proxyk pythonban való megvalósítására.

Eseményvezérelt

A natív kódú proxy elindulása után is van mód beavatkozni a működésbe mégpedig eseményekre adott válaszok segítségével. Amikor számottevő esemény keletkezik a protokoll futása során (felhasználói authentikáció, fájl letöltésének kérése, stb), erről a policy egy eseményt kap, melyben engedélyezheti, vagy megtilthatja az adott funkciót.

Nem vagyunk azonban igen/nem válaszokra korlátozva, Python változókon keresztül láthatjuk a proxy teljes állapotterét, és az exportált interface-n keresztül egyéb függvényhívásokkal is befolyásolhatjuk a proxy működését. Alapvetően 3 különböző mód áll rendelkezésünkre a C-ben írt proxy illetve a Pythonban írt policy közötti kommunikációra:

  1. Események (eventek)

    A proxy küldi a policy felé, általában paraméterekkel és valamilyen visszatérési értékkel rendelkezik, mely a proxy működését befolyásolja. Az event lekezelése a policy szempontjából egy osztály egy metódusának az implementálást jelenti.

  2. Attribútumok

    A policy felől a proxy egy osztály példányának tűnik, mely attribútumokkal rendelkezik. Lehetőségünk van ilyen attribútumokat beállítására, illetve az attribútumok értékének futásidejű kiszámítására.

  3. Callback-ek

    Az event alapvetően proxy->policy irányú kommunikáció, lehetőség van azonban policy->proxy irányú hívásokra is, ezeket hívjuk callbackeknek.

Óriási probléma lehet, hogy ha minden eseménynél explicit módon meg kell adnunk az eseményre adott válasz feltételeit. Képzeljünk el egy olyan tűzfalat, melyen 30 különböző proxy fut. Ha mind a 30 proxynak van 10 eseménye, melyet az alapértelmezéstől eltérő módon kell konfigurálnunk, akkor az 300 esemény leírását jelenti. Ráadásul ennek redundanciája is magas, hiszen a döntés alapja valószínűleg nagyrészt ugyanaz.

Pythonban alapvetően két mód is rendelkezésre áll a fenti probléma kezelésére:

A fenti probléma a döntési réteg és a proxyk közötti kommunikáció mennyiségét (azaz a teljesítményt) is erősen befolyásolja. Erre megoldás a normatív szabályozás lehetősége, mely alapján a proxy saját hatáskörben dönthet a policy által megszabott keretek között. Ezt a ZORP keretein belül attribútumok beállításával érhetjük el.

Moduláris

Az egyes protokollokhoz tartozó proxy egy shared objectben (a Windows-os DLL megfelelője) található, ahonnan a ZORP főprogram szükség esetén betölti. A kapcsolódási felületek lehetővé teszik, hogy egy proxy nem csak önállóan létezhet, hanem felsőbb szintű protokollok alprotokolljaihoz is köthető.

Ennek előnye leginkább olyan csatornákon jelentkezik, mely számos adatstreamet multiplexál. Ilyen például az ssh, ahol TCP forward segítségével számos, egymástól független protokoll zajlik. A modularitással megoldható az ssh portforwardban futó POP3 csatorna ellenőrzése is.

FIXME: abra

Ahogy az ábrán is láthatjuk, a fenti ismertetett 4 komponensből egy többszintű proxy szerkezet kialakítható, ahol a Stream jelképezhet hálózati kapcsolatot, illetve gépen belüli IPC mechanizmust is.