all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
To: muradm <mail@muradm.net>
Cc: 56608@debbugs.gnu.org
Subject: [bug#56608] [PATCH v2 2/2] gnu: tests: Add fail2ban tests.
Date: Mon, 22 Aug 2022 15:13:09 -0400	[thread overview]
Message-ID: <87edx8gkhm.fsf@gmail.com> (raw)
In-Reply-To: <20220822172607.31515-3-mail@muradm.net> (muradm's message of "Mon, 22 Aug 2022 20:26:07 +0300")

Hi,

muradm <mail@muradm.net> writes:

[...]

> --- /dev/null
> +++ b/gnu/tests/security.scm

I'd keep the tests with the introductory commit (squashed in preceding
one).

> @@ -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))
> +
> +\f
> +;;;
> +;;; 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))))
                             ^ (guix combinators) seems unused

> +  (define vm
> +    (virtual-machine
> +     (operating-system os)
> +     (port-forwardings '())))

(define vm (virtual-machine (operating-system os))) should be
sufficient.

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

Overkill as used once in scope.

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

I like to test that services can be restarted too, as in my experience
there can be races and other situations that may cause them to fail
restarting.

> +
> +          (test-assert "fail2ban socket ready"
> +            (wait-for-unix-socket-m
> +             "/var/run/fail2ban/fail2ban.sock"))

Same comment as above.

> +          (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))))
                             ^ (guix combinators) not needed
                             
> +
> +  (define vm
> +    (virtual-machine
> +     (operating-system os)
> +     (port-forwardings '())))

Same comment as above.

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

Likewise.

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

Perhaps this could be turned into an Shepherd action, and the Guile
procedure could do the above to return the text output; to simplify the
test and reduce boilerplate, while providing value to the user.

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

Same comment as above w.r.t. (guix combinators)
> +
> +  (define vm
> +    (virtual-machine
> +     (operating-system os)
> +     (port-forwardings '())))

Same comment as above.

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

Same comment as above.

> +          (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

Perhaps %test-fail2ban-extension ?  Otherwise, that last test seems to
test exactly the same things as the preceding one, so there should be a
procedure to generate the test, taking the OS as an argument to avoid
code duplication.

Thanks for working on this!

Maxim




  reply	other threads:[~2022-08-22 19:14 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-17  2:32 [bug#56608] [PATCH] gnu: security: Add fail2ban-service-type muradm
2022-08-03 16:09 ` Maxim Cournoyer
2022-08-22 17:26   ` [bug#56608] [PATCH v2 0/2] " muradm
2022-08-22 17:26     ` [bug#56608] [PATCH v2 1/2] gnu: security: " muradm
2022-08-22 18:53       ` Maxim Cournoyer
2022-08-23 18:22         ` muradm
2022-08-22 17:26     ` [bug#56608] [PATCH v2 2/2] gnu: tests: Add fail2ban tests muradm
2022-08-22 19:13       ` Maxim Cournoyer [this message]
2022-08-23 18:51         ` muradm
2022-08-23 20:13           ` [bug#56608] [PATCH v3] gnu: security: Add fail2ban-service-type muradm
2022-08-29  2:01             ` bug#56608: " Maxim Cournoyer
2022-08-23 20:19           ` [bug#56608] [PATCH v2 2/2] gnu: tests: Add fail2ban tests muradm

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87edx8gkhm.fsf@gmail.com \
    --to=maxim.cournoyer@gmail.com \
    --cc=56608@debbugs.gnu.org \
    --cc=mail@muradm.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.