diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..70b552a --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +TARGET?=fail2ban +MODULES?=${TARGET:=.pp.bz2} +SHAREDIR?=/usr/share + +all: ${TARGET:=.pp.bz2} + +%.pp.bz2: %.pp + @echo Compressing $^ -\> $@ + bzip2 -9 $^ + +%.pp: %.te + make -f ${SHAREDIR}/selinux/devel/Makefile $@ + +clean: + rm -f *~ *.tc *.pp *.pp.bz2 + rm -rf tmp *.tar.gz + +man: install-policy + sepolicy manpage --path . --domain ${TARGET}_t + +install-policy: all + semodule -i ${TARGET}.pp.bz2 + +install: man + install -D -m 644 ${TARGET}.pp.bz2 ${DESTDIR}${SHAREDIR}/selinux/packages/${TARGET}.pp.bz2 + install -D -m 644 ${TARGET}_selinux.8 ${DESTDIR}${SHAREDIR}/man/man8/ diff --git a/fail2ban.fc b/fail2ban.fc new file mode 100644 index 0000000..4da938f --- /dev/null +++ b/fail2ban.fc @@ -0,0 +1,9 @@ +/etc/rc\.d/init\.d/fail2ban -- gen_context(system_u:object_r:fail2ban_initrc_exec_t,s0) + +/usr/bin/fail2ban -- gen_context(system_u:object_r:fail2ban_exec_t,s0) +/usr/bin/fail2ban-client -- gen_context(system_u:object_r:fail2ban_client_exec_t,s0) +/usr/bin/fail2ban-server -- gen_context(system_u:object_r:fail2ban_exec_t,s0) + +/var/lib/fail2ban(/.*)? gen_context(system_u:object_r:fail2ban_var_lib_t,s0) +/var/log/fail2ban\.log.* -- gen_context(system_u:object_r:fail2ban_log_t,s0) +/var/run/fail2ban.* gen_context(system_u:object_r:fail2ban_var_run_t,s0) diff --git a/fail2ban.if b/fail2ban.if new file mode 100644 index 0000000..94e1936 --- /dev/null +++ b/fail2ban.if @@ -0,0 +1,313 @@ +## Update firewall filtering to ban IP addresses with too many password failures. + +######################################## +## +## Execute a domain transition to run fail2ban. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`fail2ban_domtrans',` + gen_require(` + type fail2ban_t, fail2ban_exec_t; + ') + + corecmd_search_bin($1) + domtrans_pattern($1, fail2ban_exec_t, fail2ban_t) +') + +####################################### +## +## Execute the fail2ban client in +## the fail2ban client domain. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`fail2ban_domtrans_client',` + gen_require(` + type fail2ban_client_t, fail2ban_client_exec_t; + ') + + corecmd_search_bin($1) + domtrans_pattern($1, fail2ban_client_exec_t, fail2ban_client_t) +') + +####################################### +## +## Execute fail2ban client in the +## fail2ban client domain, and allow +## the specified role the fail2ban +## client domain. +## +## +## +## Domain allowed to transition. +## +## +## +## +## Role allowed access. +## +## +# +interface(`fail2ban_run_client',` + gen_require(` + attribute_role fail2ban_client_roles; + ') + + fail2ban_domtrans_client($1) + roleattribute $2 fail2ban_client_roles; +') + +##################################### +## +## Connect to fail2ban over a unix domain +## stream socket. +## +## +## +## Domain allowed access. +## +## +# +interface(`fail2ban_stream_connect',` + gen_require(` + type fail2ban_t, fail2ban_var_run_t; + ') + + files_search_pids($1) + stream_connect_pattern($1, fail2ban_var_run_t, fail2ban_var_run_t, fail2ban_t) +') + +######################################## +## +## Read and write inherited temporary files. +## +## +## +## Domain allowed access. +## +## +# +interface(`fail2ban_rw_inherited_tmp_files',` + gen_require(` + type fail2ban_tmp_t; + ') + + files_search_tmp($1) + allow $1 fail2ban_tmp_t:file rw_inherited_file_perms; +') + +######################################## +## +## Read and write to an fail2ba unix stream socket. +## +## +## +## Domain allowed access. +## +## +# +interface(`fail2ban_rw_stream_sockets',` + gen_require(` + type fail2ban_t; + ') + + allow $1 fail2ban_t:unix_stream_socket rw_stream_socket_perms; +') + +####################################### +## +## Do not audit attempts to use +## fail2ban file descriptors. +## +## +## +## Domain to not audit. +## +## +# +interface(`fail2ban_dontaudit_use_fds',` + gen_require(` + type fail2ban_t; + ') + + dontaudit $1 fail2ban_t:fd use; +') + +####################################### +## +## Do not audit attempts to read and +## write fail2ban unix stream sockets +## +## +## +## Domain to not audit. +## +## +# +interface(`fail2ban_dontaudit_rw_stream_sockets',` + gen_require(` + type fail2ban_t; + ') + + dontaudit $1 fail2ban_t:unix_stream_socket { read write }; +') + +######################################## +## +## Read fail2ban lib files. +## +## +## +## Domain allowed access. +## +## +# +interface(`fail2ban_read_lib_files',` + gen_require(` + type fail2ban_var_lib_t; + ') + + files_search_var_lib($1) + read_files_pattern($1, fail2ban_var_lib_t, fail2ban_var_lib_t) +') + +######################################## +## +## Allow the specified domain to read fail2ban's log files. +## +## +## +## Domain allowed access. +## +## +## +# +interface(`fail2ban_read_log',` + gen_require(` + type fail2ban_log_t; + ') + + logging_search_logs($1) + allow $1 fail2ban_log_t:dir list_dir_perms; + allow $1 fail2ban_log_t:file read_file_perms; +') + +######################################## +## +## Allow the specified domain to append +## fail2ban log files. +## +## +## +## Domain allowed access. +## +## +# +interface(`fail2ban_append_log',` + gen_require(` + type fail2ban_log_t; + ') + + logging_search_logs($1) + allow $1 fail2ban_log_t:dir list_dir_perms; + allow $1 fail2ban_log_t:file append_file_perms; +') + +######################################## +## +## Read fail2ban PID files. +## +## +## +## Domain allowed access. +## +## +# +interface(`fail2ban_read_pid_files',` + gen_require(` + type fail2ban_var_run_t; + ') + + files_search_pids($1) + allow $1 fail2ban_var_run_t:file read_file_perms; +') + +######################################## +## +## dontaudit read and write an leaked file descriptors +## +## +## +## Domain to not audit. +## +## +# +interface(`fail2ban_dontaudit_leaks',` + gen_require(` + type fail2ban_t; + ') + + dontaudit $1 fail2ban_t:tcp_socket { read write }; + dontaudit $1 fail2ban_t:unix_dgram_socket { read write }; + dontaudit $1 fail2ban_t:unix_stream_socket { read write }; +') + +######################################## +## +## All of the rules required to administrate +## an fail2ban environment +## +## +## +## Domain allowed access. +## +## +## +## +## The role to be allowed to manage the fail2ban domain. +## +## +## +# +interface(`fail2ban_admin',` + gen_require(` + type fail2ban_t, fail2ban_log_t, fail2ban_initrc_exec_t; + type fail2ban_var_run_t, fail2ban_var_lib_t, fail2ban_tmp_t; + type fail2ban_client_t; + ') + + allow $1 { fail2ban_t fail2ban_client_t }:process signal_perms; + ps_process_pattern($1, { fail2ban_t fail2ban_client_t }) + + tunable_policy(`deny_ptrace',`',` + allow $1 { fail2ban_t fail2ban_client_t }:process ptrace; + ') + + init_labeled_script_domtrans($1, fail2ban_initrc_exec_t) + domain_system_change_exemption($1) + role_transition $2 fail2ban_initrc_exec_t system_r; + allow $2 system_r; + + logging_list_logs($1) + admin_pattern($1, fail2ban_log_t) + + files_list_pids($1) + admin_pattern($1, fail2ban_var_run_t) + + files_list_var_lib($1) + admin_pattern($1, fail2ban_var_lib_t) + + files_list_tmp($1) + admin_pattern($1, fail2ban_tmp_t) + + fail2ban_run_client($1, $2) +') diff --git a/fail2ban.spec b/fail2ban.spec index 5e72d32..27557e1 100644 --- a/fail2ban.spec +++ b/fail2ban.spec @@ -1,10 +1,15 @@ Summary: Daemon to ban hosts that cause multiple authentication errors Name: fail2ban Version: 0.11.1 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv2+ URL: http://fail2ban.sourceforge.net/ Source0: https://github.com/%{name}/%{name}/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz +# SELinux policy +Source1: fail2ban.fc +Source2: fail2ban.if +Source3: fail2ban.te +Source4: Makefile # Give up being PartOf iptables and ipset for now # https://bugzilla.redhat.com/show_bug.cgi?id=1379141 # https://bugzilla.redhat.com/show_bug.cgi?id=1573185 @@ -29,6 +34,7 @@ BuildArch: noarch %if 0%{?fedora} || 0%{?rhel} >= 7 BuildRequires: systemd %endif +BuildRequires: selinux-policy-devel # Default components Requires: %{name}-firewalld = %{version}-%{release} Requires: %{name}-sendmail = %{version}-%{release} @@ -52,6 +58,16 @@ sub-packages are available to install support for other actions and configurations. +%package selinux +Summary: SELinux policies for Fail2Ban +%{?selinux_requires} +%global modulename fail2ban +%global selinuxtype targeted + +%description selinux +SELinux policies for Fail2Ban. + + %package server Summary: Core server component for Fail2Ban %if 0%{?fedora} || 0%{?rhel} >= 7 @@ -67,6 +83,7 @@ Requires(preun): /sbin/service %endif Requires: ipset Requires: iptables +Requires: (%{name}-selinux if selinux-policy-%{selinuxtype}) %description server This package contains the core server components for Fail2Ban with minimal @@ -167,9 +184,12 @@ by default. sed -i -e 's/^before = paths-.*/before = paths-fedora.conf/' config/jail.conf 2to3 --write --nobackups . find -type f -exec sed -i -e '1s,^#!/usr/bin/python *,#!/usr/bin/python%{python3_version},' {} + +# SELinux sources +cp -p %SOURCE1 %SOURCE2 %SOURCE3 . %build %py3_build +make -f %SOURCE4 %install %py3_install @@ -221,11 +241,32 @@ EOF # Remove installed doc, use doc macro instead rm -r %{buildroot}%{_docdir}/%{name} +# SELinux +# install policy modules +install -d %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype} +install -m 0644 %{modulename}.pp.bz2 %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype} + %check %python3 bin/fail2ban-testcases --verbosity=2 --no-network + +%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} + + %post server %if 0%{?fedora} || 0%{?rhel} >= 7 %systemd_post fail2ban.service @@ -250,6 +291,11 @@ fi %files +%files selinux +%{_datadir}/selinux/packages/%{selinuxtype}/%{name}.pp.bz2 +%ghost %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{name} +%license COPYING + %files server %doc README.md TODO ChangeLog COPYING doc/*.txt %{_bindir}/fail2ban-client @@ -316,6 +362,9 @@ fi %changelog +* Wed Feb 26 2020 Orion Poplawski - 0.11.1-4 +- Add SELinux policy + * Tue Jan 28 2020 Fedora Release Engineering - 0.11.1-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild diff --git a/fail2ban.te b/fail2ban.te new file mode 100644 index 0000000..0b5effb --- /dev/null +++ b/fail2ban.te @@ -0,0 +1,190 @@ +policy_module(fail2ban, 1.5.0) + +######################################## +# +# Declarations +# + +attribute_role fail2ban_client_roles; + +type fail2ban_t; +type fail2ban_exec_t; +init_daemon_domain(fail2ban_t, fail2ban_exec_t) + +type fail2ban_initrc_exec_t; +init_script_file(fail2ban_initrc_exec_t) + +type fail2ban_log_t; +logging_log_file(fail2ban_log_t) + +type fail2ban_var_lib_t; +files_type(fail2ban_var_lib_t) + +type fail2ban_var_run_t; +files_pid_file(fail2ban_var_run_t) + +type fail2ban_tmp_t; +files_tmp_file(fail2ban_tmp_t) + +type fail2ban_client_t; +type fail2ban_client_exec_t; +init_system_domain(fail2ban_client_t, fail2ban_client_exec_t) +role fail2ban_client_roles types fail2ban_client_t; + +######################################## +# +# Server Local policy +# + +allow fail2ban_t self:capability { dac_read_search sys_tty_config }; +allow fail2ban_t self:process { getpgid setsched signal }; +allow fail2ban_t self:fifo_file rw_fifo_file_perms; +allow fail2ban_t self:unix_stream_socket { accept connectto listen }; +allow fail2ban_t self:tcp_socket { accept listen }; +allow fail2ban_t self:netlink_netfilter_socket create_socket_perms; + +read_files_pattern(fail2ban_t, fail2ban_t, fail2ban_t) + +append_files_pattern(fail2ban_t, fail2ban_log_t, fail2ban_log_t) +create_files_pattern(fail2ban_t, fail2ban_log_t, fail2ban_log_t) +setattr_files_pattern(fail2ban_t, fail2ban_log_t, fail2ban_log_t) +logging_log_filetrans(fail2ban_t, fail2ban_log_t, file) + +manage_dirs_pattern(fail2ban_t, fail2ban_tmp_t, fail2ban_tmp_t) +manage_files_pattern(fail2ban_t, fail2ban_tmp_t, fail2ban_tmp_t) +exec_files_pattern(fail2ban_t, fail2ban_tmp_t, fail2ban_tmp_t) +files_tmp_filetrans(fail2ban_t, fail2ban_tmp_t, { dir file }) + +manage_dirs_pattern(fail2ban_t, fail2ban_var_lib_t, fail2ban_var_lib_t) +manage_files_pattern(fail2ban_t, fail2ban_var_lib_t, fail2ban_var_lib_t) + +manage_dirs_pattern(fail2ban_t, fail2ban_var_run_t, fail2ban_var_run_t) +manage_sock_files_pattern(fail2ban_t, fail2ban_var_run_t, fail2ban_var_run_t) +manage_files_pattern(fail2ban_t, fail2ban_var_run_t, fail2ban_var_run_t) +files_pid_filetrans(fail2ban_t, fail2ban_var_run_t, file) + +kernel_read_system_state(fail2ban_t) +kernel_read_network_state(fail2ban_t) + + +corecmd_exec_bin(fail2ban_t) +corecmd_exec_shell(fail2ban_t) + +corenet_all_recvfrom_netlabel(fail2ban_t) +corenet_tcp_sendrecv_generic_if(fail2ban_t) +corenet_tcp_sendrecv_generic_node(fail2ban_t) + +corenet_sendrecv_whois_client_packets(fail2ban_t) +corenet_tcp_connect_whois_port(fail2ban_t) +corenet_tcp_sendrecv_whois_port(fail2ban_t) + +dev_read_urand(fail2ban_t) + +domain_use_interactive_fds(fail2ban_t) +domain_dontaudit_read_all_domains_state(fail2ban_t) + +files_read_etc_runtime_files(fail2ban_t) +files_list_var(fail2ban_t) +files_dontaudit_list_tmp(fail2ban_t) + +fs_list_inotifyfs(fail2ban_t) +fs_getattr_all_fs(fail2ban_t) + +auth_use_nsswitch(fail2ban_t) + +logging_read_all_logs(fail2ban_t) +logging_read_audit_log(fail2ban_t) +logging_send_syslog_msg(fail2ban_t) +logging_read_syslog_pid(fail2ban_t) +logging_dontaudit_search_audit_logs(fail2ban_t) +logging_mmap_generic_logs(fail2ban_t) +logging_mmap_journal(fail2ban_t) + +mta_send_mail(fail2ban_t) + +sysnet_manage_config(fail2ban_t) + +optional_policy(` + apache_read_log(fail2ban_t) +') + +optional_policy(` + dbus_system_bus_client(fail2ban_t) + dbus_connect_system_bus(fail2ban_t) + + optional_policy(` + firewalld_dbus_chat(fail2ban_t) + ') +') + +optional_policy(` + ftp_read_log(fail2ban_t) +') + +optional_policy(` + gnome_dontaudit_search_config(fail2ban_t) +') + +optional_policy(` + iptables_domtrans(fail2ban_t) +') + +optional_policy(` + allow fail2ban_t self:capability sys_resource; + allow fail2ban_t self:process setrlimit; + journalctl_exec(fail2ban_t) +') + +optional_policy(` + libs_exec_ldconfig(fail2ban_t) +') + +optional_policy(` + rpm_exec(fail2ban_t) +') + +optional_policy(` + shorewall_domtrans(fail2ban_t) +') + +######################################## +# +# Client Local policy +# + +allow fail2ban_client_t self:capability { dac_read_search }; +allow fail2ban_client_t self:unix_stream_socket { create connect write read }; + +domtrans_pattern(fail2ban_client_t, fail2ban_exec_t, fail2ban_t) + +allow fail2ban_client_t fail2ban_t:process { rlimitinh }; + +dontaudit fail2ban_client_t fail2ban_var_run_t:dir_file_class_set audit_access; +allow fail2ban_client_t fail2ban_var_run_t:dir write; +stream_connect_pattern(fail2ban_client_t, fail2ban_var_run_t, fail2ban_var_run_t, fail2ban_t) + +kernel_read_system_state(fail2ban_client_t) + +corecmd_exec_bin(fail2ban_client_t) + +dev_read_urand(fail2ban_client_t) +dev_read_rand(fail2ban_client_t) + +domain_use_interactive_fds(fail2ban_client_t) + +files_search_pids(fail2ban_client_t) + +auth_use_nsswitch(fail2ban_client_t) + +libs_exec_ldconfig(fail2ban_client_t) + +logging_getattr_all_logs(fail2ban_client_t) +logging_search_all_logs(fail2ban_client_t) +logging_read_audit_log(fail2ban_client_t) + +userdom_dontaudit_search_user_home_dirs(fail2ban_client_t) +userdom_use_user_terminals(fail2ban_client_t) + +optional_policy(` + apache_read_log(fail2ban_client_t) +')