forked from georou/pihole-selinux
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pihole.te
executable file
·259 lines (197 loc) · 10.7 KB
/
pihole.te
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
policy_module(pihole, 1.0.0)
########################################
#
# Declarations
#
#permissive pihole_t;
#permissive pihole_cgi_script_t;
#######################################
#
# PiHole policy
#
type pihole_t;
type pihole_exec_t;
init_daemon_domain(pihole_t, pihole_exec_t)
init_nnp_daemon_domain(pihole_t) # Needed when using systemd hardening options in service file. NoNewPrivileges gets implied and so SELinux can't transition. https://danwalsh.livejournal.com/78312.html
role system_r types pihole_t;
type pihole_initrc_exec_t;
init_script_file(pihole_initrc_exec_t)
type pihole_data_t;
files_type(pihole_data_t)
type pihole_etc_t;
files_config_file(pihole_etc_t)
type pihole_tmp_t;
files_tmp_file(pihole_tmp_t)
type pihole_tmpfs_t;
files_tmpfs_file(pihole_tmpfs_t)
type pihole_unit_file_t;
systemd_unit_file(pihole_unit_file_t)
type pihole_var_log_t alias pihole_log_t;
logging_log_file(pihole_var_log_t)
type pihole_var_run_t;
files_pid_file(pihole_var_run_t)
type pihole_port_t;
corenet_port(pihole_port_t)
allow pihole_t self:capability { chown fowner ipc_lock net_bind_service sys_nice }; # chown & fowner tripped on prestart file. Source files search shows prestart and gravity.sh use it.
allow pihole_t self:process { execmem setsched };
allow pihole_t self:netlink_route_socket create_netlink_socket_perms;
allow pihole_t self:tcp_socket create_stream_socket_perms;
allow pihole_t self:udp_socket create_socket_perms;
allow pihole_t self:unix_dgram_socket create_socket_perms;
allow pihole_t pihole_cgi_rw_content_t:file map;
allow pihole_t pihole_cgi_script_exec_t:file getattr;
allow pihole_t pihole_port_t:tcp_socket name_bind;
#manage_dirs_pattern(pihole_t, pihole_data_t, pihole_data_t)
#manage_files_pattern(pihole_t, pihole_data_t, pihole_data_t)
allow pihole_t pihole_etc_t:file { map relabelfrom relabelto }; # Prestart script uses install to create empty files in /etc/pihole. Isn't needed if using touch instead.
manage_dirs_pattern(pihole_t, pihole_etc_t, pihole_etc_t)
manage_files_pattern(pihole_t, pihole_etc_t, pihole_etc_t)
files_etc_filetrans(pihole_t, pihole_etc_t, { dir file })
allow pihole_t pihole_tmp_t:file map;
manage_dirs_pattern(pihole_t, pihole_tmp_t, pihole_tmp_t)
manage_files_pattern(pihole_t, pihole_tmp_t, pihole_tmp_t)
files_tmp_filetrans(pihole_t, pihole_tmp_t, { dir file })
allow pihole_t pihole_tmpfs_t:file map;
manage_dirs_pattern(pihole_t, pihole_tmpfs_t, pihole_tmpfs_t)
manage_files_pattern(pihole_t, pihole_tmpfs_t, pihole_tmpfs_t)
fs_tmpfs_filetrans(pihole_t, pihole_tmpfs_t, { dir file })
allow pihole_t pihole_var_log_t:file { map relabelfrom relabelto }; # Prestart script uses install to create an empty file in /var/log/pihole
manage_dirs_pattern(pihole_t, pihole_var_log_t, pihole_var_log_t)
manage_files_pattern(pihole_t, pihole_var_log_t, pihole_var_log_t)
manage_lnk_files_pattern(pihole_t, pihole_var_log_t, pihole_var_log_t)
logging_log_filetrans(pihole_t, pihole_var_log_t, { dir file lnk_file })
allow pihole_t pihole_var_run_t:file { relabelfrom relabelto }; # Prestart script uses install to create an empty file in /run/pihole-FTL.pid
manage_dirs_pattern(pihole_t, pihole_var_run_t, pihole_var_run_t)
manage_files_pattern(pihole_t, pihole_var_run_t, pihole_var_run_t)
manage_sock_files_pattern(pihole_t, pihole_var_run_t, pihole_var_run_t)
files_pid_filetrans(pihole_t, pihole_var_run_t, { dir file })
manage_dirs_pattern(pihole_t, pihole_cgi_content_t, pihole_cgi_content_t)
manage_files_pattern(pihole_t, pihole_cgi_content_t, pihole_cgi_content_t)
manage_dirs_pattern(pihole_t, pihole_cgi_rw_content_t, pihole_cgi_rw_content_t)
manage_files_pattern(pihole_t, pihole_cgi_rw_content_t, pihole_cgi_rw_content_t)
# Added an entry as a DNS resolver in settings menu
allow pihole_t dnsmasq_etc_t:dir list_dir_perms;
dnsmasq_read_config(pihole_t)
dnsmasq_write_config(pihole_t)
#manage_dirs_pattern(pihole_t, dnsmasq_etc_t, dnsmasq_etc_t)
#manage_files_pattern(pihole_t, dnsmasq_etc_t, dnsmasq_etc_t)
kernel_read_network_state(pihole_t) # Pressed 'Restart DNS Resolver' in Settings menu
kernel_read_system_state(pihole_t)
auth_read_passwd_file(pihole_t)
corenet_tcp_bind_dns_port(pihole_t)
corenet_tcp_connect_dns_port(pihole_t) # Popped up randomly after leaving pihole running for weeks. 28/9/22. name_connect deny
corenet_udp_bind_dns_port(pihole_t)
corenet_udp_bind_dhcpd_port(pihole_t) # Using pihole as a DHCP service
corenet_tcp_bind_generic_node(pihole_t)
corenet_udp_bind_generic_node(pihole_t)
corecmd_exec_bin(pihole_t) # Using cut and install commands in scripts triggered this
corecmd_exec_shell(pihole_t)
fs_getattr_tmpfs(pihole_t)
fs_getattr_xattr_fs(pihole_t)
logging_manage_var_log_symlinks(pihole_t) # Only needed until v6 removes creating symlinks in pihole-FTL-prestart.sh
sysnet_read_config(pihole_t)
sysnet_exec_ifconfig(pihole_t)
selinux_validate_context(pihole_t) # Prestart script uses install to create empty files in /etc/pihole. Isn't needed if using touch instead.
seutil_read_file_contexts(pihole_t) # Prestart script uses install to create empty files in /etc/pihole. Isn't needed if using touch instead.
optional_policy(`
cron_system_entry(pihole_t, pihole_exec_t)
')
optional_policy(`
logrotate_domtrans(pihole_t)
')
# For use with systemd sandboxing PrivateTmp in unit file
optional_policy(`
systemd_private_tmp(pihole_tmp_t)
')
#######################################
#
# PiHole CGI script local policy
#
apache_content_template(pihole_cgi)
apache_content_alias_template(pihole_cgi, pihole_cgi)
type pihole_cgi_script_tmp_t;
files_tmp_file(pihole_cgi_script_tmp_t)
type pihole_cgi_script_tmpfs_t;
files_tmpfs_file(pihole_cgi_script_tmpfs_t)
# Clicked disable for X amount of time. Writes to /etc/pihole/setupVars.conf via addOrEditKeyValPair() in utils.sh
# Root needs to write to files but has no DAC permissions in /etc/pihole.
allow pihole_cgi_script_t self:capability { dac_read_search dac_override };
allow pihole_cgi_script_t self:capability { chown fowner fsetid kill net_admin setgid setuid sys_resource sys_ptrace };
allow pihole_cgi_script_t self:process { execmem setfscreate setpgid setrlimit };
allow pihole_cgi_script_t self:netlink_route_socket create_netlink_socket_perms;
allow pihole_cgi_script_t self:netlink_tcpdiag_socket r_netlink_socket_perms;
allow pihole_cgi_script_t self:tcp_socket create_socket_perms;
allow pihole_cgi_script_t self:udp_socket create_socket_perms;
allow pihole_cgi_script_t pihole_exec_t:file execmod; # Clicked Tools > Pi-hole diagnosis
allow pihole_cgi_script_t pihole_cgi_content_t:file map; # Clicked Enable/Disable on entry in Blacklist
manage_dirs_pattern(pihole_cgi_script_t, pihole_data_t, pihole_data_t)
manage_files_pattern(pihole_cgi_script_t, pihole_data_t, pihole_data_t)
manage_dirs_pattern(pihole_cgi_script_t, pihole_cgi_script_tmp_t, pihole_cgi_script_tmp_t)
manage_files_pattern(pihole_cgi_script_t, pihole_cgi_script_tmp_t, pihole_cgi_script_tmp_t)
#manage_lnk_files_pattern(pihole_cgi_script_t, pihole_cgi_script_tmp_t, pihole_cgi_script_tmp_t)
#manage_sock_files_pattern(pihole_cgi_script_t, pihole_cgi_script_tmp_t, pihole_cgi_script_tmp_t)
files_tmp_filetrans(pihole_cgi_script_t, pihole_cgi_script_tmp_t, { dir file })
allow pihole_cgi_script_t pihole_cgi_script_tmp_t:file map; # Clicked BackUp config
manage_dirs_pattern(pihole_cgi_script_t, pihole_cgi_script_tmpfs_t, pihole_cgi_script_tmpfs_t)
manage_files_pattern(pihole_cgi_script_t, pihole_cgi_script_tmpfs_t, pihole_cgi_script_tmpfs_t)
#manage_lnk_files_pattern(pihole_cgi_script_t, pihole_cgi_script_tmpfs_t, pihole_cgi_script_tmpfs_t)
#manage_sock_files_pattern(pihole_cgi_script_t, pihole_cgi_script_tmpfs_t, pihole_cgi_script_tmpfs_t)
fs_tmpfs_filetrans(pihole_cgi_script_t, pihole_cgi_script_tmpfs_t, { dir file lnk_file })
# Future consideration to create a shared domain to allow these. V6 Pi-hole will combine webserver into one so this requirement might change.
pihole_manage_config(pihole_cgi_script_t)
pihole_read_pid_files(pihole_cgi_script_t)
pihole_read_log(pihole_cgi_script_t)
pihole_signal(pihole_cgi_script_t)
files_etc_filetrans(pihole_cgi_script_t, pihole_etc_t, { dir file })
pihole_systemctl(pihole_cgi_script_t) # Pressed 'Restart DNS Resolver' in Settings menu
name_connect_pihole_port(pihole_cgi_script_t)
kernel_dgram_send(pihole_cgi_script_t)
kernel_read_net_sysctls(pihole_cgi_script_t) # Triggered from Fedora Server 38
kernel_read_network_state(pihole_cgi_script_t) # Triggered from Fedora Server 38
#kernel_request_load_module(pihole_cgi_script_t) # Popped up randomly when clicking Update Gravity. Loads=tcp-ulp-tls
# https://github.com/pi-hole/pi-hole/blob/8495565a6f065f372a8b0c64265ff3cdabe26d4b/advanced/Scripts/chronometer.sh#L205
dev_list_sysfs(pihole_cgi_script_t)
auth_use_pam(pihole_cgi_script_t) # For using sudo. Devs have chosen to add lighttpd to sudoers and elevate to run commands with the /usr/bin/pihole-FTL binary.
apache_rw_stream_sockets(pihole_cgi_script_t)
apache_write_log(pihole_cgi_script_t)
corenet_tcp_connect_http_port(pihole_cgi_script_t)
corenet_udp_bind_generic_node(pihole_cgi_script_t)
dnsmasq_read_config(pihole_cgi_script_t)
manage_dirs_pattern(pihole_cgi_script_t, dnsmasq_etc_t, dnsmasq_etc_t)
manage_files_pattern(pihole_cgi_script_t, dnsmasq_etc_t, dnsmasq_etc_t)
domain_read_all_domains_state(pihole_cgi_script_t)
files_list_tmp(pihole_cgi_script_t)
miscfiles_read_generic_certs(pihole_cgi_script_t)
init_read_utmp(pihole_cgi_script_t) # The use of sudo in /var/www/html/admin/scripts/pi-hole/php scripts triggers this
gen_require(`
type httpd_sys_content_t;
')
# Disable timer file created in /var/www/html/custom_disable_timer when using webGUI "Disable For x minutes"
filetrans_pattern(pihole_cgi_script_t, httpd_sys_content_t, pihole_cgi_rw_content_t, file, "custom_disable_timer")
# Fedora Server 38 with kernel 6.4.14 supports auditing io_uring
# avc: denied { sqpoll } for pid=6161 comm="dig" scontext=system_u:system_r:pihole_cgi_script_t:s0 tcontext=system_u:system_r:pihole_cgi_script_t:s0 tclass=io_uring permissive=0
# Triggered selecting Update Gravity in webUI
# https://www.paul-moore.com/blog/d/2022/01/linux_v516.html
optional_policy(`
gen_require(`
type pihole_cgi_script_t;
')
allow pihole_cgi_script_t self:io_uring sqpoll;
')
#################################
#
# Unconfined plugin local policy
#
optional_policy(`
type pihole_unconfined_t;
domain_type(pihole_unconfined_t)
type pihole_unconfined_exec_t;
application_executable_file(pihole_unconfined_exec_t)
domain_entry_file(pihole_unconfined_t, pihole_unconfined_exec_t)
role system_r types pihole_unconfined_t;
domtrans_pattern(pihole_t, pihole_unconfined_exec_t, pihole_unconfined_t)
domtrans_pattern(pihole_cgi_script_t, pihole_unconfined_exec_t, pihole_unconfined_t)
optional_policy(`
unconfined_domain(pihole_unconfined_t)
')
')