net-analyzer/fail2ban: improve systemd unit ordering

If fail2ban was using ipset as a backend, previously, fail2ban would create
e.g. a 'f2b-sshd' ipset on startup and delete it on shutdown. But the
ipstables-store service would save this on shutdown too (and run before
fail2ban cleans it up), and then on boot, try to restore it before fail2ban
can create it again.

Thanks to Ryan Tsien and Mike Fisher for both their patience and explanations
on the bug. Quoting Mike on the fix:

> With this ordering, upon shutdown fail2ban stops, removing the iptables
> rule it inserted at the front of the INPUT chain, then iptables-store saves
> the remaining rules. Upon startup iptables-restore repopulates the bulk of
> the rules, then fail2ban starts and inserts itself back in the front of the
> chain after it creates the ipset.

Closes: https://bugs.gentoo.org/871996
Signed-off-by: Sam James <sam@gentoo.org>
This commit is contained in:
Sam James
2025-08-30 15:22:08 +01:00
parent a6e8f296b6
commit e48605a688
3 changed files with 165 additions and 0 deletions

View File

@@ -0,0 +1,150 @@
# Copyright 1999-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=8
PYTHON_COMPAT=( python3_{11..13} )
inherit bash-completion-r1 edo python-single-r1 systemd tmpfiles
DESCRIPTION="Scans log files and bans IPs that show malicious signs"
HOMEPAGE="https://www.fail2ban.org/"
if [[ ${PV} == *9999 ]] ; then
EGIT_REPO_URI="https://github.com/fail2ban/fail2ban"
inherit git-r3
else
SRC_URI="https://github.com/fail2ban/fail2ban/archive/${PV}.tar.gz -> ${P}.tar.gz"
KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~ppc ~ppc64 ~riscv ~sparc ~x86"
fi
LICENSE="GPL-2"
SLOT="0"
IUSE="selinux systemd test"
RESTRICT="!test? ( test )"
REQUIRED_USE="${PYTHON_REQUIRED_USE}"
RDEPEND="
${PYTHON_DEPS}
$(python_gen_cond_dep '
dev-python/pyasyncore[${PYTHON_USEDEP}]
dev-python/pyasynchat[${PYTHON_USEDEP}]
' 3.12)
virtual/logger
virtual/mta
selinux? ( sec-policy/selinux-fail2ban )
systemd? (
$(python_gen_cond_dep '
dev-python/python-systemd[${PYTHON_USEDEP}]
')
)
"
BDEPEND="
$(python_gen_cond_dep '
dev-python/setuptools[${PYTHON_USEDEP}]
')
test? (
$(python_gen_cond_dep '
dev-python/aiosmtpd[${PYTHON_USEDEP}]
')
)
"
DOCS=( ChangeLog DEVELOP README.md THANKS TODO doc/run-rootless.txt )
PATCHES=(
"${FILESDIR}"/${PN}-0.11.2-adjust-apache-logs-paths.patch
"${FILESDIR}"/${PN}-1.0.2-umask-tests.patch
"${FILESDIR}"/${PN}-1.1.0-openssh-9.8.patch
"${FILESDIR}"/${PN}-1.1.0-openssh-9.8-fixups.patch
"${FILESDIR}"/${PN}-1.1.0-openrc-nftables.patch
"${FILESDIR}"/${PN}-1.1.0-systemd-order.patch
)
src_prepare() {
default
# Replace /var/run with /run, but not in the top source directory
find . -mindepth 2 -type f -exec \
sed -i -e 's|/var\(/run/fail2ban\)|\1|g' {} + || die
}
src_compile() {
edo ${EPYTHON} setup.py build
}
src_test() {
# Skip testRepairDb for bug #907348 (didn't always fail..)
# https://github.com/fail2ban/fail2ban/issues/3586
bin/fail2ban-testcases \
--no-network \
--ignore databasetestcase.DatabaseTest.testRepairDb \
--verbosity=4 || die "Tests failed with ${EPYTHON}"
# Workaround for bug #790251
rm -rf fail2ban.egg-info || die
}
src_install() {
edo ${EPYTHON} setup.py install --prefix="${EPREFIX}/usr" --root="${D}"
python_fix_shebang "${ED}"/usr/bin
python_optimize
einstalldocs
rm -rf "${ED}"/usr/share/doc/${PN} "${ED}"/run || die
newconfd files/fail2ban-openrc.conf ${PN}
# These two are placed in the ${BUILD_DIR} after being "built"
# in install_scripts().
newinitd "${S}"/build/fail2ban-openrc.init ${PN}
systemd_dounit "${S}"/build/${PN}.service
dotmpfiles files/${PN}-tmpfiles.conf
doman man/*.{1,5}
# Use INSTALL_MASK if you do not want to touch /etc/logrotate.d.
# See http://thread.gmane.org/gmane.linux.gentoo.devel/35675
insinto /etc/logrotate.d
newins files/${PN}-logrotate ${PN}
keepdir /var/lib/${PN}
newbashcomp files/bash-completion ${PN}-client
bashcomp_alias ${PN}-client ${PN}-server ${PN}-regex
}
pkg_preinst() {
has_version "<${CATEGORY}/${PN}-0.7"
previous_less_than_0_7=$?
}
pkg_postinst() {
tmpfiles_process ${PN}-tmpfiles.conf
if [[ ${previous_less_than_0_7} == 0 ]] ; then
elog
elog "Configuration files are now in /etc/fail2ban/"
elog "You probably have to manually update your configuration"
elog "files before restarting Fail2Ban!"
elog
elog "Fail2Ban is not installed under /usr/lib anymore. The"
elog "new location is under /usr/share."
elog
elog "You are upgrading from version 0.6.x, please see:"
elog "http://www.fail2ban.org/wiki/index.php/HOWTO_Upgrade_from_0.6_to_0.8"
fi
if ! has_version dev-python/pyinotify ; then
elog "For most jail.conf configurations, it is recommended you install"
elog "dev-python/pyinotify to control how log file modifications are detected"
fi
if ! has_version dev-lang/python[sqlite] ; then
elog "If you want to use ${PN}'s persistent database, then reinstall"
elog "dev-lang/python with USE=sqlite. If you do not use the"
elog "persistent database feature, then you should set"
elog "dbfile = :memory: in fail2ban.conf accordingly."
fi
}

View File

@@ -55,6 +55,7 @@ DOCS=( ChangeLog DEVELOP README.md THANKS TODO doc/run-rootless.txt )
PATCHES=(
"${FILESDIR}"/${PN}-0.11.2-adjust-apache-logs-paths.patch
"${FILESDIR}"/${PN}-1.0.2-umask-tests.patch
"${FILESDIR}"/${PN}-1.1.0-systemd-order.patch
)
src_prepare() {

View File

@@ -0,0 +1,14 @@
https://bugs.gentoo.org/871996
--- a/files/fail2ban.service.in
+++ b/files/fail2ban.service.in
@@ -1,7 +1,10 @@
[Unit]
Description=Fail2Ban Service
Documentation=man:fail2ban(1)
+
+Before=iptables-store.service ip6tables-store.service
After=network.target iptables.service firewalld.service ip6tables.service ipset.service nftables.service
+After=iptables-restore.service ip6tables-restore.service
PartOf=iptables.service firewalld.service ip6tables.service ipset.service nftables.service
[Service]