From: Arun Isaac <arunisaac@systemreboot.net>
To: "Ludovic Courtès" <ludo@gnu.org>
Cc: 32465@debbugs.gnu.org
Subject: [bug#32465] Add iptables service
Date: Fri, 14 Sep 2018 16:29:09 +0530 [thread overview]
Message-ID: <cu7efdwwdj6.fsf@systemreboot.net> (raw)
In-Reply-To: <cu7wos02sch.fsf@systemreboot.net>
[-- Attachment #1: Type: text/plain, Size: 755 bytes --]
Hi,
I generalized this service to work for both iptables and ip6tables. I
added system tests, and made the other corrections that were
suggested. Some questions follow.
- Is the example I added for the iptables.rules sufficient? I couldn't
find upstream documentation for the iptables.rules format. I suspect
it doesn't exist. Do you know of any upstream documentation that can
be referred to here?
- In the attached patch, the fourth test ("inetd echo service is
accessible after iptables firewall is stopped") doesn't work. In that
service, I am trying to stop the iptables service, but I'm not able
to. How do I programmatically stop the iptables service? Is what I
have done correct?
Any other feedback is also welcome.
Thank you.
[-- Attachment #2: 0001-gnu-services-Add-iptables-service.patch --]
[-- Type: text/x-patch, Size: 11331 bytes --]
From dcfdd0bd981aa9da4835f322173490e239048e65 Mon Sep 17 00:00:00 2001
From: Arun Isaac <arunisaac@systemreboot.net>
Date: Fri, 17 Aug 2018 16:39:07 +0530
Subject: [PATCH] gnu: services: Add iptables service.
* gnu/services/networking.scm (<iptables-configuration>): New record type.
(iptables-service-type): New variable.
* gnu/tests/networking.scm (run-iptables-test): New procedure.
(%test-iptables): New variable.
* doc/guix.texi (Networking Services): Document it.
---
doc/guix.texi | 48 ++++++++++++++
gnu/services/networking.scm | 56 ++++++++++++++++-
gnu/tests/networking.scm | 122 +++++++++++++++++++++++++++++++++++-
3 files changed, 224 insertions(+), 2 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index cccf166d0..7dd7f8fc9 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -11575,6 +11575,54 @@ Thus, it can be instantiated like this:
@end lisp
@end defvr
+@cindex iptables
+@defvr {Scheme Variable} iptables-service-type
+This is the service type to set up an iptables configuration. iptables is a
+packet filtering framework supported by the Linux kernel. This service
+supports configuring iptables for both IPv4 and IPv6. A simple example
+configuration rejecting all incoming connections except those to the ssh port
+22 is shown below.
+
+@lisp
+(service iptables-service-type
+ (iptables-configuration
+ (ipv4-rules (plain-file "iptables.rules" "*filter
+:INPUT ACCEPT
+:FORWARD ACCEPT
+:OUTPUT ACCEPT
+-A INPUT -p tcp --dport 22 -j ACCEPT
+-A INPUT -j REJECT --reject-with icmp-port-unreachable
+COMMIT
+"))
+ (ipv6-rules (plain-file "ip6tables.rules" "*filter
+:INPUT ACCEPT
+:FORWARD ACCEPT
+:OUTPUT ACCEPT
+-A INPUT -p tcp --dport 22 -j ACCEPT
+-A INPUT -j REJECT --reject-with icmp6-port-unreachable
+COMMIT
+"))))
+@end lisp
+@end defvr
+
+@deftp {Data Type} iptables-configuration
+The data type representing the configuration of iptables.
+
+@table @asis
+@item @code{iptables} (default: @code{iptables})
+The iptables package that provides @code{iptables-restore} and
+@code{ip6tables-restore}.
+@item @code{ipv4-rules} (default: @code{%iptables-accept-all-rules})
+The iptables rules to use. It will be passed to @code{iptables-restore}.
+This may be any ``file-like'' object (@pxref{G-Expressions, file-like
+objects}).
+@item @code{ipv6-rules} (default: @code{%iptables-accept-all-rules})
+The ip6tables rules to use. It will be passed to @code{ip6tables-restore}.
+This may be any ``file-like'' object (@pxref{G-Expressions, file-like
+objects}).
+@end table
+@end deftp
+
@cindex NTP
@cindex real time clock
@deffn {Scheme Procedure} ntp-service [#:ntp @var{ntp}] @
diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm
index b6b5ee3fe..bd1d5a270 100644
--- a/gnu/services/networking.scm
+++ b/gnu/services/networking.scm
@@ -8,6 +8,7 @@
;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
;;; Copyright © 2018 Tobias Geerinckx-Rice <me@tobias.gr>
;;; Copyright © 2018 Chris Marusich <cmmarusich@gmail.com>
+;;; Copyright © 2018 Arun Isaac <arunisaac@systemreboot.net>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -103,7 +104,14 @@
wpa-supplicant-service-type
openvswitch-service-type
- openvswitch-configuration))
+ openvswitch-configuration
+
+ iptables-configuration
+ iptables-configuration?
+ iptables-configuration-iptables
+ iptables-configuration-ipv4-rules
+ iptables-configuration-ipv6-rules
+ iptables-service-type))
;;; Commentary:
;;;
@@ -1108,4 +1116,50 @@ networking."))))
switch designed to enable massive network automation through programmatic
extension.")))
+;;;
+;;; iptables
+;;;
+
+(define %iptables-accept-all-rules
+ (plain-file "iptables-accept-all.rules"
+ "*filter
+:INPUT ACCEPT
+:FORWARD ACCEPT
+:OUTPUT ACCEPT
+COMMIT
+"))
+
+(define-record-type* <iptables-configuration>
+ iptables-configuration make-iptables-configuration iptables-configuration?
+ (iptables iptables-configuration-iptables
+ (default iptables))
+ (ipv4-rules iptables-configuration-ipv4-rules
+ (default %iptables-accept-all-rules))
+ (ipv6-rules iptables-configuration-ipv6-rules
+ (default %iptables-accept-all-rules)))
+
+(define iptables-shepherd-service
+ (match-lambda
+ (($ <iptables-configuration> iptables ipv4-rules ipv6-rules)
+ (let ((iptables-restore (file-append iptables "/sbin/iptables-restore"))
+ (ip6tables-restore (file-append iptables "/sbin/ip6tables-restore")))
+ (shepherd-service
+ (documentation "Packet filtering framework")
+ (provision '(iptables))
+ (start #~(lambda _
+ (invoke #$iptables-restore #$ipv4-rules)
+ (invoke #$ip6tables-restore #$ipv6-rules)))
+ (stop #~(lambda _
+ (invoke #$iptables-restore #$%iptables-accept-all-rules)
+ (invoke #$ip6tables-restore #$%iptables-accept-all-rules))))))))
+
+(define iptables-service-type
+ (service-type
+ (name 'iptables)
+ (description
+ "Run @command{iptables-restore}, setting up the specified rules.")
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ (compose list iptables-shepherd-service))))))
+
;;; networking.scm ends here
diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index 381c5caf1..58fe61a49 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2017 Thomas Danckaert <post@thomasdanckaert.be>
;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
;;; Copyright © 2018 Chris Marusich <cmmarusich@gmail.com>
+;;; Copyright © 2018 Arun Isaac <arunisaac@systemreboot.net>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -29,9 +30,11 @@
#:use-module (guix store)
#:use-module (guix monads)
#:use-module (gnu packages bash)
+ #:use-module (gnu packages linux)
#:use-module (gnu packages networking)
#:use-module (gnu services shepherd)
- #:export (%test-inetd %test-openvswitch %test-dhcpd %test-tor))
+ #:use-module (ice-9 match)
+ #:export (%test-inetd %test-openvswitch %test-dhcpd %test-tor %test-iptables))
(define %inetd-os
;; Operating system with 2 inetd services.
@@ -434,3 +437,120 @@ subnet 192.168.1.0 netmask 255.255.255.0 {
(name "tor")
(description "Test a running Tor daemon configuration.")
(value (run-tor-test))))
+
+(define* (run-iptables-test)
+ "Run tests of 'iptables-service-type'."
+ (define iptables-rules
+ "*filter
+:INPUT ACCEPT
+:FORWARD ACCEPT
+:OUTPUT ACCEPT
+-A INPUT -p tcp -m tcp --dport 7 -j REJECT --reject-with icmp-port-unreachable
+COMMIT
+")
+
+ (define ip6tables-rules
+ "*filter
+:INPUT ACCEPT
+:FORWARD ACCEPT
+:OUTPUT ACCEPT
+-A INPUT -p tcp -m tcp --dport 7 -j REJECT --reject-with icmp6-port-unreachable
+COMMIT
+")
+
+ (define inetd-echo-port 7)
+
+ (define os
+ (marionette-operating-system
+ (simple-operating-system
+ (dhcp-client-service)
+ (service inetd-service-type
+ (inetd-configuration
+ (entries (list
+ (inetd-entry
+ (name "echo")
+ (socket-type 'stream)
+ (protocol "tcp")
+ (wait? #f)
+ (user "root"))))))
+ (service iptables-service-type
+ (iptables-configuration
+ (ipv4-rules (plain-file "iptables.rules" iptables-rules))
+ (ipv6-rules (plain-file "ip6tables.rules" ip6tables-rules)))))
+ #:imported-modules '((gnu services herd))
+ #:requirements '(inetd iptables)))
+
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (use-modules (srfi srfi-64)
+ (gnu build marionette))
+ (define marionette
+ (make-marionette (list #$(virtual-machine os))))
+
+ (define (dump-iptables iptables-save marionette)
+ (marionette-eval
+ `(begin
+ (use-modules (ice-9 popen)
+ (ice-9 rdelim)
+ (ice-9 regex))
+ (call-with-output-string
+ (lambda (out)
+ (call-with-port
+ (open-pipe* OPEN_READ ,iptables-save)
+ (lambda (in)
+ (let loop ((line (read-line in)))
+ ;; iptables-save does not output rules in the exact
+ ;; same format we loaded using iptables-restore. It
+ ;; adds comments, packet counters, etc. We remove
+ ;; these additions.
+ (unless (eof-object? line)
+ (cond
+ ;; Remove comments
+ ((string-match "^#" line) #t)
+ ;; Remove packet counters
+ ((string-match "^:([A-Z]*) ([A-Z]*) .*" line)
+ => (lambda (match-record)
+ (format out ":~a ~a~%"
+ (match:substring match-record 1)
+ (match:substring match-record 2))))
+ ;; Pass other lines without modification
+ (else (display line out)
+ (newline out)))
+ (loop (read-line in)))))))))
+ marionette))
+
+ (mkdir #$output)
+ (chdir #$output)
+
+ (test-begin "iptables")
+
+ (test-equal "iptables-save dumps the same rules that were loaded"
+ (dump-iptables #$(file-append iptables "/sbin/iptables-save")
+ marionette)
+ #$iptables-rules)
+
+ (test-equal "ip6tables-save dumps the same rules that were loaded"
+ (dump-iptables #$(file-append iptables "/sbin/ip6tables-save")
+ marionette)
+ #$ip6tables-rules)
+
+ (test-error "iptables firewall blocks access to inetd echo service"
+ 'misc-error
+ (wait-for-tcp-port inetd-echo-port marionette #:timeout 5))
+
+ (test-assert "inetd echo service is accessible after iptables firewall is stopped"
+ (begin
+ (marionette-eval '(stop-service 'iptables) marionette)
+ (wait-for-tcp-port inetd-echo-port marionette #:timeout 5)))
+
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation "iptables" test))
+
+(define %test-iptables
+ (system-test
+ (name "iptables")
+ (description "Test a running iptables daemon.")
+ (value (run-iptables-test))))
--
2.18.0
next prev parent reply other threads:[~2018-09-14 11:00 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-17 11:24 [bug#32465] Add iptables service Arun Isaac
2018-09-04 13:14 ` Ludovic Courtès
2018-09-04 13:52 ` Julien Lepiller
2018-09-05 9:40 ` Arun Isaac
2018-09-10 12:51 ` Ludovic Courtès
2018-09-05 9:42 ` Arun Isaac
2018-09-14 10:59 ` Arun Isaac [this message]
2018-09-17 21:05 ` Ludovic Courtès
2018-09-18 6:24 ` Arun Isaac
2018-09-18 14:39 ` Ludovic Courtès
2018-09-18 16:02 ` Arun Isaac
2018-09-19 20:41 ` Ludovic Courtès
2018-09-20 7:50 ` bug#32465: " Arun Isaac
2018-09-11 6:53 ` [bug#32465] " Björn Höfling
2018-09-11 8:43 ` Arun Isaac
2018-09-15 12:27 ` Rutger Helling
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
List information: https://guix.gnu.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cu7efdwwdj6.fsf@systemreboot.net \
--to=arunisaac@systemreboot.net \
--cc=32465@debbugs.gnu.org \
--cc=ludo@gnu.org \
/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 public inbox
https://git.savannah.gnu.org/cgit/guix.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).