I want to use Pihole on Rocky Linux 9 and wrote a policy for it. During testing some files were put there (by the sed
command) which I now want to clean up. Upon trying to remove the files it looks as follows.
[root@pihole03 ~]# rm /etc/pihole/sed*
rm: remove regular file '/etc/pihole/sedGcMe6O'? y
rm: cannot remove '/etc/pihole/sedGcMe6O': Permission denied
rm: remove regular file '/etc/pihole/sedkOdgd5'? y
rm: cannot remove '/etc/pihole/sedkOdgd5': Permission denied
rm: remove regular file '/etc/pihole/sedTetiRf'? y
rm: cannot remove '/etc/pihole/sedTetiRf': Permission denied
The files themselves look as follows.
drwxrwxr-x. 3 pihole pihole system_u:object_r:pihole_t:s0 4096 May 31 08:19 .
[...]
-rw-r--r--. 1 root root system_u:object_r:pihole_etc_t:s0 398 May 30 20:40 sedGcMe6O
-rw-------. 1 root root system_u:object_r:pihole_etc_t:s0 399 May 30 21:47 sedkOdgd5
-rw-r--r--. 1 root root system_u:object_r:pihole_etc_t:s0 399 May 30 21:49 sedTetiRf
[...]
I do get denials for the removal action.
type=AVC msg=audit(1685513107.410:217): avc: denied { remove_name } for pid=17665 comm="rm" name="sedGcMe6O" dev="dm-0" ino=482814 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=system_u:object_r:pihole_t:s0 tclass=dir permissive=0
type=AVC msg=audit(1685513108.270:218): avc: denied { remove_name } for pid=17665 comm="rm" name="sedkOdgd5" dev="dm-0" ino=469130 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=system_u:object_r:pihole_t:s0 tclass=dir permissive=0
type=AVC msg=audit(1685513108.793:219): avc: denied { remove_name } for pid=17665 comm="rm" name="sedTetiRf" dev="dm-0" ino=480817 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=system_u:object_r:pihole_t:s0 tclass=dir permissive=0
It just doesn't seem the right way to add a rule like allow unconfined_t pihole_t:dir remove_name;
so I guess I am missing something essential when creating the type pihole_t
or similar.
For the sake of visibility and overview I'll post my in-place policy at the end.
Type enforcement
policy_module(pihole,1.0.0)
gen_require(`
type chkpwd_t;
type dnsmasq_etc_t;
type dns_port_t;
type fs_t;
type httpd_t;
type httpd_sys_rw_content_t;
type ifconfig_exec_t;
type init_t;
type initrc_var_run_t;
type kernel_t;
type net_conf_t;
type node_t;
type passwd_file_t;
type proc_net_t;
type proc_t;
type shadow_t;
type shell_exec_t;
type sssd_conf_t;
type sssd_var_lib_t;
type systemd_userdbd_runtime_t;
type tmpfs_t;
type unconfined_service_t;
type unconfined_t;
type unreserved_port_t;
type user_devpts_t;
type var_log_t;
type var_run_t;
')
type pihole_t;
type pihole_content_t;
type pihole_etc_t;
type pihole_exec_t;
type pihole_log_t;
type pihole_var_run_t;
init_daemon_domain(pihole_t, pihole_exec_t)
logging_log_file(pihole_log_t)
logging_search_logs(pihole_t)
logging_log_filetrans(pihole_t, pihole_log_t, file)
userdom_use_inherited_user_terminals(pihole_t)
files_pid_file(pihole_var_run_t)
files_search_pids(pihole_t)
files_pid_filetrans(pihole_t, pihole_var_run_t, file)
files_type(pihole_content_t)
files_type(pihole_etc_t)
allow httpd_t self:capability { audit_write net_admin };
allow httpd_t self:netlink_audit_socket { create nlmsg_relay read write };
allow httpd_t self:netlink_tcpdiag_socket { bind create getattr nlmsg_read read setopt write };
allow httpd_t dnsmasq_etc_t:dir { add_name remove_name write };
allow httpd_t dnsmasq_etc_t:file { append create getattr ioctl open read rename setattr unlink write };
allow httpd_t initrc_var_run_t:file { lock open read };
allow httpd_t kernel_t:dir { getattr search };
allow httpd_t kernel_t:file { read open };
allow httpd_t pihole_t:dir { add_name getattr ioctl open read remove_name search setattr write };
allow httpd_t pihole_t:file { create getattr lock open read rename setattr unlink write };
allow httpd_t pihole_t:lnk_file read;
allow httpd_t pihole_t:process signal;
allow httpd_t pihole_content_t:file { getattr lock open read rename setattr unlink write };
allow httpd_t pihole_etc_t:file { create getattr lock ioctl open read rename setattr unlink write };
allow httpd_t pihole_exec_t:file { execute execute_no_trans getattr ioctl map open read };
allow httpd_t pihole_log_t:file { open read };
allow httpd_t shadow_t:file { getattr read open };
allow httpd_t sssd_conf_t:file { getattr open read };
allow httpd_t var_run_t:file { getattr read open };
allow init_t pihole_t:dir mounton;
allow init_t pihole_exec_t:file { execute execute_no_trans map read open };
allow pihole_t self:capability { net_bind_service sys_nice };
allow pihole_t self:dir { add_name remove_name write };
allow pihole_t self:file { create setattr unlink };
allow pihole_t self:netlink_route_socket { bind create getattr getopt nlmsg_read read setopt write };
allow pihole_t self:process { execmem setsched };
allow pihole_t self:tcp_socket { accept bind create ioctl listen read setopt write };
allow pihole_t self:udp_socket { bind create connect getattr ioctl read setopt write };
allow pihole_t self:unix_dgram_socket { connect create };
allow pihole_t dnsmasq_etc_t:dir { getattr open read search };
allow pihole_t dnsmasq_etc_t:file { getattr open read };
allow pihole_t dns_port_t:tcp_socket name_bind;
allow pihole_t dns_port_t:udp_socket name_bind;
allow pihole_t fs_t:filesystem { associate getattr };
allow pihole_t httpd_sys_rw_content_t:dir { getattr search };
allow pihole_t httpd_sys_rw_content_t:file { getattr lock open read };
allow pihole_t ifconfig_exec_t:file { execute execute_no_trans getattr map open read };
allow pihole_t net_conf_t:file { getattr open read };
allow pihole_t node_t:tcp_socket node_bind;
allow pihole_t node_t:udp_socket node_bind;
allow pihole_t pihole_content_t:file { getattr lock open read setattr write };
allow pihole_t pihole_etc_t:file { getattr lock open read };
allow pihole_t pihole_log_t:dir search;
allow pihole_t pihole_log_t:file { open read };
allow pihole_t pihole_var_run_t:file manage_file_perms;
allow pihole_t proc_t:file { open read };
allow pihole_t proc_net_t:file { getattr open read };
allow pihole_t proc_net_t:lnk_file read;
allow pihole_t shell_exec_t:file { execute execute_no_trans map };
allow pihole_t tmpfs_t:file { create map open read unlink write };
allow pihole_t tmpfs_t:filesystem getattr;
allow pihole_t unreserved_port_t:tcp_socket name_bind;
allow pihole_t var_run_t:file { getattr open read write };
allow pihole_t var_run_t:sock_file create;
dontaudit pihole_t passwd_file_t:file read;
dontaudit pihole_t sssd_var_lib_t:dir search;
dontaudit pihole_t systemd_userdbd_runtime_t:dir read;
# necessary for the "pihole -up" updater
allow unconfined_t pihole_t:dir { add_name write };
allow unconfined_service_t pihole_t:dir setattr;
File context
/etc/pihole(/.*)? gen_context(system_u:object_r:pihole_etc_t,s0)
/etc/pihole/(pihole-FTL\.conf|setupVars\.conf) gen_context(system_u:object_r:pihole_etc_t,s0)
/etc/pihole/gravity(_old)?\.db(_temp(-journal)?)? gen_context(system_u:object_r:pihole_content_t,s0)
/etc/pihole/pihole-FTL\.db gen_context(system_u:object_r:pihole_content_t,s0)
/usr/bin/pihole-FTL gen_context(system_u:object_r:pihole_exec_t,s0)
/usr/local/bin/pihole gen_context(system_u:object_r:pihole_exec_t,s0)
/var/log/pihole(-FTL)?\.log gen_context(system_u:object_r:pihole_log_t,s0)
/var/log/pihole(/.*)? gen_context(system_u:object_r:pihole_log_t,s0)
This is still work in progress but still I'm happy for feedback regarding improvement also.
It just doesn't seem the right way to add a rule like allow unconfined_t pihole_t:dir remove_name;
I think it is.
Unless you are managing a system with confined users, selinux is here to prevent processes to access something they should not, not to prevent unconfined users access files.
chown
/ chmod
and setfacl
can be used for this.
Although, if it is a one time job, you could change the context of the files before removing them with chcon
.
Or, if it's not a one time removal, and you don't want to grants unconfined_t
permissions, you could write a script, run it with systemd service and timer, and allow init_t to remove files with pihole_t
context.