From 5b573bb9a34fec5d34a4509c68015951ec6669b9 Mon Sep 17 00:00:00 2001 From: Vit Mojzis Date: Fri, 14 Feb 2020 17:43:36 +0100 Subject: [PATCH] Add freeipa-selinux subpackage Add freeipa-selinux subpackage containing selinux policy for FreeIPA server. This policy module will override the distribution policy. Policy files where extracted from https://github.com/fedora-selinux/selinux-policy See Independent policy project guidelines for more details about shipping custom SELinux policy. https://fedoraproject.org/wiki/SELinux/IndependentPolicy Reviewed-By: Christian Heimes --- freeipa.spec.in | 62 ++++++++++ selinux/ipa.fc | 29 +++++ selinux/ipa.if | 310 ++++++++++++++++++++++++++++++++++++++++++++++++ selinux/ipa.te | 292 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 693 insertions(+) create mode 100644 selinux/ipa.fc create mode 100644 selinux/ipa.if create mode 100644 selinux/ipa.te diff --git a/freeipa.spec.in b/freeipa.spec.in index ccf648ec4a5..7ec732f468a 100755 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -36,6 +36,13 @@ %global linter_options --disable-pylint --without-jslint %endif +# Include SELinux subpackage +%if 0%{?fedora} >= 30 || 0%{?rhel} > 8 + %global with_selinux 1 + %global selinuxtype targeted + %global modulename ipa +%endif + %if 0%{?rhel} %global package_name ipa %global alt_name freeipa @@ -284,6 +291,13 @@ BuildRequires: krb5-server >= %{krb5_version} # ONLY_CLIENT %endif +# +# Build dependencies for SELinux policy +# +%if 0%{?with_selinux} +BuildRequires: selinux-policy-devel +%endif + %description IPA is an integrated solution to provide centrally managed Identity (users, hosts, services), Authentication (SSO, 2FA), and Authorization @@ -349,6 +363,11 @@ Requires: oddjob # 0.7.0-2: https://pagure.io/gssproxy/pull-request/172 Requires: gssproxy >= 0.7.0-2 Requires: sssd-dbus >= %{sssd_version} +%if 0%{?with_selinux} +# This ensures that the *-selinux package and all it’s dependencies are not pulled +# into containers and other systems that do not use SELinux +Requires: (%{name}-selinux if selinux-policy-%{selinuxtype}) +%endif # if with_selinux Provides: %{alt_name}-server = %{version} Conflicts: %{alt_name}-server @@ -736,6 +755,19 @@ This package contains tests that verify IPA functionality under Python 3. # with_ipatests %endif +%if 0%{?with_selinux} +# SELinux subpackage +%package selinux +Summary: FreeIPA SELinux policy +BuildArch: noarch +Requires: selinux-policy-%{selinuxtype} +Requires(post): selinux-policy-%{selinuxtype} +%{?selinux_requires} + +%description selinux +Custom SELinux policy module +# with_selinux +%endif %prep %setup -n freeipa-%{version} -q @@ -838,6 +870,10 @@ mkdir -p %{buildroot}%{_sysconfdir}/cron.d # ONLY_CLIENT %endif +%if 0%{?with_selinux} +install -D -m 0644 selinux/%{modulename}.pp.bz2 %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2 +# with_selinux +%endif %clean rm -rf %{buildroot} @@ -992,6 +1028,26 @@ if [ $1 -gt 1 ] ; then fi +%if 0%{?with_selinux} +# SELinux contexts are saved so that only affected files can be +# relabeled after the policy module installation +%pre selinux +%selinux_relabel_pre -s %{selinuxtype} + +%post selinux +%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2 + +%postun selinux +if [ $1 -eq 0 ]; then + %selinux_modules_uninstall -s %{selinuxtype} %{modulename} +fi + +%posttrans selinux +%selinux_relabel_post -s %{selinuxtype} +# with_selinux +%endif + + %triggerin client -- openssh-server # Has the client been configured? restore=0 @@ -1372,6 +1428,12 @@ fi # with_ipatests %endif +%if 0%{?with_selinux} +%files selinux +%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.* +%ghost %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename} +# with_selinux +%endif %changelog * Tue Nov 26 2013 Petr Viktorin - @VERSION@-@VENDOR_SUFFIX@ diff --git a/selinux/ipa.fc b/selinux/ipa.fc new file mode 100644 index 00000000000..61fd84f0069 --- /dev/null +++ b/selinux/ipa.fc @@ -0,0 +1,29 @@ +/etc/httpd/alias/ipasession.key -- gen_context(system_u:object_r:ipa_cert_t,s0) + +/usr/lib/systemd/system/ipa-otpd.* -- gen_context(system_u:object_r:ipa_otpd_unit_file_t,s0) + +/usr/lib/systemd/system/ipa-dnskeysyncd.* -- gen_context(system_u:object_r:ipa_dnskey_unit_file_t,s0) + +/usr/lib/systemd/system/ipa-ods-exporter.* -- gen_context(system_u:object_r:ipa_ods_exporter_unit_file_t,s0) + +/usr/libexec/ipa-otpd -- gen_context(system_u:object_r:ipa_otpd_exec_t,s0) +/usr/libexec/ipa/ipa-otpd -- gen_context(system_u:object_r:ipa_otpd_exec_t,s0) + + +/usr/libexec/ipa/ipa-ods-exporter -- gen_context(system_u:object_r:ipa_ods_exporter_exec_t,s0) + +/usr/libexec/ipa/ipa-dnskeysyncd -- gen_context(system_u:object_r:ipa_dnskey_exec_t,s0) +/usr/libexec/ipa/ipa-dnskeysync-replica -- gen_context(system_u:object_r:ipa_dnskey_exec_t,s0) + +/usr/libexec/ipa/com\.redhat\.idm\.trust-fetch-domains -- gen_context(system_u:object_r:ipa_helper_exec_t,s0) +/usr/libexec/ipa/oddjob/com\.redhat\.idm\.trust-fetch-domains -- gen_context(system_u:object_r:ipa_helper_exec_t,s0) +/usr/libexec/ipa/oddjob/org\.freeipa\.server\.conncheck -- gen_context(system_u:object_r:ipa_helper_exec_t,s0) + +/var/lib/ipa(/.*)? gen_context(system_u:object_r:ipa_var_lib_t,s0) + +/var/log/ipa(/.*)? gen_context(system_u:object_r:ipa_log_t,s0) + +/var/log/ipareplica-conncheck.log.* -- gen_context(system_u:object_r:ipa_log_t,s0) + +/var/run/ipa(/.*)? gen_context(system_u:object_r:ipa_var_run_t,s0) + diff --git a/selinux/ipa.if b/selinux/ipa.if new file mode 100644 index 00000000000..72a6b78bad4 --- /dev/null +++ b/selinux/ipa.if @@ -0,0 +1,310 @@ +## Policy for IPA services. + +######################################## +## +## Execute rtas_errd in the rtas_errd domin. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`ipa_domtrans_otpd',` + gen_require(` + type ipa_otpd_t, ipa_otpd_exec_t; + ') + + corecmd_search_bin($1) + domtrans_pattern($1, ipa_otpd_exec_t, ipa_otpd_t) +') + +######################################## +## +## Connect to ipa-otpd over a unix stream socket. +## +## +## +## Domain allowed access. +## +## +# +interface(`ipa_stream_connect_otpd',` + gen_require(` + type ipa_otpd_t; + ') + allow $1 ipa_otpd_t:unix_stream_socket connectto; +') + +######################################## +## +## Connect to ipa-ods-exporter over a unix stream socket. +## +## +## +## Domain allowed access. +## +## +# +interface(`ipa_stream_connect_ods_exporter',` + gen_require(` + type ipa_ods_exporter_t; + ') + allow $1 ipa_ods_exporter_t:unix_stream_socket connectto; +') + +######################################## +## +## Execute ipa-helper in the ipa_helper domain. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`ipa_domtrans_helper',` + gen_require(` + type ipa_helper_t, ipa_helper_exec_t; + ') + + domtrans_pattern($1, ipa_helper_exec_t, ipa_helper_t) +') + +######################################## +## +## Execute ipa-helper in the ipa_helper domain. +## +## +## +## Domain allowed to transition. +## +## +## +## +## Role allowed access. +## +## +# +interface(`ipa_run_helper',` + gen_require(` + type ipa_helper_t; + attribute_role ipa_helper_roles; + ') + + ipa_domtrans_helper($1) + roleattribute $2 ipa_helper_roles; +') + +######################################## +## +## Allow domain to manage ipa lib files/dirs. +## +## +## +## Domain allowed access. +## +## +# +interface(`ipa_search_lib',` + gen_require(` + type ipa_var_lib_t; + ') + + search_dirs_pattern($1, ipa_var_lib_t, ipa_var_lib_t) +') + +######################################## +## +## Allow domain to manage ipa lib files/dirs. +## +## +## +## Domain allowed access. +## +## +# +interface(`ipa_manage_lib',` + gen_require(` + type ipa_var_lib_t; + ') + + manage_files_pattern($1, ipa_var_lib_t, ipa_var_lib_t) + manage_dirs_pattern($1, ipa_var_lib_t, ipa_var_lib_t) +') + +######################################## +## +## Allow domain to manage ipa log files/dirs. +## +## +## +## Domain allowed access. +## +## +# +interface(`ipa_manage_log',` + gen_require(` + type ipa_log_t; + ') + + manage_files_pattern($1, ipa_log_t, ipa_log_t) + manage_dirs_pattern($1, ipa_log_t, ipa_log_t) +') + +######################################## +## +## Allow domain to manage ipa lib files/dirs. +## +## +## +## Domain allowed access. +## +## +# +interface(`ipa_read_lib',` + gen_require(` + type ipa_var_lib_t; + ') + + read_files_pattern($1, ipa_var_lib_t, ipa_var_lib_t) + list_dirs_pattern($1, ipa_var_lib_t, ipa_var_lib_t) +') + +######################################## +## +## Allow domain to manage ipa run files/dirs. +## +## +## +## Domain allowed access. +## +## +# +interface(`ipa_manage_pid_files',` + gen_require(` + type ipa_var_run_t; + ') + manage_files_pattern($1, ipa_var_run_t, ipa_var_run_t) + manage_dirs_pattern($1, ipa_var_run_t, ipa_var_run_t) +') + +######################################## +## +## Create specified objects in generic +## pid directories with the ipa pid file type. +## +## +## +## Domain allowed access. +## +## +## +## +## The name of the object being created. +## +## +# +interface(`ipa_filetrans_pid',` + gen_require(` + type ipa_var_run_t; + ') + + files_pid_filetrans($1, ipa_var_run_t, file, $2) +') + +######################################## +## +## Allow domain to manage ipa tmp files +## +## +## +## Domain allowed access. +## +## +# +interface(`ipa_delete_tmp',` + gen_require(` + type ipa_tmp_t; + ') + + files_search_tmp($1) + allow $1 ipa_tmp_t:file unlink; +') + +######################################## +## +## Create log files with a named file +## type transition. +## +## +## +## Domain allowed access. +## +## +# +interface(`ipa_named_filetrans_log_dir',` + gen_require(` + type ipa_log_t; + ') + + logging_log_named_filetrans($1, ipa_log_t, dir, "ipa") +') + +####################################### +## +## Allow domain to create /tmp/ca.p12 +## +## +## +## Domain allowed access. +## +## +# +interface(`ipa_filetrans_named_content',` + + gen_require(` + type ipa_tmp_t; + ') + + files_tmp_filetrans($1, ipa_tmp_t, file, "ca.p12") +') + +######################################## +## +## Create file ipasession.key in cert_t dir +## with ipa_cert_t type +## +## +## +## Domain allowed access. +## +## +# +interface(`ipa_cert_filetrans_named_content',` + gen_require(` + type ipa_cert_t; + type cert_t; + ') + + filetrans_pattern($1, cert_t, ipa_cert_t, file ,"ipasession.key") + manage_files_pattern($1, ipa_cert_t, ipa_cert_t) +') + +######################################## +## +## Allow domain to read ipa tmp files/dirs. +## +## +## +## Domain allowed access. +## +## +# +interface(`ipa_read_tmp',` + gen_require(` + type ipa_tmp_t; + ') + + read_files_pattern($1, ipa_tmp_t, ipa_tmp_t) +') diff --git a/selinux/ipa.te b/selinux/ipa.te new file mode 100644 index 00000000000..2cdf91408a5 --- /dev/null +++ b/selinux/ipa.te @@ -0,0 +1,292 @@ +policy_module(ipa, 1.0.0) + +######################################## +# +# Declarations +# + +attribute ipa_domain; + +attribute_role ipa_helper_roles; +roleattribute system_r ipa_helper_roles; + +type ipa_otpd_t, ipa_domain; +type ipa_otpd_exec_t; +init_daemon_domain(ipa_otpd_t, ipa_otpd_exec_t) + +type ipa_dnskey_t, ipa_domain; +type ipa_dnskey_exec_t; +init_daemon_domain(ipa_dnskey_t, ipa_dnskey_exec_t) + +type ipa_ods_exporter_t, ipa_domain; +type ipa_ods_exporter_exec_t; +init_daemon_domain(ipa_ods_exporter_t, ipa_ods_exporter_exec_t) + +type ipa_otpd_unit_file_t; +systemd_unit_file(ipa_otpd_unit_file_t) + +type ipa_dnskey_unit_file_t; +systemd_unit_file(ipa_dnskey_unit_file_t) + +type ipa_ods_exporter_unit_file_t; +systemd_unit_file(ipa_ods_exporter_unit_file_t) + +type ipa_log_t; +logging_log_file(ipa_log_t) + +type ipa_var_lib_t; +files_type(ipa_var_lib_t) + +type ipa_var_run_t; +files_pid_file(ipa_var_run_t) + +type ipa_helper_t; +type ipa_helper_exec_t; +domain_type(ipa_helper_t) +domain_obj_id_change_exemption(ipa_helper_t) +init_system_domain(ipa_helper_t, ipa_helper_exec_t) +role ipa_helper_roles types ipa_helper_t; + +type ipa_cert_t; +miscfiles_cert_type(ipa_cert_t) + +type ipa_tmp_t; +files_tmp_file(ipa_tmp_t) + +######################################## +# +# ipa_otpd local policy +# + +allow ipa_otpd_t self:capability2 block_suspend; + +allow ipa_otpd_t self:fifo_file rw_fifo_file_perms; +allow ipa_otpd_t self:unix_stream_socket create_stream_socket_perms; + +read_files_pattern(ipa_otpd_t, ipa_cert_t, ipa_cert_t) +read_lnk_files_pattern(ipa_otpd_t, ipa_cert_t, ipa_cert_t) + +manage_dirs_pattern(ipa_otpd_t, ipa_var_run_t, ipa_var_run_t) +manage_files_pattern(ipa_otpd_t, ipa_var_run_t, ipa_var_run_t) +files_pid_filetrans(ipa_otpd_t, ipa_var_run_t, file) + +corenet_tcp_connect_radius_port(ipa_otpd_t) + +dev_read_urand(ipa_otpd_t) +dev_read_rand(ipa_otpd_t) + +sysnet_dns_name_resolve(ipa_otpd_t) + +optional_policy(` + dirsrv_stream_connect(ipa_otpd_t) +') + +optional_policy(` + kerberos_use(ipa_otpd_t) +') + +optional_policy(` + sssd_stream_connect(ipa_otpd_t) +') + +######################################## +# +# ipa-helper local policy +# + + +allow ipa_helper_t self:capability { net_admin dac_read_search dac_override chown }; + +#kernel bug +dontaudit ipa_helper_t self:capability2 block_suspend; + +allow ipa_helper_t self:process setfscreate; +allow ipa_helper_t self:fifo_file rw_fifo_file_perms; +allow ipa_helper_t self:netlink_route_socket r_netlink_socket_perms; + +manage_files_pattern(ipa_helper_t, ipa_log_t, ipa_log_t) +logging_log_filetrans(ipa_helper_t, ipa_log_t, file) + +manage_dirs_pattern(ipa_helper_t, ipa_var_run_t, ipa_var_run_t) +manage_files_pattern(ipa_helper_t, ipa_var_run_t, ipa_var_run_t) +files_pid_filetrans(ipa_helper_t, ipa_var_run_t, { dir file }) + +kernel_read_system_state(ipa_helper_t) +kernel_read_network_state(ipa_helper_t) + +corenet_tcp_connect_ldap_port(ipa_helper_t) +corenet_tcp_connect_smbd_port(ipa_helper_t) +corenet_tcp_connect_http_port(ipa_helper_t) +corenet_tcp_connect_kerberos_password_port(ipa_helper_t) + +corecmd_exec_bin(ipa_helper_t) +corecmd_exec_shell(ipa_helper_t) + +dev_read_urand(ipa_helper_t) + +auth_use_nsswitch(ipa_helper_t) + +files_list_tmp(ipa_helper_t) + +ipa_manage_pid_files(ipa_helper_t) +ipa_read_lib(ipa_helper_t) + +logging_send_syslog_msg(ipa_helper_t) + +optional_policy(` + dirsrv_stream_connect(ipa_helper_t) +') + +optional_policy(` + ldap_stream_connect(ipa_helper_t) +') + +optional_policy(` + libs_exec_ldconfig(ipa_helper_t) +') + +optional_policy(` + kerberos_read_keytab(ipa_helper_t) +') + +optional_policy(` + memcached_stream_connect(ipa_helper_t) +') + +optional_policy(` + oddjob_system_entry(ipa_helper_t, ipa_helper_exec_t) +') + +optional_policy(` + rpm_read_db(ipa_helper_t) +') + +optional_policy(` + samba_read_config(ipa_helper_t) +') + +optional_policy(` + sssd_manage_lib_files(ipa_helper_t) +') + +######################################## +# +# ipa-dnskey local policy +# +allow ipa_dnskey_t self:tcp_socket create_stream_socket_perms; +allow ipa_dnskey_t self:udp_socket create_socket_perms; +allow ipa_dnskey_t self:unix_dgram_socket create_socket_perms; +allow ipa_dnskey_t self:netlink_route_socket { create_netlink_socket_perms nlmsg_read }; + +read_files_pattern(ipa_dnskey_t, ipa_cert_t, ipa_cert_t) +read_lnk_files_pattern(ipa_dnskey_t, ipa_cert_t, ipa_cert_t) + +manage_files_pattern(ipa_dnskey_t, ipa_var_lib_t, ipa_var_lib_t) +setattr_dirs_pattern(ipa_dnskey_t, ipa_var_lib_t, ipa_var_lib_t) +list_dirs_pattern(ipa_dnskey_t, ipa_var_lib_t, ipa_var_lib_t) + +manage_files_pattern(ipa_dnskey_t, ipa_tmp_t, ipa_tmp_t) +files_tmp_filetrans(ipa_dnskey_t, ipa_tmp_t, { file }) + +kernel_dgram_send(ipa_dnskey_t) +kernel_read_system_state(ipa_dnskey_t) +kernel_read_network_state(ipa_dnskey_t) + +auth_use_nsswitch(ipa_dnskey_t) + +corecmd_exec_bin(ipa_dnskey_t) +corecmd_exec_shell(ipa_dnskey_t) + +corenet_tcp_bind_generic_node(ipa_dnskey_t) +corenet_tcp_connect_kerberos_port(ipa_dnskey_t) +corenet_tcp_connect_rndc_port(ipa_dnskey_t) + +dev_read_rand(ipa_dnskey_t) + +can_exec(ipa_dnskey_t,ipa_dnskey_exec_t) + +libs_exec_ldconfig(ipa_dnskey_t) + +logging_send_syslog_msg(ipa_dnskey_t) + +miscfiles_read_certs(ipa_dnskey_t) + +sysnet_read_config(ipa_dnskey_t) + +optional_policy(` + apache_search_config(ipa_dnskey_t) +') + +optional_policy(` + bind_domtrans_ndc(ipa_dnskey_t) + bind_read_dnssec_keys(ipa_dnskey_t) + bind_manage_zone(ipa_dnskey_t) + bind_manage_zone_dirs(ipa_dnskey_t) + bind_search_cache(ipa_dnskey_t) +') + +optional_policy(` + dirsrv_stream_connect(ipa_dnskey_t) +') + +optional_policy(` + kerberos_read_keytab(ipa_dnskey_t) +') + +optional_policy(` + opendnssec_domtrans(ipa_dnskey_t) + opendnssec_manage_config(ipa_dnskey_t) + opendnssec_manage_var_files(ipa_dnskey_t) + opendnssec_filetrans_etc_content(ipa_dnskey_t) +') + +######################################## +# +# ipa-ods-exporter local policy +# +allow ipa_ods_exporter_t self:netlink_route_socket { bind create getattr nlmsg_read }; +allow ipa_ods_exporter_t self:udp_socket { connect create getattr }; +allow ipa_ods_exporter_t self:unix_dgram_socket { create getopt setopt }; + +manage_files_pattern(ipa_ods_exporter_t, ipa_var_lib_t, ipa_var_lib_t) +list_dirs_pattern(ipa_ods_exporter_t, ipa_var_lib_t, ipa_var_lib_t) + +manage_files_pattern(ipa_ods_exporter_t, ipa_tmp_t, ipa_tmp_t) +manage_dirs_pattern(ipa_ods_exporter_t, ipa_tmp_t, ipa_tmp_t) +files_tmp_filetrans(ipa_ods_exporter_t, ipa_tmp_t, { dir file }) + +kernel_dgram_send(ipa_ods_exporter_t) + +auth_use_nsswitch(ipa_ods_exporter_t) + +corecmd_exec_bin(ipa_ods_exporter_t) +corecmd_exec_shell(ipa_ods_exporter_t) + +libs_exec_ldconfig(ipa_ods_exporter_t) + +logging_send_syslog_msg(ipa_ods_exporter_t) + +miscfiles_read_certs(ipa_ods_exporter_t) + +sysnet_read_config(ipa_ods_exporter_t) + +optional_policy(` + bind_search_cache(ipa_ods_exporter_t) +') + +optional_policy(` + dirsrv_stream_connect(ipa_ods_exporter_t) +') + +optional_policy(` + kerberos_read_keytab(ipa_ods_exporter_t) +') + +optional_policy(` + opendnssec_manage_var_files(ipa_ods_exporter_t) + opendnssec_stream_connect(ipa_ods_exporter_t) +') + +optional_policy(` + ldap_stream_connect(ipa_ods_exporter_t) +')