|
# vim: sw=4:ts=4:et
|
|
#
|
|
# Copyright 2013 Red Hat, Inc.
|
|
#
|
|
# This program and entire repository is free software: you can redistribute it
|
|
# and/or modify it under the terms of the GNU General Public License as
|
|
# published by the Free Software Foundation, either version 3 of the License,
|
|
# or any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with
|
|
# this program. If not, see http://www.gnu.org/licenses/.
|
|
#
|
|
|
|
policy_module(foreman, @@VERSION@@)
|
|
|
|
#######################################
|
|
#
|
|
# Declarations
|
|
#
|
|
|
|
## <desc>
|
|
## <p>
|
|
## Determine whether Ruby on Rails can listen/bind any port.
|
|
## </p>
|
|
## </desc>
|
|
gen_tunable(foreman_rails_can_listen_any, false)
|
|
|
|
## <desc>
|
|
## <p>
|
|
## Determine whether Ruby on Rails can connect to LDAP ports.
|
|
## </p>
|
|
## </desc>
|
|
gen_tunable(foreman_rails_can_connect_ldap, true)
|
|
|
|
## <desc>
|
|
## <p>
|
|
## Determine whether Ruby on Rails can connect to TCP ports
|
|
## other than specified in the policy.
|
|
## </p>
|
|
## </desc>
|
|
gen_tunable(foreman_rails_can_connect_all, false)
|
|
|
|
## <desc>
|
|
## <p>
|
|
## Determine whether websockify can connect to all TCP ports.
|
|
## </p>
|
|
## </desc>
|
|
gen_tunable(websockify_can_connect_all, false)
|
|
|
|
## <desc>
|
|
## <p>
|
|
## Determine whether Ruby on Rails can connect to OpenStack
|
|
## </p>
|
|
## </desc>
|
|
gen_tunable(foreman_rails_can_connect_openstack, true)
|
|
|
|
## <desc>
|
|
## <p>
|
|
## Determine whether Ruby on Rails can execute ssh (needed for qemu+ssh libvirt connection).
|
|
## </p>
|
|
## </desc>
|
|
gen_tunable(foreman_rails_can_spawn_ssh, true)
|
|
|
|
## <desc>
|
|
## <p>
|
|
## Determine whether Ruby on Rails can connect to http_cache_port_t and squid_port_t.
|
|
## </p>
|
|
## </desc>
|
|
gen_tunable(foreman_rails_can_connect_http_proxy, true)
|
|
|
|
## <desc>
|
|
## <p>
|
|
## Determine whether Ruby on Rails can connect to local or remote libvirt.
|
|
## </p>
|
|
## </desc>
|
|
gen_tunable(foreman_rails_can_connect_libvirt, true)
|
|
|
|
## <desc>
|
|
## <p>
|
|
## Determine whether Ruby on Rails can connect to remote SMTP services
|
|
## </p>
|
|
## </desc>
|
|
gen_tunable(foreman_rails_can_connect_smtp, true)
|
|
|
|
###############
|
|
#
|
|
# Types
|
|
#
|
|
|
|
type foreman_rails_t;
|
|
type foreman_rails_exec_t;
|
|
|
|
type foreman_rails_unit_file_t;
|
|
systemd_unit_file(foreman_rails_unit_file_t)
|
|
|
|
require{
|
|
type etc_t;
|
|
}
|
|
typealias etc_t alias foreman_config_t;
|
|
|
|
type foreman_db_t;
|
|
files_type(foreman_db_t)
|
|
|
|
type foreman_enc_t;
|
|
files_config_file(foreman_enc_t)
|
|
|
|
type foreman_lib_t;
|
|
files_type(foreman_lib_t)
|
|
|
|
type foreman_log_t;
|
|
logging_log_file(foreman_log_t)
|
|
|
|
type foreman_var_run_t;
|
|
files_pid_file(foreman_var_run_t)
|
|
|
|
type foreman_proxy_port_t;
|
|
corenet_port(foreman_proxy_port_t)
|
|
|
|
type foreman_osapi_compute_port_t;
|
|
corenet_port(foreman_osapi_compute_port_t)
|
|
|
|
require{
|
|
type bin_t;
|
|
type httpd_t;
|
|
type websm_port_t;
|
|
type cockpit_ws_t;
|
|
type cockpit_session_t;
|
|
type cockpit_session_exec_t;
|
|
type unconfined_service_t;
|
|
type http_cache_port_t;
|
|
type squid_port_t;
|
|
}
|
|
|
|
######################
|
|
#
|
|
# Ruby on Rails policy
|
|
#
|
|
|
|
# Service transition
|
|
init_daemon_domain(foreman_rails_t, foreman_rails_exec_t)
|
|
|
|
# Temporary rule to prevent dontaudit denial during start caused
|
|
# by socket activation:
|
|
# https://community.theforeman.org/t/foreman-nightly-rpm-pipeline-611-failed/19179
|
|
allow foreman_rails_t unconfined_service_t:tcp_socket { connected_stream_socket_perms };
|
|
|
|
# Socket and PID files transition
|
|
files_pid_filetrans(foreman_rails_t, foreman_var_run_t, { file dir sock_file })
|
|
|
|
# Generic domain rules
|
|
kerberos_read_config(foreman_rails_t)
|
|
auth_read_passwd(foreman_rails_t)
|
|
dev_list_sysfs(foreman_rails_t)
|
|
dev_read_sysfs(foreman_rails_t)
|
|
hostname_exec(foreman_rails_t)
|
|
optional_policy(`
|
|
ipa_filetrans_named_content(foreman_rails_t)
|
|
')
|
|
kernel_read_network_state(foreman_rails_t)
|
|
kernel_read_system_state(foreman_rails_t)
|
|
sysnet_read_config(foreman_rails_t)
|
|
|
|
# Certificates (Foreman uses puppet certificates as well)
|
|
miscfiles_read_certs(foreman_rails_t)
|
|
optional_policy(`
|
|
puppet_read_config(foreman_rails_t)
|
|
')
|
|
|
|
# It is not possible to do transition into SCL application
|
|
# without calling a shell: https://github.com/sclorg/scl-utils/issues/31
|
|
corecmd_exec_shell(foreman_rails_t)
|
|
corecmd_exec_ls(foreman_rails_t)
|
|
# The following is needed for "scl enable" which creates temporary
|
|
# shell script /var/tmp/xxxxxxx and a subprocess.
|
|
files_manage_generic_tmp_files(foreman_rails_t)
|
|
files_manage_generic_tmp_dirs(foreman_rails_t)
|
|
|
|
# General files read and write
|
|
admin_pattern(foreman_rails_t, foreman_lib_t, foreman_lib_t)
|
|
admin_pattern(foreman_rails_t, foreman_var_run_t, foreman_var_run_t)
|
|
|
|
# Gettext support
|
|
miscfiles_read_localization(foreman_rails_t)
|
|
|
|
# The read the code (and potentially modules) from /usr/share.
|
|
files_read_usr_files(foreman_rails_t)
|
|
|
|
# Allow Foreman to access log files (but not delete or truncate them). Ideally
|
|
# only create and append should be allowed, however rake tasks also fall into
|
|
# the same domain and those tasks often simply writes to log files.
|
|
optional_policy(`
|
|
logging_list_logs(foreman_rails_t)
|
|
')
|
|
write_files_pattern(foreman_rails_t, foreman_log_t, foreman_log_t)
|
|
allow foreman_rails_t foreman_log_t:dir { create_file_perms append_file_perms list_dir_perms search_dir_perms };
|
|
allow foreman_rails_t foreman_log_t:file { create_file_perms append_file_perms };
|
|
|
|
# Allow "logger" command for debugging
|
|
kernel_dgram_send(foreman_rails_t)
|
|
optional_policy(`
|
|
logging_create_devlog_dev(foreman_rails_t)
|
|
')
|
|
|
|
# Allow Foreman to connect to the syslog socket
|
|
logging_stream_connect_syslog(foreman_rails_t)
|
|
|
|
# Systemd socket activation (Puma called with LISTEN_FDS environmental variable)
|
|
allow foreman_rails_t self:netlink_route_socket { all_netlink_route_socket_perms };
|
|
allow foreman_rails_t self:tcp_socket { all_tcp_socket_perms };
|
|
allow foreman_rails_t self:udp_socket { all_udp_socket_perms };
|
|
allow foreman_rails_t self:unix_dgram_socket { all_unix_dgram_socket_perms };
|
|
corenet_tcp_bind_generic_node(foreman_rails_t)
|
|
|
|
# Listening for HTTP communication on port 3000
|
|
corenet_tcp_bind_ntop_port(foreman_rails_t)
|
|
corenet_tcp_connect_ntop_port(foreman_rails_t)
|
|
|
|
# Listening for HTTP communication on HTTP(s) port range
|
|
corenet_tcp_bind_http_port(foreman_rails_t)
|
|
corenet_tcp_connect_http_port(foreman_rails_t)
|
|
|
|
# Listening for HTTP communication on any port
|
|
tunable_policy(`foreman_rails_can_listen_any', `
|
|
corenet_tcp_bind_generic_node(foreman_rails_t)
|
|
')
|
|
|
|
# Allow the app server to preload itself
|
|
corenet_tcp_connect_http_port(foreman_rails_t)
|
|
|
|
# Allow access to pseudo terminal devices to connect to local virt.
|
|
term_search_ptys(foreman_rails_t)
|
|
|
|
# Connecting to hosts and guests
|
|
corenet_tcp_connect_virt_port(foreman_rails_t)
|
|
corenet_tcp_connect_ssh_port(foreman_rails_t)
|
|
|
|
# Allow Foreman to do DNS queries via Ruby stdlib net package
|
|
# https://projects.theforeman.org/issues/8030
|
|
corenet_udp_bind_generic_port(foreman_rails_t)
|
|
corenet_udp_bind_generic_node(foreman_rails_t)
|
|
|
|
# Allow to perform TCP DNS search when response is too big (BZ#1877443)
|
|
# The following macro incudes corenet_tcp_connect_dns_port(foreman_rails_t)
|
|
sysnet_dns_name_resolve(foreman_rails_t)
|
|
|
|
# Allow reading /etc/resolv.conf when using systemd-resolved
|
|
allow foreman_rails_t net_conf_t:lnk_file read;
|
|
|
|
# rubygem FFI is used in foreman-tasks (BZ#1670109 / RM#26951)
|
|
allow foreman_rails_t self:process execmem;
|
|
|
|
# Connecting to remote Cockpit instance (via Remote Execution)
|
|
# or to Foreman Proxy on port 9090 (Katello)
|
|
allow foreman_rails_t websm_port_t:tcp_socket name_connect;
|
|
|
|
# Connecting to Foreman Proxy on a defined port
|
|
allow foreman_rails_t foreman_proxy_port_t:tcp_socket name_connect;
|
|
|
|
# Connecting to HTTP(s) proxy
|
|
tunable_policy(`foreman_rails_can_connect_http_proxy',`
|
|
allow foreman_rails_t http_cache_port_t:tcp_socket name_connect;
|
|
allow foreman_rails_t squid_port_t:tcp_socket name_connect;
|
|
')
|
|
|
|
# Connecting to PostgreSQL
|
|
corenet_tcp_connect_postgresql_port(foreman_rails_t)
|
|
optional_policy(`
|
|
postgresql_stream_connect(foreman_rails_t)
|
|
')
|
|
|
|
# Connecting to Redis
|
|
corenet_tcp_connect_redis_port(foreman_rails_t)
|
|
|
|
# Sending of email reports via sendmail
|
|
optional_policy(`
|
|
mta_send_mail(foreman_rails_t)
|
|
')
|
|
|
|
# Sending of email reports via SMTP directly
|
|
tunable_policy(`foreman_rails_can_connect_smtp',`
|
|
corenet_tcp_connect_smtp_port(foreman_rails_t)
|
|
')
|
|
|
|
# Connecting to LDAP
|
|
optional_policy(`
|
|
tunable_policy(`foreman_rails_can_connect_ldap', `
|
|
corenet_tcp_connect_ldap_port(foreman_rails_t)
|
|
')
|
|
')
|
|
|
|
# General "connect everywhere" rule (disabled by default)
|
|
tunable_policy(`foreman_rails_can_connect_all',`
|
|
corenet_tcp_connect_all_ports(foreman_rails_t)
|
|
')
|
|
|
|
# Allow executing rpm in the About page for diagnostics
|
|
rpm_exec(foreman_rails_t)
|
|
rpm_read_db(foreman_rails_t)
|
|
|
|
######################################
|
|
#
|
|
# Logrotate and cron
|
|
#
|
|
|
|
gen_require(`
|
|
type logrotate_t;
|
|
type system_cronjob_tmp_t;
|
|
')
|
|
|
|
# Allow sending signals in logrotate scripts
|
|
allow logrotate_t foreman_rails_unit_file_t:file read_file_perms;
|
|
allow logrotate_t foreman_rails_unit_file_t:service manage_service_perms;
|
|
|
|
# RHBZ#1527522: logrotate does not allow exec of systemctl and signals
|
|
# because we do carry some unconfined service logrotation script
|
|
# /etc/logrotate.d/foreman-proxy with logs as var_log_t
|
|
files_list_var(logrotate_t)
|
|
systemd_config_generic_services(logrotate_t)
|
|
|
|
# When Foreman cronjob is started before Ruby on Rails, /tmp/bundler
|
|
# is created with system_u:object_r:system_cronjob_tmp_t:s0 label denying
|
|
# access to the web process
|
|
manage_files_pattern(foreman_rails_t, system_cronjob_tmp_t, system_cronjob_tmp_t)
|
|
manage_dirs_pattern(foreman_rails_t, system_cronjob_tmp_t, system_cronjob_tmp_t)
|
|
|
|
#######################################
|
|
#
|
|
# Remote Execution
|
|
#
|
|
|
|
# File /usr/sbin/foreman-cockpit-session is a symlink
|
|
read_lnk_files_pattern(cockpit_ws_t, cockpit_session_exec_t, cockpit_session_exec_t)
|
|
read_lnk_files_pattern(cockpit_session_t, cockpit_session_exec_t, cockpit_session_exec_t)
|
|
|
|
# Run /usr/bin/env and /usr/bin/ruby
|
|
corecmd_exec_bin(cockpit_ws_t)
|
|
kernel_read_system_state(cockpit_ws_t)
|
|
|
|
# Connect to Foreman HTTP(s) port
|
|
corenet_tcp_connect_http_port(cockpit_session_t)
|
|
corenet_tcp_connect_http_port(cockpit_ws_t)
|
|
|
|
# Connect to remote Cockpit instance HTTPS port
|
|
corenet_tcp_connect_websm_port(cockpit_session_t)
|
|
corenet_tcp_connect_websm_port(cockpit_ws_t)
|
|
|
|
# Connect to Foreman Cockpit instance HTTPS port
|
|
corenet_tcp_connect_websm_port(httpd_t)
|
|
|
|
|
|
#######################################
|
|
#
|
|
# OpenStack Compute Resource
|
|
#
|
|
|
|
tunable_policy(`foreman_rails_can_connect_openstack',`
|
|
# keystone (identity service)
|
|
corenet_tcp_connect_commplex_main_port(foreman_rails_t)
|
|
# nova (compute service)
|
|
corenet_tcp_connect_osapi_compute_port(foreman_rails_t)
|
|
# neutron (network service)
|
|
corenet_tcp_connect_neutron_port(foreman_rails_t)
|
|
')
|
|
|
|
#######################################
|
|
#
|
|
# Libvirt Compute Resource
|
|
#
|
|
|
|
optional_policy(`
|
|
tunable_policy(`foreman_rails_can_spawn_ssh',`
|
|
require {
|
|
class process { getcap setcap };
|
|
}
|
|
allow foreman_rails_t self:process { getcap setcap };
|
|
|
|
ssh_exec(foreman_rails_t)
|
|
ssh_read_user_home_files(foreman_rails_t)
|
|
')
|
|
')
|
|
|
|
optional_policy(`
|
|
tunable_policy(`foreman_rails_can_connect_libvirt',`
|
|
virt_getattr_exec(foreman_rails_t)
|
|
virt_read_pid_symlinks(foreman_rails_t)
|
|
virt_stream_connect(foreman_rails_t)
|
|
')
|
|
')
|
|
|
|
#######################################
|
|
#
|
|
# Websockify
|
|
#
|
|
|
|
type websockify_t;
|
|
type websockify_exec_t;
|
|
role system_r types websockify_t;
|
|
|
|
application_domain(websockify_t, websockify_exec_t)
|
|
domtrans_pattern(foreman_rails_t, websockify_exec_t, websockify_t)
|
|
|
|
require {
|
|
type vnc_port_t;
|
|
class process { siginh rlimitinh noatsecure };
|
|
}
|
|
|
|
allow websockify_t self:netlink_route_socket { all_netlink_route_socket_perms };
|
|
allow websockify_t self:tcp_socket { all_tcp_socket_perms };
|
|
allow websockify_t self:udp_socket { all_udp_socket_perms };
|
|
allow foreman_rails_t websockify_t:process { siginh noatsecure rlimitinh };
|
|
|
|
apache_search_config(websockify_t)
|
|
corenet_tcp_bind_generic_node(websockify_t)
|
|
corenet_tcp_connect_vnc_port(websockify_t)
|
|
corenet_tcp_bind_vnc_port(websockify_t)
|
|
corenet_tcp_bind_vnc_port(foreman_rails_t)
|
|
dev_read_urand(websockify_t)
|
|
kernel_read_system_state(websockify_t)
|
|
optional_policy(`
|
|
logging_send_syslog_msg(websockify_t)
|
|
')
|
|
optional_policy(`
|
|
abrt_stream_connect(websockify_t)
|
|
')
|
|
miscfiles_read_localization(websockify_t)
|
|
sysnet_read_config(websockify_t)
|
|
files_search_var_lib(websockify_t)
|
|
optional_policy(`
|
|
puppet_read_lib(websockify_t)
|
|
puppet_read_config(websockify_t)
|
|
')
|
|
files_search_etc(websockify_t)
|
|
corecmd_exec_ls(websockify_t)
|
|
|
|
tunable_policy(`websockify_can_connect_all',`
|
|
corenet_tcp_connect_all_ports(websockify_t)
|
|
')
|
|
|
|
######################################
|
|
#
|
|
# Foreman Bootdisk plugin
|
|
#
|
|
|
|
# read grubx64.efi
|
|
optional_policy(`
|
|
tftp_read_content(foreman_rails_t)
|
|
tftp_read_rw_content(foreman_rails_t)
|
|
tftp_search_rw_content(foreman_rails_t)
|
|
')
|
|
|
|
# execute mkfs.msdos
|
|
fstools_exec(foreman_rails_t)
|
|
|
|
# isohybrid reads random
|
|
dev_read_rand(foreman_rails_t)
|
|
|
|
######################################
|
|
#
|
|
# Foreman Hooks plugin
|
|
#
|
|
|
|
typealias bin_t alias foreman_hook_t;
|
|
|
|
######################################
|
|
#
|
|
# Foreman Tasks plugin
|
|
#
|
|
|
|
# the plugin daemon uses daemon gem for the backround job
|
|
type foreman_tasks_exec_t;
|
|
init_daemon_domain(foreman_rails_t, foreman_tasks_exec_t)
|
|
|
|
######################################
|
|
#
|
|
# Foreman Memcache plugin
|
|
#
|
|
|
|
optional_policy(`
|
|
corenet_tcp_connect_memcache_port(foreman_rails_t)
|
|
')
|
|
|
|
######################################
|
|
#
|
|
# Apache httpd server
|
|
#
|
|
|
|
# Apache httpd reads puppet certs
|
|
optional_policy(`
|
|
puppet_read_config(httpd_t)
|
|
')
|
|
|
|
# Allow Apache access to the Unix socket
|
|
files_search_pids(httpd_t)
|
|
stream_connect_pattern(httpd_t, foreman_var_run_t, foreman_var_run_t, foreman_rails_t)
|
|
|
|
# Allow Apache access to static assets
|
|
allow httpd_t foreman_lib_t:file { getattr map open read };
|
|
allow httpd_t foreman_lib_t:lnk_file { getattr read };
|
|
|
|
######################################
|
|
#
|
|
# Foreman Templates plugin
|
|
#
|
|
|
|
# The plugin spawns git which needs be able to map files from /tmp into memory
|
|
# and manage links
|
|
allow foreman_rails_t tmp_t:file map;
|
|
allow foreman_rails_t tmp_t:lnk_file { create unlink };
|