Chápu potřebu SELinuxu v Linuxu, jak je to bezpečnější a jak jednotlivé programy pak nedělají to, co nemají. Co mne ale hodně štve je fakt, když něco nefunguje už samo z instalace, např. CouchDB 1.6.1 z CentOSu 7. Jak tedy postupovat v takovém případě (pokud si tedy uvědomíme, že to bude nejspíš SELinux – na což ukazuje v tomto konkrétním případě OS Error 139 v JavaScriptové konzole a v /var/log/couchdb/couch.log).
SELinux politiky
Magický soubor, kam SELinux zapisuje svoje problémy se jmenuje /var/log/audit/audit.log. V tomto souboru zachytíme vzniklou chybu (záznam může se objevit až chvíli po jejím výskytu). Dobrým signálem jsou výskyty avc: denied řádků. Pomocí systémové utility audit2why (magicky součást balíčku policycoreutils-python, na což hned tak nikdo nepřijde) můžeme zjistit charakter problému. Buď chybí politika (náš případ) nebo chybí povolení nějaké SELinux proměnné (setsebool).
V případě politiky pak můžeme využít utilitu audit2allow na vygenerování modulu SELinux politik pro vyřešení uvedeného problému (např. z posledních 1 000 řádků logu):
1 2 3 |
tail -1000 /var/log/audit/audit.log \ | audit2allow -m myserver_couchdb \ >/root/myserver_couchdb.te |
Výraz myserver_couchdb označuje název modulu, který si přejeme vytvořit (doporučuji prefixovat jménem vašeho serveru nebo společnosti, aby se předešlo duplikování jména již používaného systémem – při duplikaci by došlo k nahrazení originálního modulu vaším a pouze by se problém absentujících politik přesunul jinam).
Soubor /root/myserver_couchdb.te je textový a dobře čitelný, obsahuje deklaraci a definici modulu pro vyřešení vašeho problému, např. u mne v případě CouchDB takto:
1 2 3 4 5 6 7 8 9 10 11 12 |
module myserver_couchdb 1.0; require { type couchdb_var_lib_t; type rabbitmq_beam_t; class process execmem; class dir create; } #============= rabbitmq_beam_t ============== allow rabbitmq_beam_t couchdb_var_lib_t:dir create; allow rabbitmq_beam_t self:process execmem; |
Je vhodné alespoň zběžně projít, že se názvy typů týkají služeb souvisejících s CouchDB – RabbitMQ je používán vnitřně. Všechny povolené politiky v poslední části modulu musí být např. popsány v části require. Často platí, že bude potřeba více oprávnění pro konkrétní class, typicky dir nebo file potřebují být založeny, otevřeny, musí z nich jít číst nebo do nich psát, nastavovat atributy apod. Plný rozsah lze buď odhadnout pomocí Google a konkrétní SELinux třídy (co obsahuje a typicky by měla obsahovat), nebo použijeme inkrementální zjišťování metodou povolit kus politiky, vyzkoušet a podle nového pádu nalézt další kousek skládanky.
Samotný myserver_couchdb.te je pak třeba převést do formátu používaného SELinuxem:
1 2 |
checkmodule -M -m -o /root/myserver_couchdb.mod /root/myserver_couchdb.te semodule_package -m /root/myserver_couchdb.mod -o /root/myserver_couchdb.pp |
a vzniklý soubor /root/myserver_couchdb.pp již můžeme nainstalovat a aktivovat v SELinuxu:
1 |
semodule -i /root/myserver_couchdb.pp |
V případě výskytu jakékoliv chyby nejčastě chybí deklarace použitého typu v require (po ručním zásahu) nebo pád zavaděče (přebíjíme svým module jiný existující modul, který definuje věci, které požadujeme v require).
setsebool
Některé problémy ale takto vytvořená politika nevyřeší – je třeba prozkoumat také proměnné setsebool. Nápomocný nám bude zejména příkaz
1 |
getsebool -a |
který zobrazí seznam existující proměnných a jejich aktuální nastavení.
Změny vyzkoušíme příkazem:
1 |
setsebool httpd_read_user_content on |
a pokud vše funguje, zaneseme změnu trvale pomocí
1 |
setsebool -P httpd_read_user_content on |
Hodně štěstí při vylaďování vašich politik a proměnných SELinuxu. Je vždy ale lepší nalézt řešení inkrementální politikou či proměnnou než vypnout celý SELinux.