collected: SELinux-module example for mod_tile
For a project@work I had to setup an open street map server on Scientific Linux 6.1 (64 bit) for rendering the map of the BRD. For this I installed all needed components – and run into big trouble with mod_tile. This module is responsible for taking queries for map-tiles from the apache, forward it to the render daemon and deliver the images back. mod_tile and renderd communicate via an unix socket. And SELinux prevents mod_tile – that runs in the context of httpd – to access the socket. A short grep of the web gives a general answer: disable SELinux. Since SELinux was also a long time common problem to me (yes, I used echo „0“ > /selinux/enforce some times) I decided to accept the challenge… and after reading a lot I got a solution:=).
The following description should work in general if you have trouble with „access-denied-by-SELinux“-problems. The process is quite easy: use the output of the SELinux-audit-logging for create a probate module. Step by step:
0. be sure that SELinux is your problem. Maybe you got error messages like „permission denied“ when accessing files – and you already give full access via chmod/ (if the application gives no output use strace and grep for EACCES, use -e trace=… to filter systemcalls) and/or set the correct security context by chcon/restorecon. Have a look at the boolean shortcuts (getsebool -a | grep ) to check if there is an option to permit the needed action/access.
1. check SELinux-audit-log (/var/log/audit/audit.log) for entries that are related to your problem. If there is nothing enable audit by restart your machine with an additional kernel parameter audit=1. For mod_tile we captured 2 entries:
type=AVC msg=audit(1328183212.312:383): avc: denied { connectto } for pid=2314 comm="httpd" path="/var/run/renderd/renderd.sock" scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=unix_stream_socket
type=AVC msg=audit(1328182336.427:158): avc: denied { write } for pid=2017 comm="httpd" name="renderd.sock" dev=sda2 ino=2097727 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:var_run_t:s0 tclass=sock_file
Put the relevant entries into a separate file like audit.out.
2a.build module the long way – so you see what happens…
/*build the module description aka "the source" into apachemodtile.te*/
#>cat audit.out | audit2allow -m apachemodtile > apachemodtile.te
#>cat apachemodtile.te
module apachemodtile 1.0;
require {
type unconfined_t;
type var_run_t;
type httpd_t;
class sock_file write;
class unix_stream_socket connectto;
}
#============= httpd_t ==============
allow httpd_t unconfined_t:unix_stream_socket connectto;
allow httpd_t var_run_t:sock_file write;
/*build the binary module apachemodtile.mod*/
#>checkmodule -M -m -o apachemodtile.mod apachemodtile.te
/*build a SELinux policy module package in apachemodtile.pp*/
#>semodule_package -o apachemodtile.pp -m apachemodtile.mod
2b. use audit2module – does all of 2a in one step:
#>cat audit.out | audit2allow -M apachemodtile
3. install the module permanently:
/*modul goes (SL61) to /etc/selinux/targeted/modules/active/modules/apachemodtile.pp*/
#>semodule -i apachemodtile.pp
After this mod_tile was able to connect to the socket of the renderd. Quite easy 🙂