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