all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Solene Rapenne <solene@perso.pw>
To: guix-devel@gnu.org
Subject: Feedback on a new simple firewall service
Date: Wed, 9 Jun 2021 21:11:59 +0200	[thread overview]
Message-ID: <20210609211159.0f31f134@perso.pw> (raw)

Hello,

I'm looking for advices and feedback. I wrote a simple service (reusing
the iptables service as a start) that I called "firewall", the purpose
is to block all incoming ports and list the ports you want to allow.
The point is to allow users to easily manage their firewall without
knowing about to use iptables. Most of the time opening a few ports and
blocking everything is enough.

However, while this works in its current state, I'm not satisfied of my
code and the way it works.

- it's not compatible with iptables and not extendable, should I merge
  this into the iptables service?

- I'm defining the configuration file in a long string with map calls
  and conditions, it looks very ugly. I didn't write much Scheme in my
  life and I struggled a bit to get the pieces to form the string, this
  is noticeable in the result

- what should happend when you stop the service? I'm currently using a
  default rules set that keep incoming traffic blocked on every ports but
  this may not be desirable.


Exemple of configuration:

(service firewall-service-type
  (firewall-configuration
    (udp '(53))
    (tcp '(22 70 1965))))

The according iptables -L output:
---------
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:gopher
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:1965
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
--------

Here is my code in its current state

;;;
;;; Firewall
;;;

(define %firewall-accept-all-rules
  (plain-file "firewall-block-all.rules"
              "*filter
:INPUT DROP
:FORWARD DROP
:OUTPUT ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
COMMIT
"))

(define-record-type* <firewall-configuration>
  firewall-configuration make-firewall-configuration
  firewall-configuration?
  (tcp firewall-configuration-tcp
       (default #f))
  (udp firewall-configuration-udp
       (default #f)))

(define firewall-shepherd-service
  (match-lambda
   (($ <firewall-configuration> tcp udp)
    (let* ((iptables-restore (file-append iptables "/sbin/iptables-restore"))
          (ip6tables-restore (file-append iptables "/sbin/ip6tables-restore"))
          (custom-rules
           (plain-file
            "iptables-defined.rules"
            (format #f
                    "*filter~%:INPUT DROP~%:FORWARD DROP~%:OUTPUT ACCEPT~%~a~%~a~%~a~%COMMIT~%"
                    "-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT"
                    (if tcp
                        (string-join
                         (map (lambda (tcp) (format #f "-A INPUT -p tcp --dport ~a -j ACCEPT" tcp)) tcp)
                         "\n")
                        "")
                    
                    (if udp
                        (string-join
                         (map (lambda (udp) (format #f "-A INPUT -p udp --dport ~a -j ACCEPT" udp)) udp)
                         "\n")
                        ""))))
          (ruleset (if (or udp tcp) ;; if no ports defined, use the default ruleset
                       custom-rules
                       %firewall-accept-all-rules)))
      (shepherd-service
       (documentation "Easy firewall management")
       (provision '(firewall))
       (start #~(lambda _
                  (invoke #$iptables-restore  #$ruleset)
                  (invoke #$ip6tables-restore #$ruleset)))
       (stop #~(lambda _
                 (invoke #$iptables-restore #$%firewall-accept-all-rules)
                 (invoke #$ip6tables-restore #$%firewall-accept-all-rules))))))))

(define firewall-service-type
  (service-type
   (name 'firewall)
   (description
    "Run @command{iptables-restore}, setting up the specified rules.")
   (extensions
    (list (service-extension shepherd-root-service-type
                             (compose list firewall-shepherd-service))))))


             reply	other threads:[~2021-06-09 19:12 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-09 19:11 Solene Rapenne [this message]
2021-06-11  2:53 ` Feedback on a new simple firewall service OFF TOPIC PRAISE Joshua Branson

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=20210609211159.0f31f134@perso.pw \
    --to=solene@perso.pw \
    --cc=guix-devel@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 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.