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:
döntési mechanizmus
alkalmazásszintű gateway-ek, proxyk
authentikációt végző komponensek
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.
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:
ZorpListen
Adott hálózati porton figyelve kapcsolatokat fogad, majd erről értesíti a Python réteget. Az elfogadott kapcsolatot a továbbiakban egy ZorpStream példány jelképezi.
ZorpConnect
A megadott forráscímről kapcsolódást kezdeményez a szintén megadott célhoz.
ZorpStream
Egy I/O csatornát jelképez, melyből olvasni, írni lehet.
ZorpProxy
Egy protokoll specifikus proxy-t jelképező felület, mely biztosítja az átjárást a tűzfalon keresztül. A ZorpProxy kapcsolódási felületként Stream-eket használ, bármilyen full-duplex csatornán keresztül két proxy összekapcsolható. (például SSH proxyban beágyazott POP3 protokoll esetén, amikor a kliens és a szerver géppel az SSH kommunikál hálózati socketeken keresztül, a POP3 proxyval pedig az SSH proxy unix domain socketeken keresztül, miután a titkosítást a protokollból eltávolította)
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.
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:
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.
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.
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.
Pythonban alapvetően két mód is rendelkezésre áll a fenti probléma kezelésére:
származtatás: Pythonban gyakran használt policy leírása osztályokkal, és az abból való származtatás.
LSPP MAC policy implementációja: zónák, zónákhoz rendelt címkék, és az eseményekhez rendelt adatáramlás iránya alapján a döntés elvégezhető. A policy kialakításákor az egyetlen feladat a zónák kijelölése, és a címkék kiosztása.
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.