Project

General

Profile

Download (14.9 KB) Statistics
| Branch: | Tag: | Revision:
# 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 Docker via local socket
## </p>
## </desc>
gen_tunable(foreman_rails_can_connect_container_unix, true)

## <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_port_t when preloading app.
## </p>
## </desc>
gen_tunable(foreman_rails_can_connect_http, 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)

type foreman_container_port_t;
corenet_port(foreman_container_port_t)

require{
type bin_t;
type httpd_t;
type httpd_tmp_t;
type ifconfig_exec_t;
type init_t;
type proc_net_t;
type puppetmaster_exec_t;
type puppetmaster_t;
type sysctl_net_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)
')

# 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)

# 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)
')

######################################
#
# Container / Docker
#

allow foreman_rails_t foreman_container_port_t:tcp_socket name_connect;

optional_policy(`
tunable_policy(`foreman_rails_can_connect_container_unix',`
ifdef(`has_container', `
container_stream_connect(foreman_rails_t)
container_spc_stream_connect(foreman_rails_t)
')
ifdef(`has_docker', `
docker_stream_connect(foreman_rails_t)
#docker_spc_stream_connect(foreman_rails_t)
gen_require(`
type spc_t, spc_var_run_t;
attribute pidfile;
')
files_search_pids(foreman_rails_t)
allow foreman_rails_t pidfile:sock_file write_sock_file_perms;
allow foreman_rails_t spc_t:unix_stream_socket connectto;
')
')
')

######################################
#
# 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)
(20-20/21)