On 19/11/2024 21:09, Jeffrey Walton via selinux wrote:
Hi Everyone,
I need a little help in determining the proper SELinux context for data files served by Nginx. SELinux is in enforcing mode. The web server static pages are at /var/www/html (for historic reasons). The data files are in the filesystem in /var, but at /var/ftc-data. There's also a soft symlink at /var/www/html/ftc-data that points to /var/ftc-data.
/var/www/html is working as expected, but I am getting a 403 on the data files and the data file directory. I.e., I get a 403 on http://www.example.com/ftc-data, even though the directory is ugo+x.
The filesystem topology of interest is:
+------+ | /var | +------+ / \ / \ / \ www ftc-data / |+ file1.dat / |+ file2.dat / |+ file3.dat html |+ index.html |+ symlink to ftc-data/var/www and /var/www/html have system_u:object_r:httpd_sys_content_t:s0. The web server is serving the static html files Ok.
/var/ftc-data has unconfined_u:object_r:var_t:s0. I am not thrilled about unconfined_u, and I am pretty sure var_t should be httpd_sys_content_t.
The last wrinkle is, the data files get updated once a day using a systemd timer. So systemd needs write access to /var/ftc-data.
Would someone help me understand what SELinux context should be for /var/ftc-data, please?
Thanks in advance.
Sounds like you want to change the label of /var/ftc-data to httpd_sys_content_t. There's an example of how to use matchpathcon, semanage-fcontext and restorecon to achieve this here:
https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html-sin...
... and there's also http_selinux(8) which lists all the httpd-related types and booleans etc.
As for your timer unit, the service it launches likely already runs as unconfined_service_t, so SELinux won't prevent it from writing to /var/ftc-data. So you shouldn't need to do anything here unless you want to write a custom policy for the service.
However there's one thing that might trip you up: if you try to write your service as a shell script one-liner (e.g., ExecStart=/bin/bash -c '...') then you'll find it ends up running as initrc_t, which is confined & likely won't be allowed to mess with files labelled with http_sys_content_t.
# sesearch -T -s init_t -t shell_exec_t -c process type_transition init_t shell_exec_t:process initrc_t;
You must put your scripts into files labelled with bin_t or usr_t (the default for /usr/local/bin, /usr/local/libexec, etc) and that way they will end up running as unconfined_service_t.
# sesearch -T -s init_t -c process -D unconfined_service_t type_transition init_t bin_t:process unconfined_service_t; type_transition init_t usr_t:process unconfined_service_t;
Likely for any non-trivial service you're already doing that, but I thought I'd mention it anyway because this was a stumbling block for me while I was learning how to use SELinux properly.
The reason for this a bit obscure, and I don't really understand it; perhaps someone else reading this might be able to fill me in? I understand that back in the day, sysvinit (running as init_t) would need to ensure that its init scripts were run as initrc_t, hence the transition rule triggered by executing a file lablled shell_exec_t above.
However, init scripts are labelled with initrc_exec_t, and this rule exists:
# sesearch -T -s init_t -t initrc_exec_t -c process type_transition init_t initrc_exec_t:process initrc_t;
... so why is this rule not sufficient? What's the need for the rule that transitions to initrc_t when a file labelled with shell_exec_t is executed? Something I've always wondered but never asked about before. :)