Secmark

Viszonylag kevesen tudják, hogy az SELinux segítségével nem csak a helyi fájlrendszer tartalma címkézhető fel, hanem a hálózati forgalom megjelölésére is lehetőségünk van. A security mark (Secmark) használata révén könnyen megkülönböztethetjük az egyes hálózati forgalmainkat, sőt, a Netfilter segítségével egyszerűen és gyorsan szűrőszabályokat definiálhatunk az érintett csomagokra vonatkozóan.

A téma egyik szakértője, egyben az SELinux aktív fejlesztője Paul Moore, aki a HP berkein belül végzi jelentős munkáját. Jelen cikkünk Paul nemrég megjelent blogbejegyzésének fordítása.

A 2.6.18-as kernel bevezetésekor James Morris (a Red Hat SELinux fejlesztője) a jelenleg compat_net néven ismert SELinux ACL-rendszer lecserélésén dolgozott (ez a rendszer lehetővé tette, hogy a hálózati forgalomban használt csomagokat különféle attribútumok alapján szűrhessük) - ez lett a Secmark. A Secmark alapvetően az elavult compat_net két legfontosabb problémáját hivatott orvosolni: a korábbi infrastruktúra egyrészt nem annyira flexibilis, mint az iptables/Netfilter, másrészt - tervezési hibákből eredően - meglehetősen lassú. A csomagok felcímkézésére és az akkoriban használt, nem túl kifinomult csomagvizsgáló mechanizmus lecserélésére kézenfekvő megoldás volt a meglévő iptables infrastruktúra használata. A 2.6.29-es kernelverzió megjelenésével a compat_net funkciói elavultak és a 2.6.30-rc kernel patcheiben megjelentek azok a kódok, amelyek teljesen eltávolítják azokat.

A Secmark a Netfilteren keresztül rendel címkéket (security mark) bizonyos csomagokhoz, melyeket az SELinux a policyban meghatározott módon fog kezelni. Ezen eljárás segítségével a rendszeradminisztrátorok nem csak a már meglévő compat_net attribútumok (port, host) alapján szűrhetik a csomagokat, hanem az iptables/Netfilter összes paramétere használható lesz, többek között az állapottartó követés (stateful packet matching) is. James Morris remek cikkét (http://james-morris.livejournal.com/11010.html) ajánlom elsőként mindazok számára, akik a legtöbbet szeretnék kihozni a Secmark nyújtotta funkcionalitásból. Itt és most nem szeretném a fenti cikket egy az egyben lemásolni, inkább rövid útmutatót adnék a Secmark használatához.

Mielőtt hozzálátnánk, fontos, hogy megállapítsuk, rendszerünk támogatja-e a Secmark használatát; ezt a /selinux/compat_net fájl vizsgálatával végezhetjük el. Ha a fájl nem létezik a rendszerben, de az SELinux engedélyezve van, akkor vagy olyan nagyon régi kernelt használunk, amely nem támogatja a Secmarkot, vagy nagyon új kernelünk van, ami csak Secmark-kompatibilis. Ha látjuk a fájlt és a tartalma 0, akkor a Secmark funkciók engedélyezve vannak, ellenkező esetben compat_net módban vagyunk. Utóbbi esetben a Secmark aktiválása a fenti fájl tartalmának 0-ra való módosításával végezhető el, de előtte győződjünk meg arról, hogy az installált iptables támogatja a Secmark szabályok használatát.

# cat /selinux/compat_net
0

Első lépésként egy új SELinux címkét fogunk definiálni a felcímkézendő hálózati forgalom megjelölésére. Ekkor máris szembesülhetünk a régi és az új mechanizmus legnagyobb különbségével: a compat_net révén címkéket rendelünk hostokhoz és portokhoz, míg a Secmarkkal magukat a csomagokat címkézzük meg. Második feladatunk annak meghatározása, mely hálózati tulajdonságokat szeretnénk felhasználni a csomagok megjelölésekor. Mind a compat_net, mind a Secmark támogatja tetszőleges portok és hostok komcinációját, így szerencsére a már meglévő compat_net szabályokat is felhasználhatjuk Secmark környezetben. Az egyetlen különbség az, hogy a compat_net használatakor minden egyes port és host saját címkét kap, míg a Secmark használatakor port és host kombinációk esetén kerülnek a címkék kiosztásra. A következő példában a foo.lan hosthoz tartozó SSH csomagokat látjuk majd el foo_ssh_packet_t típussal és engedélyezzük ezeknek a helyi rendszerünkön sshd_t típusban futó SSH démonhoz való kapcsolódását. A gyakorlott olvasó észreveheti, hogy jelenleg MLS policyvel dolgozom, de a példák ugyanígy működőképesek lesznek az alapértelmezett targeted policy használatakor is.

Mivel saját SELinux labelt fogunk használni, elsőként egy SELinux policy modult készítünk, amelyben definiáljuk az új típust és engedélyezzük ezen típus hálózati kapcsolódását az SSH démonhoz:

# policy header
policy_module(secmark_example,0.1.0)
gen_require(`
        type sshd_t;
')

# az új típus
type foo_ssh_packet_t;

# engedélyezzük az sshd_t típus számára a fenti labellel rendelkező csomagok
# fogadását
allow sshd_t foo_ssh_packet_t:packet recv;

Fordítsuk le és töltsük be a modult az alábbi parancsokkal:

# cp /usr/share/selinux/devel/Makefile .
# make
Compiling mls secmark_example module
/usr/bin/checkmodule:  loading policy configuration from 
tmp/secmark_example.tmp
/usr/bin/checkmodule:  policy configuration loaded
/usr/bin/checkmodule:  writing binary representation (version 10) to tmp/secmark_example.mod
Creating mls secmark_example.pp policy package
rm tmp/secmark_example.mod tmp/secmark_example.mod.fc

# ls
Makefile            secmark_example.if  secmark_example.te
secmark_example.fc  secmark_example.pp  tmp
# semodule -i secmark_example.pp
# semodule -l | grep secmark_example
secmark_example 0.1.0

Következő és egyben utolsó lépésünk Secmark szabályok létrehozása az iptables segítségével:

# host foo.lan
foo.lan has address 192.168.0.16
# iptables -t mangle -A INPUT -p tcp --src 192.168.0.16 --dport 22
 -j SECMARK --selctx system_u:object_r:foo_ssh_packet_t:s0
# iptables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
SECMARK    tcp  --  foo.lan              anywhere            
tcp dpt:ssh SECMARK selctx system_u:object_r:foo_ssh_packet_t:s0

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

Mostantól a foo.lan gépről a 22-es TCP portra érkező csomagok foo_ssh_packet_t típusúak lesznek és az SELinux szabályai alapján csak az sshd_t típusban futó processzek tudják olvasni ezeket. A fent létrehozott policy modul eltávolításával ellenőrizhetük ezt: a foo.lan gépről érkező SSH forgalom megszakad és a logokban szép AVC denial üzeneteket találunk.

Végezetül ne felejtsük el megjegyezni, hogy a modern Linux kernelek használatakor kétféle SELinux security címkéket lehet egy csomaghoz hozzárendelni: azt, amelyről a fentiekben beszéltünk, valamint az ún. peer címkét. Mindkét típus használata eltérő működésű és célzatú: a Secmark címkékkel hálózati tulajdonságuk alapján jelölhetünk csomagokat, míg a peer címkékkel a küldő oldal csomagot generáló processzének SELinux biztonsági attribútumait küldhetjük el.

(A cikk eredetije itt olvasható.)

Hozzászólások

Nekem a gyári (2.6.27.24-170.2.68.fc10.i686) Fedora 10 kernelre azt mondja:

cat /selinux/compat_net
0

A 11-ben meg elvileg a -29 lesz az alapértelmezett. De lassan váltanak majd.

Azt nem értem, hogy van ugye gyári policy. Hogyha adok hozzá pluszban szabályt, akkor a gyári megmarad? Frissítés után is?

Nagyjából Fedora 8 és RHEL5 megjelenése óta moduláris policyt használunk. Ez azt jelenti, hogy lehetséges a core policy mellé olyan szabálymodulokat illeszteni, amelyek kiegészítik a gyári szabályokat. Természetesen a gyári megmarad, habár van lehetőség a gyári modulok frissítésére is.

Már régen esett szó az SELinuxról, de ami késik az nem múlik :)
Egy újabb remek cikkel bővült az SELinux témakör.

Webappz - http://webappz.hu/