netfilter.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Timo Lindfors <timo.lindfors@iki.fi>
To: Netfilter list <netfilter@vger.kernel.org>
Subject: Analyzing firewall rules programmatically
Date: Tue, 30 Jan 2024 22:13:26 +0200 (EET)	[thread overview]
Message-ID: <alpine.DEB.2.20.2401302150460.27550@mail.home> (raw)

Hi,

I spent some time trying to figure out how to programmatically answer 
questions like "Does the ruleset R allow reaching service listening on port P from 
interface I?" or "Does the ruleset R1 allow something that ruleset R2 does 
not allow?".

I tried to find prior work on this area and was able to find "Verified 
iptables Firewall Analysis and Verification" [1] that uses 
the Isabelle proof assistant for iptables rules and "Automated Analysis 
and Debugging of Network Connectivity Policies" [2, 3] that uses Z3 for 
some simple Azure firewall ACL rules.

I could not find anything relevant for netfilter so I began experimenting 
a bit by writing a python function that tries to simulate nftables 
behavior given a ruleset and a packet. I used output of "nft --json list 
ruleset" to and soon noticed that it doesn't quite contain all the 
necessary information for this task.

For example, the default ufw configuration uses iptables to setup

Chain ufw-not-local (1 references)
  pkts bytes target     prot opt in     out     source               destination
   779 46756 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

which shows up as

$ sudo nft -a list ruleset | grep "handle 247"
 		fib daddr type local counter packets 772 bytes 46336

in in the "normal" output. However, in the JSON output critical 
information (mainly "LOCAL") is entirely missing:

$ sudo nft -a --json list ruleset | jq . | grep -B5 -A19 '"handle": 247'
     {
       "rule": {
         "family": "ip",
         "table": "filter",
         "chain": "ufw-not-local",
         "handle": 247,
         "expr": [
           {
             "xt": {
               "type": "match",
               "name": "addrtype"
             }
           },
           {
             "counter": {
               "packets": 778,
               "bytes": 46696
             }
           },
           {
             "return": null
           }
         ]
       }
     },


I understand that ufw is using a compatibility interface. Nevertheless, 
I'm in need of a way to analyze firewall configurations of large number of 
real-world systems programmatically. Can you suggest how I should approach 
this? I can think of at least the following options:

1) Fix the JSON output.

2) Ignore the JSON output and try to parse the output of "nft list 
ruleset".

3) Use JSON output of most of the stuff but fill the gaps by also 
parsing "nft list ruleset".

4) Try to parse the raw netlink traffic seen in "nft --debug=netlink list 
ruleset".

4) Create separate tools for parsing iptables and netfilter rules and 
hope that no system mixes these two.


[1] https://link.springer.com/article/10.1007/s10817-017-9445-1
[2] https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/secguru.pdf
[3] https://github.com/Z3Prover/FirewallChecker



             reply	other threads:[~2024-01-30 20:13 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-30 20:13 Timo Lindfors [this message]
2024-02-01 20:34 ` Analyzing firewall rules programmatically Kerin Millar
2024-02-02 19:05   ` Timo Lindfors
2024-02-02 20:55     ` Kerin Millar
2024-02-03 11:45     ` Florian Westphal
2024-02-05 12:35       ` Timo Lindfors

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=alpine.DEB.2.20.2401302150460.27550@mail.home \
    --to=timo.lindfors@iki.fi \
    --cc=netfilter@vger.kernel.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.
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).