diff --git a/gnu/local.mk b/gnu/local.mk
index acd41797b9..31569033bc 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -758,6 +758,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/tests/package-management.scm		\
   %D%/tests/reconfigure.scm			\
   %D%/tests/rsync.scm				\
+  %D%/tests/security.scm			\
   %D%/tests/security-token.scm			\
   %D%/tests/singularity.scm			\
   %D%/tests/ssh.scm				\
diff --git a/gnu/tests/security.scm b/gnu/tests/security.scm
new file mode 100644
index 0000000000..4003eff1e5
--- /dev/null
+++ b/gnu/tests/security.scm
@@ -0,0 +1,314 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2022 muradm <mail@muradm.net>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu tests security)
+  #:use-module (guix gexp)
+  #:use-module (gnu packages admin)
+  #:use-module (gnu services)
+  #:use-module (gnu services security)
+  #:use-module (gnu services ssh)
+  #:use-module (gnu system)
+  #:use-module (gnu system vm)
+  #:use-module (gnu tests)
+  #:export (%test-fail2ban-basic
+            %test-fail2ban-simple
+            %test-fail2ban-extending))
+
+
+;;;
+;;; fail2ban tests
+;;;
+
+(define (run-fail2ban-basic-test)
+
+  (define os
+    (marionette-operating-system
+     (simple-operating-system
+      (service fail2ban-service-type))
+     #:imported-modules '((gnu services herd)
+                          (guix combinators))))
+
+  (define vm
+    (virtual-machine
+     (operating-system os)
+     (port-forwardings '())))
+
+  (define test
+    (with-imported-modules '((gnu build marionette)
+                             (guix build utils))
+      #~(begin
+          (use-modules (srfi srfi-64)
+                       (gnu build marionette))
+
+          (define marionette (make-marionette (list #$vm)))
+
+          (define (wait-for-unix-socket-m socket)
+            (wait-for-unix-socket socket marionette))
+
+          (test-runner-current (system-test-runner #$output))
+          (test-begin "fail2ban-basic-test")
+
+          (test-assert "fail2ban running"
+            (marionette-eval
+             '(begin
+                (use-modules (gnu services herd))
+                (start-service 'fail2ban))
+             marionette))
+
+          (test-assert "fail2ban socket ready"
+            (wait-for-unix-socket-m
+             "/var/run/fail2ban/fail2ban.sock"))
+
+          (test-assert "fail2ban pid ready"
+            (marionette-eval
+             '(file-exists? "/var/run/fail2ban/fail2ban.pid")
+             marionette))
+
+          (test-assert "fail2ban log file"
+            (marionette-eval
+             '(file-exists? "/var/log/fail2ban.log")
+             marionette))
+
+          (test-end))))
+
+  (gexp->derivation "fail2ban-basic-test" test))
+
+(define %test-fail2ban-basic
+  (system-test
+   (name "fail2ban-basic")
+   (description "Test basic fail2ban running capability.")
+   (value (run-fail2ban-basic-test))))
+
+(define %fail2ban-server-cmd
+  (program-file
+   "fail2ban-server-cmd"
+   #~(begin
+       (let ((cmd #$(file-append fail2ban "/bin/fail2ban-server")))
+         (apply execl cmd cmd `("-p" "/var/run/fail2ban/fail2ban.pid"
+                                "-s" "/var/run/fail2ban/fail2ban.sock"
+                                ,@(cdr (program-arguments))))))))
+
+(define (run-fail2ban-simple-test)
+
+  (define os
+    (marionette-operating-system
+     (simple-operating-system
+      (service
+       fail2ban-service-type
+       (fail2ban-configuration
+        (jails
+         (list
+          (fail2ban-jail-configuration (name "sshd") (enabled #t)))))))
+     #:imported-modules '((gnu services herd)
+                          (guix combinators))))
+
+  (define vm
+    (virtual-machine
+     (operating-system os)
+     (port-forwardings '())))
+
+  (define test
+    (with-imported-modules '((gnu build marionette)
+                             (guix build utils))
+      #~(begin
+          (use-modules (srfi srfi-64)
+                       (ice-9 popen)
+                       (ice-9 rdelim)
+                       (rnrs io ports)
+                       (gnu build marionette)
+                       (guix build utils))
+
+          (define marionette (make-marionette (list #$vm)))
+
+          (define (wait-for-unix-socket-m socket)
+            (wait-for-unix-socket socket marionette))
+
+          (test-runner-current (system-test-runner #$output))
+          (test-begin "fail2ban-simple-test")
+
+          (test-assert "fail2ban running"
+            (marionette-eval
+             '(begin
+                (use-modules (gnu services herd))
+                (start-service 'fail2ban))
+             marionette))
+
+          (test-assert "fail2ban socket ready"
+            (wait-for-unix-socket-m
+             "/var/run/fail2ban/fail2ban.sock"))
+
+          (test-assert "fail2ban pid ready"
+            (marionette-eval
+             '(file-exists? "/var/run/fail2ban/fail2ban.pid")
+             marionette))
+
+          (test-assert "fail2ban log file"
+            (marionette-eval
+             '(file-exists? "/var/log/fail2ban.log")
+             marionette))
+
+          (test-equal "fail2ban sshd jail running"
+            '("Status for the jail: sshd"
+              "|- Filter"
+              "|  |- Currently failed:\t0"
+              "|  |- Total failed:\t0"
+              "|  `- File list:\t/var/log/secure"
+              "`- Actions"
+              "   |- Currently banned:\t0"
+              "   |- Total banned:\t0"
+              "   `- Banned IP list:\t"
+              "")
+            (marionette-eval
+             '(begin
+                (use-modules (ice-9 rdelim) (ice-9 popen) (rnrs io ports))
+                (let ((call-command
+                       (lambda (cmd)
+                         (let* ((err-cons (pipe))
+                                (port (with-error-to-port (cdr err-cons)
+                                        (lambda () (open-input-pipe cmd))))
+                                (_ (setvbuf (car err-cons) 'block
+                                            (* 1024 1024 16)))
+                                (result (read-delimited "" port)))
+                           (close-port (cdr err-cons))
+                           (values result (read-delimited "" (car err-cons)))))))
+                  (string-split
+                   (call-command
+                    (string-join (list #$%fail2ban-server-cmd "status" "sshd") " "))
+                   #\newline)))
+             marionette))
+
+          (test-equal "fail2ban sshd jail running"
+            0
+            (marionette-eval
+             '(status:exit-val (system* #$%fail2ban-server-cmd "status" "sshd"))
+             marionette))
+
+          (test-end))))
+
+  (gexp->derivation "fail2ban-simple-test" test))
+
+(define %test-fail2ban-simple
+  (system-test
+   (name "fail2ban-simple")
+   (description "Test simple fail2ban running capability.")
+   (value (run-fail2ban-simple-test))))
+
+(define (run-fail2ban-extending-test)
+
+  (define os
+    (marionette-operating-system
+     (simple-operating-system
+      (service
+       (fail2ban-jail-service
+        openssh-service-type
+        (fail2ban-jail-configuration
+         (name "sshd") (enabled #t)))
+       (openssh-configuration)))
+     #:imported-modules '((gnu services herd)
+                          (guix combinators))))
+
+  (define vm
+    (virtual-machine
+     (operating-system os)
+     (port-forwardings '())))
+
+  (define test
+    (with-imported-modules '((gnu build marionette)
+                             (guix build utils))
+      #~(begin
+          (use-modules (srfi srfi-64)
+                       (ice-9 popen)
+                       (ice-9 rdelim)
+                       (rnrs io ports)
+                       (gnu build marionette)
+                       (guix build utils))
+
+          (define marionette (make-marionette (list #$vm)))
+
+          (define (wait-for-unix-socket-m socket)
+            (wait-for-unix-socket socket marionette))
+
+          (test-runner-current (system-test-runner #$output))
+          (test-begin "fail2ban-extending-test")
+
+          (test-assert "sshd running"
+            (marionette-eval
+             '(begin
+                (use-modules (gnu services herd))
+                (start-service 'ssh-daemon))
+             marionette))
+
+          (test-assert "fail2ban socket ready"
+            (wait-for-unix-socket-m
+             "/var/run/fail2ban/fail2ban.sock"))
+
+          (test-assert "fail2ban pid ready"
+            (marionette-eval
+             '(file-exists? "/var/run/fail2ban/fail2ban.pid")
+             marionette))
+
+          (test-assert "fail2ban log file"
+            (marionette-eval
+             '(file-exists? "/var/log/fail2ban.log")
+             marionette))
+
+          (test-equal "fail2ban sshd jail running"
+            '("Status for the jail: sshd"
+              "|- Filter"
+              "|  |- Currently failed:\t0"
+              "|  |- Total failed:\t0"
+              "|  `- File list:\t/var/log/secure"
+              "`- Actions"
+              "   |- Currently banned:\t0"
+              "   |- Total banned:\t0"
+              "   `- Banned IP list:\t"
+              "")
+            (marionette-eval
+             '(begin
+                (use-modules (ice-9 rdelim) (ice-9 popen) (rnrs io ports))
+                (let ((call-command
+                       (lambda (cmd)
+                         (let* ((err-cons (pipe))
+                                (port (with-error-to-port (cdr err-cons)
+                                        (lambda () (open-input-pipe cmd))))
+                                (_ (setvbuf (car err-cons) 'block
+                                            (* 1024 1024 16)))
+                                (result (read-delimited "" port)))
+                           (close-port (cdr err-cons))
+                           (values result (read-delimited "" (car err-cons)))))))
+                  (string-split
+                   (call-command
+                    (string-join (list #$%fail2ban-server-cmd "status" "sshd") " "))
+                   #\newline)))
+             marionette))
+
+          (test-equal "fail2ban sshd jail running"
+            0
+            (marionette-eval
+             '(status:exit-val (system* #$%fail2ban-server-cmd "status" "sshd"))
+             marionette))
+
+          (test-end))))
+
+  (gexp->derivation "fail2ban-extending-test" test))
+
+(define %test-fail2ban-extending
+  (system-test
+   (name "fail2ban-extending")
+   (description "Test extending fail2ban running capability.")
+   (value (run-fail2ban-extending-test))))
