mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-12-24 05:18:07 -05:00
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.
This commit is contained in:
parent
3e63a83c0f
commit
9926b8f809
3 changed files with 231 additions and 2 deletions
|
@ -11612,6 +11612,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}] @
|
||||
|
|
|
@ -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 @@ (define-module (gnu services networking)
|
|||
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 @@ (define openvswitch-service-type
|
|||
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
|
||||
|
|
|
@ -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 @@ (define-module (gnu tests networking)
|
|||
#: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,127 @@ (define %test-tor
|
|||
(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))
|
||||
|
||||
;; TODO: This test freezes up at the login prompt without any
|
||||
;; relevant messages on the console. Perhaps it is waiting for some
|
||||
;; timeout. Find and fix this issue.
|
||||
;; (test-assert "inetd echo service is accessible after iptables firewall is stopped"
|
||||
;; (begin
|
||||
;; (marionette-eval
|
||||
;; '(begin
|
||||
;; (use-modules (gnu services herd))
|
||||
;; (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))))
|
||||
|
|
Loading…
Reference in a new issue