Subject: [bug#78066] [PATCH v2 2/5] gnu: fail2ban: Update to 1.1.0.

From: Nicolas Graves <[email-masked]>
Date: Sun, 27 Apr 2025 11:08:09 +0200

* gnu/packages/patches/fail2ban-0.11.2_CVE-2021-32749.patch,
  gnu/packages/fail2ban-0.11.2_fix-setuptools-drop-2to3.patch,
  gnu/packages/patches/fail2ban-0.11.2_fix-test-suite.patch,
  gnu/packages/patches/fail2ban-python310-server-action.patch,
  gnu/packages/fail2ban-python310-server-actions.patch: Delete patches.

* gnu/local.mk: Deregister patches.

* gnu/packages/admin.scm (fail2ban): Update to 1.1.0.
  [source]<snippet>: Use (srfi srfi-26) for readability.
  <patches>: Deregister patches.
  [build-system]: Switch to pyproject-build-system.
  [arguments]<phases>: Remove phase 'invoke-2to3.  Add phase
  'avoid-external-binary-in-/bin to avoid creating a symlink to
  python-wrapper binary during installation (current 'install phase
  breaks otherwise).
  [native-inputs]: Add python-setuptools, python-wheel.
---
 gnu/local.mk                                  |   6 -
 gnu/packages/admin.scm                        |  33 ++--
 .../fail2ban-0.11.2_CVE-2021-32749.patch      | 155 ------------------
 ...2ban-0.11.2_fix-setuptools-drop-2to3.patch |  64 --------
 .../fail2ban-0.11.2_fix-test-suite.patch      |  48 ------
 .../fail2ban-python310-server-action.patch    |  27 ---
 .../fail2ban-python310-server-actions.patch   |  25 ---
 .../fail2ban-python310-server-jails.patch     |  25 ---
 8 files changed, 15 insertions(+), 368 deletions(-)
 delete mode 100644 gnu/packages/patches/fail2ban-0.11.2_CVE-2021-32749.patch
 delete mode 100644 gnu/packages/patches/fail2ban-0.11.2_fix-setuptools-drop-2to3.patch
 delete mode 100644 gnu/packages/patches/fail2ban-0.11.2_fix-test-suite.patch
 delete mode 100644 gnu/packages/patches/fail2ban-python310-server-action.patch
 delete mode 100644 gnu/packages/patches/fail2ban-python310-server-actions.patch
 delete mode 100644 gnu/packages/patches/fail2ban-python310-server-jails.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 3f5e4cec38..be2639eeb4 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1259,13 +1259,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/expat-CVE-2024-45492.patch	\
   %D%/packages/patches/extempore-unbundle-external-dependencies.patch	\
   %D%/packages/patches/extundelete-e2fsprogs-1.44.patch		\
-  %D%/packages/patches/fail2ban-0.11.2_CVE-2021-32749.patch	\
-  %D%/packages/patches/fail2ban-0.11.2_fix-setuptools-drop-2to3.patch	\
-  %D%/packages/patches/fail2ban-0.11.2_fix-test-suite.patch	\
   %D%/packages/patches/fail2ban-paths-guix-conf.patch		\
-  %D%/packages/patches/fail2ban-python310-server-action.patch	\
-  %D%/packages/patches/fail2ban-python310-server-actions.patch	\
-  %D%/packages/patches/fail2ban-python310-server-jails.patch	\
   %D%/packages/patches/faiss-tests-CMakeLists-find-googletest.patch	\
   %D%/packages/patches/falcosecurity-libs-shared-build.patch	\
   %D%/packages/patches/farstream-gupnp.patch                         \
diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index c6c5188d81..689e9bcd4a 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -6231,7 +6231,7 @@ (define-public sysdig
 (define-public fail2ban
   (package
     (name "fail2ban")
-    (version "0.11.2")
+    (version "1.1.0")
     (source (origin
               (method git-fetch)
               (uri (git-reference
@@ -6240,8 +6240,8 @@ (define-public fail2ban
               (file-name (git-file-name name version))
               (sha256
                (base32
-                "00d9q8m284q2wy6q462nipzszplfbvrs9fhgn0y3imwsc24kv1db"))
-              (modules '((guix build utils)))
+                "0lfakna6ad2xwz95sjxzkavipcsxiy7ybavkdkf9zzmspf2ws4yk"))
+              (modules '((guix build utils) (srfi srfi-26)))
               (snippet
                '(begin
                   ;; deleting things that are not feasible to fix
@@ -6289,10 +6289,9 @@ (define-public fail2ban
                     (("'/usr/share/doc/fail2ban'")
                      "'usr/share/doc/fail2ban'"))
                   ;; disable tests performing unacceptable side-effects
-                  (let ((make-suite (lambda (t)
-                                      (string-append
-                                       "tests.addTest.unittest.makeSuite."
-                                       t ".."))))
+                  (let ((make-suite (cut string-append
+                                         "tests.addTest\\(loadTests\\("
+                                         <> "\\)\\)")))
                     (substitute* "fail2ban/tests/utils.py"
                       (((make-suite "actiontestcase.CommandActionTest"))
                        "")
@@ -6311,20 +6310,16 @@ (define-public fail2ban
                       (((make-suite
                          "servertestcase.ServerConfigReaderTests"))
                        "")))))
-              (patches (search-patches
-                        "fail2ban-0.11.2_fix-setuptools-drop-2to3.patch"
-                        "fail2ban-python310-server-action.patch"
-                        "fail2ban-python310-server-actions.patch"
-                        "fail2ban-python310-server-jails.patch"
-                        "fail2ban-0.11.2_fix-test-suite.patch"
-                        "fail2ban-0.11.2_CVE-2021-32749.patch"
-                        "fail2ban-paths-guix-conf.patch"))))
-    (build-system python-build-system)
+              (patches (search-patches "fail2ban-paths-guix-conf.patch"))))
+    (build-system pyproject-build-system)
     (arguments
      '(#:phases (modify-phases %standard-phases
-                  (add-before 'build 'invoke-2to3
+                  (add-after 'unpack 'avoid-external-binary-in-/bin
                     (lambda _
-                      (invoke "./fail2ban-2to3")))
+                      (delete-file "fail2ban/setup.py")
+                      (substitute* '("bin/fail2ban-testcases"
+                                     "setup.py")
+                        ((".*updatePyExec.*") ""))))
                   (add-before 'install 'fix-default-config
                     (lambda* (#:key outputs #:allow-other-keys)
                       (substitute* '("config/paths-common.conf"
@@ -6410,6 +6405,8 @@ (define-public fail2ban
                                       "fail2ban-testcases"))
                           (for-each install-man5
                                     '("jail.conf")))))))))
+    (native-inputs
+     (list python-setuptools python-wheel))
     (inputs (list gawk
                   coreutils-minimal
                   curl
diff --git a/gnu/packages/patches/fail2ban-0.11.2_CVE-2021-32749.patch b/gnu/packages/patches/fail2ban-0.11.2_CVE-2021-32749.patch
deleted file mode 100644
index d3c677918c..0000000000
--- a/gnu/packages/patches/fail2ban-0.11.2_CVE-2021-32749.patch
+++ /dev/null
@@ -1,155 +0,0 @@
-From 410a6ce5c80dd981c22752da034f2529b5eee844 Mon Sep 17 00:00:00 2001
-From: sebres <[email-masked]>
-Date: Mon, 21 Jun 2021 17:12:53 +0200
-Subject: [PATCH] fixed possible RCE vulnerability, unset escape variable
- (default tilde) stops consider "~" char after new-line as composing escape
- sequence
-
----
- config/action.d/complain.conf         | 2 +-
- config/action.d/dshield.conf          | 2 +-
- config/action.d/mail-buffered.conf    | 8 ++++----
- config/action.d/mail-whois-lines.conf | 2 +-
- config/action.d/mail-whois.conf       | 6 +++---
- config/action.d/mail.conf             | 6 +++---
- 6 files changed, 13 insertions(+), 13 deletions(-)
-
-diff --git a/config/action.d/complain.conf b/config/action.d/complain.conf
-index 3a5f882c9f..4d73b05859 100644
---- a/config/action.d/complain.conf
-+++ b/config/action.d/complain.conf
-@@ -102,7 +102,7 @@ logpath = /dev/null
- # Notes.:  Your system mail command. Is passed 2 args: subject and recipient
- # Values:  CMD
- #
--mailcmd = mail -s
-+mailcmd = mail -E 'set escape' -s
- 
- # Option:  mailargs
- # Notes.:  Additional arguments to mail command. e.g. for standard Unix mail:
-diff --git a/config/action.d/dshield.conf b/config/action.d/dshield.conf
-index c128bef348..3d5a7a53a9 100644
---- a/config/action.d/dshield.conf
-+++ b/config/action.d/dshield.conf
-@@ -179,7 +179,7 @@ tcpflags =
- # Notes.:  Your system mail command. Is passed 2 args: subject and recipient
- # Values:  CMD
- #
--mailcmd = mail -s
-+mailcmd = mail -E 'set escape' -s
- 
- # Option:  mailargs
- # Notes.:  Additional arguments to mail command. e.g. for standard Unix mail:
-diff --git a/config/action.d/mail-buffered.conf b/config/action.d/mail-buffered.conf
-index 325f185b2f..79b841049c 100644
---- a/config/action.d/mail-buffered.conf
-+++ b/config/action.d/mail-buffered.conf
-@@ -17,7 +17,7 @@ actionstart = printf %%b "Hi,\n
-               The jail <name> has been started successfully.\n
-               Output will be buffered until <lines> lines are available.\n
-               Regards,\n
--              Fail2Ban"|mail -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest>
-+              Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest>
- 
- # Option:  actionstop
- # Notes.:  command executed at the stop of jail (or at the end of Fail2Ban)
-@@ -28,13 +28,13 @@ actionstop = if [ -f <tmpfile> ]; then
-                  These hosts have been banned by Fail2Ban.\n
-                  `cat <tmpfile>`
-                  Regards,\n
--                 Fail2Ban"|mail -s "[Fail2Ban] <name>: Summary from <fq-hostname>" <dest>
-+                 Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: Summary from <fq-hostname>" <dest>
-                  rm <tmpfile>
-              fi
-              printf %%b "Hi,\n
-              The jail <name> has been stopped.\n
-              Regards,\n
--             Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
-+             Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
- 
- # Option:  actioncheck
- # Notes.:  command executed once before each actionban command
-@@ -55,7 +55,7 @@ actionban = printf %%b "`date`: <ip> (<failures> failures)\n" >> <tmpfile>
-                 These hosts have been banned by Fail2Ban.\n
-                 `cat <tmpfile>`
-                 \nRegards,\n
--                Fail2Ban"|mail -s "[Fail2Ban] <name>: Summary" <dest>
-+                Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: Summary" <dest>
-                 rm <tmpfile>
-             fi
- 
-diff --git a/config/action.d/mail-whois-lines.conf b/config/action.d/mail-whois-lines.conf
-index 3a3e56b2c7..d2818cb9b9 100644
---- a/config/action.d/mail-whois-lines.conf
-+++ b/config/action.d/mail-whois-lines.conf
-@@ -72,7 +72,7 @@ actionunban =
- # Notes.:  Your system mail command. Is passed 2 args: subject and recipient
- # Values:  CMD
- #
--mailcmd = mail -s
-+mailcmd = mail -E 'set escape' -s
- 
- # Default name of the chain
- #
-diff --git a/config/action.d/mail-whois.conf b/config/action.d/mail-whois.conf
-index 7fea34c40d..ab33b616dc 100644
---- a/config/action.d/mail-whois.conf
-+++ b/config/action.d/mail-whois.conf
-@@ -20,7 +20,7 @@ norestored = 1
- actionstart = printf %%b "Hi,\n
-               The jail <name> has been started successfully.\n
-               Regards,\n
--              Fail2Ban"|mail -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest>
-+              Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest>
- 
- # Option:  actionstop
- # Notes.:  command executed at the stop of jail (or at the end of Fail2Ban)
-@@ -29,7 +29,7 @@ actionstart = printf %%b "Hi,\n
- actionstop = printf %%b "Hi,\n
-              The jail <name> has been stopped.\n
-              Regards,\n
--             Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
-+             Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
- 
- # Option:  actioncheck
- # Notes.:  command executed once before each actionban command
-@@ -49,7 +49,7 @@ actionban = printf %%b "Hi,\n
-             Here is more information about <ip> :\n
-             `%(_whois_command)s`\n
-             Regards,\n
--            Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest>
-+            Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest>
- 
- # Option:  actionunban
- # Notes.:  command executed when unbanning an IP. Take care that the
-diff --git a/config/action.d/mail.conf b/config/action.d/mail.conf
-index 5d8c0e154c..f4838ddcb6 100644
---- a/config/action.d/mail.conf
-+++ b/config/action.d/mail.conf
-@@ -16,7 +16,7 @@ norestored = 1
- actionstart = printf %%b "Hi,\n
-               The jail <name> has been started successfully.\n
-               Regards,\n
--              Fail2Ban"|mail -s "[Fail2Ban] <name>: started  on <fq-hostname>" <dest>
-+              Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: started  on <fq-hostname>" <dest>
- 
- # Option:  actionstop
- # Notes.:  command executed at the stop of jail (or at the end of Fail2Ban)
-@@ -25,7 +25,7 @@ actionstart = printf %%b "Hi,\n
- actionstop = printf %%b "Hi,\n
-              The jail <name> has been stopped.\n
-              Regards,\n
--             Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
-+             Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
- 
- # Option:  actioncheck
- # Notes.:  command executed once before each actionban command
-@@ -43,7 +43,7 @@ actionban = printf %%b "Hi,\n
-             The IP <ip> has just been banned by Fail2Ban after
-             <failures> attempts against <name>.\n
-             Regards,\n
--            Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest>
-+            Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest>
- 
- # Option:  actionunban
- # Notes.:  command executed when unbanning an IP. Take care that the
diff --git a/gnu/packages/patches/fail2ban-0.11.2_fix-setuptools-drop-2to3.patch b/gnu/packages/patches/fail2ban-0.11.2_fix-setuptools-drop-2to3.patch
deleted file mode 100644
index b0b14364b1..0000000000
--- a/gnu/packages/patches/fail2ban-0.11.2_fix-setuptools-drop-2to3.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 5ac303df8a171f748330d4c645ccbf1c2c7f3497 Mon Sep 17 00:00:00 2001
-From: sebres <[email-masked]>
-Date: Sun, 19 Sep 2021 18:49:18 +0200
-Subject: [PATCH] fix gh-3098: build fails with error in fail2ban setup
- command: use_2to3 is invalid (setuptools 58+)
-
----
- setup.py | 16 +---------------
- 1 file changed, 1 insertion(+), 15 deletions(-)
-
-diff --git a/setup.py b/setup.py
-index f4c2550f6f..98413273c5 100755
---- a/setup.py
-+++ b/setup.py
-@@ -48,7 +48,7 @@
- from glob import glob
- 
- from fail2ban.setup import updatePyExec
--
-+from fail2ban.version import version
- 
- source_dir = os.path.realpath(os.path.dirname(
- 	# __file__ seems to be overwritten sometimes on some python versions (e.g. bug of 2.6 by running under cProfile, etc.):
-@@ -112,22 +112,12 @@ def update_scripts(self, dry_run=False):
- # Wrapper to specify fail2ban own options:
- class install_command_f2b(install):
- 	user_options = install.user_options + [
--		('disable-2to3', None, 'Specify to deactivate 2to3, e.g. if the install runs from fail2ban test-cases.'),
- 		('without-tests', None, 'without tests files installation'),
- 	]
- 	def initialize_options(self):
--		self.disable_2to3 = None
- 		self.without_tests = not with_tests
- 		install.initialize_options(self)
- 	def finalize_options(self):
--		global _2to3
--		## in the test cases 2to3 should be already done (fail2ban-2to3):
--		if self.disable_2to3:
--			_2to3 = False
--		if _2to3:
--			cmdclass = self.distribution.cmdclass
--			cmdclass['build_py'] = build_py_2to3
--			cmdclass['build_scripts'] = build_scripts_2to3
- 		if self.without_tests:
- 			self.distribution.scripts.remove('bin/fail2ban-testcases')
- 
-@@ -178,7 +168,6 @@ def run(self):
- if setuptools:
- 	setup_extra = {
- 		'test_suite': "fail2ban.tests.utils.gatherTests",
--		'use_2to3': True,
- 	}
- else:
- 	setup_extra = {}
-@@ -202,9 +191,6 @@ def run(self):
- 		('/usr/share/doc/fail2ban', doc_files)
- 	)
- 
--# Get version number, avoiding importing fail2ban.
--# This is due to tests not functioning for python3 as 2to3 takes place later
--exec(open(join("fail2ban", "version.py")).read())
- 
- setup(
- 	name = "fail2ban",
diff --git a/gnu/packages/patches/fail2ban-0.11.2_fix-test-suite.patch b/gnu/packages/patches/fail2ban-0.11.2_fix-test-suite.patch
deleted file mode 100644
index 91d973e72e..0000000000
--- a/gnu/packages/patches/fail2ban-0.11.2_fix-test-suite.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 747d4683221b5584f9663695fb48145689b42ceb Mon Sep 17 00:00:00 2001
-From: sebres <[email-masked]>
-Date: Mon, 4 Jan 2021 02:42:38 +0100
-Subject: [PATCH] fixes century selector of %ExY and %Exy in datepattern for
- tests, considering interval from 2005 (alternate now) to now; + better
- grouping algorithm for resulting century RE
-
----
- fail2ban/server/strptime.py | 24 ++++++++++++++++++++++--
- 1 file changed, 22 insertions(+), 2 deletions(-)
-
-diff --git a/fail2ban/server/strptime.py b/fail2ban/server/strptime.py
-index 1464a96d1f..39fc795865 100644
---- a/fail2ban/server/strptime.py
-+++ b/fail2ban/server/strptime.py
-@@ -36,10 +36,30 @@ def _getYearCentRE(cent=(0,3), distance=3, now=(MyTime.now(), MyTime.alternateNo
- 	Thereby respect possible run in the test-cases (alternate date used there)
- 	"""
- 	cent = lambda year, f=cent[0], t=cent[1]: str(year)[f:t]
-+	def grp(exprset):
-+		c = None
-+		if len(exprset) > 1:
-+			for i in exprset:
-+				if c is None or i[0:-1] == c:
-+					c = i[0:-1]
-+				else:
-+					c = None
-+					break
-+			if not c:
-+				for i in exprset:
-+					if c is None or i[0] == c:
-+						c = i[0]
-+					else:
-+						c = None
-+						break
-+			if c:
-+				return "%s%s" % (c, grp([i[len(c):] for i in exprset]))
-+		return ("(?:%s)" % "|".join(exprset) if len(exprset[0]) > 1 else "[%s]" % "".join(exprset)) \
-+			if len(exprset) > 1 else "".join(exprset)
- 	exprset = set( cent(now[0].year + i) for i in (-1, distance) )
- 	if len(now) and now[1]:
--		exprset |= set( cent(now[1].year + i) for i in (-1, distance) )
--	return "(?:%s)" % "|".join(exprset) if len(exprset) > 1 else "".join(exprset)
-+		exprset |= set( cent(now[1].year + i) for i in xrange(-1, now[0].year-now[1].year+1, distance) )
-+	return grp(sorted(list(exprset)))
- 
- timeRE = TimeRE()
- 
diff --git a/gnu/packages/patches/fail2ban-python310-server-action.patch b/gnu/packages/patches/fail2ban-python310-server-action.patch
deleted file mode 100644
index 723d7f7aa6..0000000000
--- a/gnu/packages/patches/fail2ban-python310-server-action.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 2b6bb2c1bed8f7009631e8f8c306fa3160324a49 Mon Sep 17 00:00:00 2001
-From: "Sergey G. Brester" <[email-masked]>
-Date: Mon, 8 Feb 2021 17:19:24 +0100
-Subject: [PATCH] follow bpo-37324: :ref:`collections-abstract-base-classes`
- moved to the :mod:`collections.abc` module
-
-(since 3.10-alpha.5 `MutableMapping` is missing in collections module)
----
- fail2ban/server/action.py | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/fail2ban/server/action.py b/fail2ban/server/action.py
-index 3bc48fe046..f0f1e6f59a 100644
---- a/fail2ban/server/action.py
-+++ b/fail2ban/server/action.py
-@@ -30,7 +30,10 @@
- import threading
- import time
- from abc import ABCMeta
--from collections import MutableMapping
-+try:
-+	from collections.abc import MutableMapping
-+except ImportError:
-+	from collections import MutableMapping
- 
- from .failregex import mapTag2Opt
- from .ipdns import DNSUtils
diff --git a/gnu/packages/patches/fail2ban-python310-server-actions.patch b/gnu/packages/patches/fail2ban-python310-server-actions.patch
deleted file mode 100644
index e31316d28b..0000000000
--- a/gnu/packages/patches/fail2ban-python310-server-actions.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 42dee38ad2ac5c3f23bdf297d824022923270dd9 Mon Sep 17 00:00:00 2001
-From: "Sergey G. Brester" <[email-masked]>
-Date: Mon, 8 Feb 2021 17:25:45 +0100
-Subject: [PATCH] amend for `Mapping`
-
----
- fail2ban/server/actions.py | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/fail2ban/server/actions.py b/fail2ban/server/actions.py
-index b7b95b445a..897d907c1a 100644
---- a/fail2ban/server/actions.py
-+++ b/fail2ban/server/actions.py
-@@ -28,7 +28,10 @@
- import os
- import sys
- import time
--from collections import Mapping
-+try:
-+	from collections.abc import Mapping
-+except ImportError:
-+	from collections import Mapping
- try:
- 	from collections import OrderedDict
- except ImportError:
diff --git a/gnu/packages/patches/fail2ban-python310-server-jails.patch b/gnu/packages/patches/fail2ban-python310-server-jails.patch
deleted file mode 100644
index e5873c415e..0000000000
--- a/gnu/packages/patches/fail2ban-python310-server-jails.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 9f1d1f4fbd0804695a976beb191f2c49a2739834 Mon Sep 17 00:00:00 2001
-From: "Sergey G. Brester" <[email-masked]>
-Date: Mon, 8 Feb 2021 17:35:59 +0100
-Subject: [PATCH] amend for `Mapping` (jails)
-
----
- fail2ban/server/jails.py | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/fail2ban/server/jails.py b/fail2ban/server/jails.py
-index 972a8c4bd2..27e12ddf65 100644
---- a/fail2ban/server/jails.py
-+++ b/fail2ban/server/jails.py
-@@ -22,7 +22,10 @@
- __license__ = "GPL"
- 
- from threading import Lock
--from collections import Mapping
-+try:
-+	from collections.abc import Mapping
-+except ImportError:
-+	from collections import Mapping
- 
- from ..exceptions import DuplicateJailException, UnknownJailException
- from .jail import Jail
-- 
2.49.0