From: Timo Lindfors <timo.lindfors@iki.fi>
To: Netfilter list <netfilter@vger.kernel.org>
Subject: Re: Analyzing firewall rules programmatically
Date: Mon, 5 Feb 2024 14:35:17 +0200 (EET) [thread overview]
Message-ID: <alpine.DEB.2.20.2402051429360.6588@mail.home> (raw)
In-Reply-To: <20240203114527.GA20263@breakpoint.cc>
On Sat, 3 Feb 2024, Florian Westphal wrote:
> Text is rather unstable, I would not rely on it.
>
> json ought to be stable, netlink is stable (its the api after all).
Thanks. I implemented my first prototype on the JSON output, and only for
netfilter for now. You can give it a ruleset, desired verdict and extra
constraints and it will find a packet that achieves the desired verdict if
it exists.
Here are some examples:
nftables_analysis$ for i in test_data/*.nft; do echo "#### $i"; cat $i; ./find_satisfying_packet.py --json-ruleset $i.json -c tcp.dport==1234; done
#### test_data/complex1.nft
#!/usr/sbin/nft -f
table inet my_filter {
chain input {
type filter hook input priority 0; policy accept;
meta nfproto ipv6 tcp sport 53 meta length == 200 iif > 0 ip6 saddr fe80::fca5:f7ff:febc:97a4 tcp dport 1234 accept
tcp dport 1234 drop
}
}
Satified
ip.daddr=-1
ip.saddr=-1
ip6.daddr=0
ip6.saddr=338288524927261089672224126588925286308
meta.iif=1
meta.l4proto=6
meta.length=200
meta.nfproto=10
tcp.dport=1234
tcp.sport=53
udp.dport=-1
udp.sport=-1
#### test_data/complex2.nft
#!/usr/sbin/nft -f
table inet my_filter {
chain input {
type filter hook input priority 0; policy accept;
meta nfproto ipv6 tcp dport 1234 accept
tcp dport 1234 drop
}
}
Satified
ip.daddr=-1
ip.saddr=-1
ip6.daddr=0
ip6.saddr=0
meta.iif=0
meta.l4proto=6
meta.length=0
meta.nfproto=10
tcp.dport=1234
tcp.sport=0
udp.dport=-1
udp.sport=-1
#### test_data/source_iface.nft
#!/usr/sbin/nft -f
table inet my_filter {
chain input {
type filter hook input priority 0; policy accept;
iif enp0s31f6 tcp dport 1234 accept
tcp dport 1234 drop
}
}
Satified
ip.daddr=0
ip.saddr=0
ip6.daddr=-1
ip6.saddr=-1
meta.iif=0
meta.l4proto=6
meta.length=0
meta.nfproto=2
tcp.dport=1234
tcp.sport=0
udp.dport=-1
udp.sport=-1
#### test_data/source_ip2.nft
#!/usr/sbin/nft -f
table inet my_filter {
chain input {
type filter hook input priority 0; policy accept;
tcp dport 1234 jump helper
tcp dport 1234 accept
}
chain helper {
ip saddr 10.61.7.4 accept
tcp dport 1234 drop
}
}
Satified
ip.daddr=0
ip.saddr=171771652
ip6.daddr=-1
ip6.saddr=-1
meta.iif=0
meta.l4proto=6
meta.length=0
meta.nfproto=2
tcp.dport=1234
tcp.sport=0
udp.dport=-1
udp.sport=-1
#### test_data/source_ip.nft
#!/usr/sbin/nft -f
table inet my_filter {
chain input {
type filter hook input priority 0; policy accept;
tcp dport 1234 ip saddr 10.61.7.4 accept
tcp dport 1234 drop
}
}
Satified
ip.daddr=0
ip.saddr=171771652
ip6.daddr=-1
ip6.saddr=-1
meta.iif=0
meta.l4proto=6
meta.length=0
meta.nfproto=2
tcp.dport=1234
tcp.sport=0
udp.dport=-1
udp.sport=-1
#### test_data/source_port_ipv6.nft
#!/usr/sbin/nft -f
table ip my_filter {
chain input {
type filter hook input priority 0; policy accept;
tcp dport 1234 drop
}
}
table ip6 my_filter {
chain input {
type filter hook input priority 0; policy accept;
tcp dport 1234 tcp sport 53 accept
tcp dport 1234 drop
}
}
Satified
ip.daddr=-1
ip.saddr=-1
ip6.daddr=0
ip6.saddr=0
meta.iif=0
meta.l4proto=6
meta.length=0
meta.nfproto=10
tcp.dport=1234
tcp.sport=53
udp.dport=-1
udp.sport=-1
#### test_data/source_port.nft
#!/usr/sbin/nft -f
table inet my_filter {
chain input {
type filter hook input priority 0; policy accept;
tcp dport 1234 tcp sport 53 accept
tcp dport 1234 drop
}
}
Satified
ip.daddr=0
ip.saddr=0
ip6.daddr=-1
ip6.saddr=-1
meta.iif=0
meta.l4proto=6
meta.length=0
meta.nfproto=2
tcp.dport=1234
tcp.sport=53
udp.dport=-1
udp.sport=-1
#### test_data/source_port_range.nft
#!/usr/sbin/nft -f
table inet my_filter {
chain input {
type filter hook input priority 0; policy accept;
tcp sport {50-55} tcp dport 1234 accept
tcp dport 1234 drop
}
}
Satified
ip.daddr=0
ip.saddr=0
ip6.daddr=-1
ip6.saddr=-1
meta.iif=0
meta.l4proto=6
meta.length=0
meta.nfproto=2
tcp.dport=1234
tcp.sport=50
udp.dport=-1
udp.sport=-1
I put the code to https://github.com/lindi2/nftables_analysis
(MIT license, do whatever you want but I would appreciate bug fixes so
that I can make it more reliable and maybe implement iptables support
later as well)
-Timo
prev parent reply other threads:[~2024-02-05 12:35 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-30 20:13 Analyzing firewall rules programmatically Timo Lindfors
2024-02-01 20:34 ` 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 [this message]
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.2402051429360.6588@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).