Linux Netfilter discussions
 help / color / mirror / Atom feed
* Is viewing a "candidate" ruleset in 'nft list ruleset' format possible?
@ 2020-04-19  2:12 Martin Gignac
  2020-04-22  4:51 ` Trent W. Buck
  0 siblings, 1 reply; 8+ messages in thread
From: Martin Gignac @ 2020-04-19  2:12 UTC (permalink / raw)
  To: netfilter

Hi,

I'd like to know if it's possible tell 'nft' to load a ruleset from
file *without* applying it (a la 'nft -c -f <ruleset>) *but* also have
it show the parsed (yet unapplied) ruleset in 'nft list ruleset'
format as well?

I ask because I have a Bash script with a few helper functions for
nftables and one of the things I'd like to be able to do is to perform
a diff between a candidate ruleset and the last applied/current
ruleset. I can already do this by diffing the ruleset from file with
the last previously saved ruleset from file, but I'd like to be able
to (instead) compare the ruleset using the "cleaned up" format from
'nft list ruleset'. I just don't know how to generate a "candidate"
ruleset in that format without applying it to the kernel first (and
then it's not longer a "candidate", obviously).

Hopefully my question makes sense.

Thanks,
-Martin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is viewing a "candidate" ruleset in 'nft list ruleset' format possible?
  2020-04-19  2:12 Is viewing a "candidate" ruleset in 'nft list ruleset' format possible? Martin Gignac
@ 2020-04-22  4:51 ` Trent W. Buck
  2020-04-22 16:34   ` Martin Gignac
  0 siblings, 1 reply; 8+ messages in thread
From: Trent W. Buck @ 2020-04-22  4:51 UTC (permalink / raw)
  To: netfilter

Martin Gignac <martin.gignac@gmail.com> writes:

> I'd like to know if it's possible tell 'nft' to load a ruleset from
> file *without* applying it (a la 'nft -c -f <ruleset>) *but* also have
> it show the parsed (yet unapplied) ruleset in 'nft list ruleset'
> format as well?

I am also interested in this.

You can simply put "list ruleset" at the bottom of the foo.nft file.
However in my experience this routinely gives outright wrong rulesets
(as at nftables 0.9.1), so I don't trust it.

A possible short-term workaround would be to spin up a netns, load the
new ruleset in *there*, then dump it and tear the ns down again...

    $ sudo nft list ruleset | b2sum
    5524[...]3459  -
    $ sudo ip netns add delete-me
    $ sudo ip netns exec delete-me  nft -i
    nft> list ruleset
    nft> add table inet filter
    nft> add chain inet filter frobozz
    nft> add rule inet filter frobozz  tcp dport ssh accept
    nft> list ruleset
    table inet filter {
            chain frobozz {
                    tcp dport 22 accept
            }
    }
    nft>
    $ sudo nft list ruleset | b2sum
    5524[...]3459  -
    $ # Good, the production ruleset hasn't changed.
    $ sudo ip netns del delete-me   # clean up

If you need to do this as unprivileged user,
I guess look into unshare(1) or bwrap...


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is viewing a "candidate" ruleset in 'nft list ruleset' format possible?
  2020-04-22  4:51 ` Trent W. Buck
@ 2020-04-22 16:34   ` Martin Gignac
  2020-04-23  2:06     ` Duncan Roe
  2020-04-30  3:10     ` Trent W. Buck
  0 siblings, 2 replies; 8+ messages in thread
From: Martin Gignac @ 2020-04-22 16:34 UTC (permalink / raw)
  To: netfilter

> You can simply put "list ruleset" at the bottom of the foo.nft file.
> However in my experience this routinely gives outright wrong rulesets
> (as at nftables 0.9.1), so I don't trust it.

That's a pretty good tip, thanks!... And you're absolutely right, it
gives some weird output. See below the diff of 'nft -c -f foo.nft'
with a 'list ruleset' at the bottom and the actual output of 'nft list
ruleset' once foot.nft is applied to the kernel:

[root@bouboule ~]# diff -u /tmp/toto1.txt /tmp/toto2.txt
--- /tmp/toto1.txt      2020-04-22 11:55:55.718378603 -0400
+++ /tmp/toto2.txt      2020-04-22 11:56:01.888551779 -0400
@@ -1,12 +1,12 @@
 table ip filter {
        chain input {
                type filter hook input priority filter; policy drop;
-               ct state 0x6 accept
+               ct state established,related accept
                ct state invalid drop
                iif "lo" accept
-               meta l4proto icmp icmp type echo-request accept
comment "You can restrict this if you want"
-               meta l4proto tcp tcp dport 22 accept comment "You can
restrict this if you want"
-               meta l4proto tcp tcp dport 179 accept comment "For BGP"
+               icmp type echo-request accept comment "You can
restrict this if you want"
+               tcp dport 22 accept comment "You can restrict this if you want"
+               tcp dport 179 accept comment "For BGP"
        }

        chain output {
@@ -15,7 +15,7 @@

        chain forward {
                type filter hook forward priority filter; policy drop;
-               ct state 0x6 counter packets 0 bytes 0 accept
+               ct state established,related counter packets 0 bytes 0 accept
                ct state invalid drop
        }
 }

Of note is the fact that the 'ct state' line does not contain both
states. As well, the addition of 'meta l4proto' adds a lot of
unecessary verbiage. But still, good to know that this is somewhat
doable as it never dawned on me to put 'list ruleset' at the end of
foo.nft.

> A possible short-term workaround would be to spin up a netns, load the
> new ruleset in *there*, then dump it and tear the ns down again...

This is actually a very cool idea! I never realized that nftables
rulesets are bound to a specific namespace, but now it makes perfect
sense. The only "drawback" (I guess) is that I cannot use 'iif' for
any other interface than 'lo' in the temp namespace; I'll need to use
'iifname' instead since the referenced interfaces won't exist in the
temp namespace. But it's not a deal breaker.

I think I will go with this workaround until (if) nftables supports
this functionality natively.

Thanks!
-Martin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is viewing a "candidate" ruleset in 'nft list ruleset' format possible?
  2020-04-22 16:34   ` Martin Gignac
@ 2020-04-23  2:06     ` Duncan Roe
  2020-04-23 12:10       ` Martin Gignac
  2020-04-30  3:25       ` Trent W. Buck
  2020-04-30  3:10     ` Trent W. Buck
  1 sibling, 2 replies; 8+ messages in thread
From: Duncan Roe @ 2020-04-23  2:06 UTC (permalink / raw)
  To: netfilter

On Wed, Apr 22, 2020 at 12:34:26PM -0400, Martin Gignac wrote:
> > You can simply put "list ruleset" at the bottom of the foo.nft file.
> > However in my experience this routinely gives outright wrong rulesets
> > (as at nftables 0.9.1), so I don't trust it.

"list ruleset" at the bottom of an nft script is completely accurate. The
command "nft list ruleset" discards portions of rules that are implicit, in the
interests of brevity.
>
> That's a pretty good tip, thanks!... And you're absolutely right, it
> gives some weird output. See below the diff of 'nft -c -f foo.nft'
> with a 'list ruleset' at the bottom and the actual output of 'nft list
> ruleset' once foot.nft is applied to the kernel:
>
> [root@bouboule ~]# diff -u /tmp/toto1.txt /tmp/toto2.txt
> --- /tmp/toto1.txt      2020-04-22 11:55:55.718378603 -0400
> +++ /tmp/toto2.txt      2020-04-22 11:56:01.888551779 -0400
> @@ -1,12 +1,12 @@
>  table ip filter {
>         chain input {
>                 type filter hook input priority filter; policy drop;
> -               ct state 0x6 accept
> +               ct state established,related accept
>                 ct state invalid drop
>                 iif "lo" accept
> -               meta l4proto icmp icmp type echo-request accept
> comment "You can restrict this if you want"
> -               meta l4proto tcp tcp dport 22 accept comment "You can
> restrict this if you want"
> -               meta l4proto tcp tcp dport 179 accept comment "For BGP"
> +               icmp type echo-request accept comment "You can
> restrict this if you want"
> +               tcp dport 22 accept comment "You can restrict this if you want"
> +               tcp dport 179 accept comment "For BGP"
>         }
>
>         chain output {
> @@ -15,7 +15,7 @@
>
>         chain forward {
>                 type filter hook forward priority filter; policy drop;
> -               ct state 0x6 counter packets 0 bytes 0 accept
> +               ct state established,related counter packets 0 bytes 0 accept
>                 ct state invalid drop
>         }
>  }
>
> Of note is the fact that the 'ct state' line does not contain both
> states.

It does show it. There are 2 bits set in 0x6. Perhaps it is an oversight that
the code path does not interpret them.

> As well, the addition of 'meta l4proto' adds a lot of
> unecessary verbiage.

They are necessary *for the kernel*. The nft user interface is smart enough that
you don't have to specify them.

> But still, good to know that this is somewhat
> doable as it never dawned on me to put 'list ruleset' at the end of
> foo.nft.
>
> > A possible short-term workaround would be to spin up a netns, load the
> > new ruleset in *there*, then dump it and tear the ns down again...
>
> This is actually a very cool idea! I never realized that nftables
> rulesets are bound to a specific namespace, but now it makes perfect
> sense. The only "drawback" (I guess) is that I cannot use 'iif' for
> any other interface than 'lo' in the temp namespace; I'll need to use
> 'iifname' instead since the referenced interfaces won't exist in the
> temp namespace. But it's not a deal breaker.
>
> I think I will go with this workaround until (if) nftables supports
> this functionality natively.
>
> Thanks!
> -Martin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is viewing a "candidate" ruleset in 'nft list ruleset' format possible?
  2020-04-23  2:06     ` Duncan Roe
@ 2020-04-23 12:10       ` Martin Gignac
  2020-04-30  3:25       ` Trent W. Buck
  1 sibling, 0 replies; 8+ messages in thread
From: Martin Gignac @ 2020-04-23 12:10 UTC (permalink / raw)
  To: netfilter

> "list ruleset" at the bottom of an nft script is completely accurate. The
> command "nft list ruleset" discards portions of rules that are implicit, in the
> interests of brevity.

> > Of note is the fact that the 'ct state' line does not contain both
> > states.

> It does show it. There are 2 bits set in 0x6. Perhaps it is an oversight that
> the code path does not interpret them.

Point taken. I guess it's just because the output of 'nft list
ruleset' seems more "human readable" to me than "list ruleset" at the
bottom, and I'd rather use the former output as a base for diffs.

Thanks,
-Martin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is viewing a "candidate" ruleset in 'nft list ruleset' format possible?
  2020-04-22 16:34   ` Martin Gignac
  2020-04-23  2:06     ` Duncan Roe
@ 2020-04-30  3:10     ` Trent W. Buck
  1 sibling, 0 replies; 8+ messages in thread
From: Trent W. Buck @ 2020-04-30  3:10 UTC (permalink / raw)
  To: netfilter

Martin Gignac <martin.gignac@gmail.com> writes:

> This is actually a very cool idea! I never realized that nftables
> rulesets are bound to a specific namespace, but now it makes perfect
> sense. The only "drawback" (I guess) is that I cannot use 'iif' for
> any other interface than 'lo' in the temp namespace; I'll need to use
> 'iifname' instead since the referenced interfaces won't exist in the
> temp namespace. But it's not a deal breaker.

You can create dummy interfaces with appropriate names inside your dummy
namespace.  Something like this (untested):

    ip -namespace delete-me link add name eth0 type dummy


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is viewing a "candidate" ruleset in 'nft list ruleset' format possible?
  2020-04-23  2:06     ` Duncan Roe
  2020-04-23 12:10       ` Martin Gignac
@ 2020-04-30  3:25       ` Trent W. Buck
  2020-04-30  8:05         ` Trent W. Buck
  1 sibling, 1 reply; 8+ messages in thread
From: Trent W. Buck @ 2020-04-30  3:25 UTC (permalink / raw)
  To: netfilter

Duncan Roe <duncan_roe@optusnet.com.au> writes:

> On Wed, Apr 22, 2020 at 12:34:26PM -0400, Martin Gignac wrote:
>> > You can simply put "list ruleset" at the bottom of the foo.nft file.
>> > However in my experience this routinely gives outright wrong rulesets
>> > (as at nftables 0.9.1), so I don't trust it.
>
> "list ruleset" at the bottom of an nft script is completely accurate.
> The command "nft list ruleset" discards portions of rules that are implicit, in the
> interests of brevity.

Sorry, I don't have a testable example.

My rulesets were like this:

    flush ruleset
    <stuff here>
    list ruleset

I *think* I saw the output of "nft -f test.nft" had entire rules
missing, where they were present in "nft list ruleset" immediately
afterwards.

I just tried to reproduce this and couldn't, so it's possible I was just
really tired and the real problem was inside my brain!

I would have understood e.g. ct state keywords being XORed to a number, but
it's possible I was seeing ELEMENTS in a list/mapping "disappear"
because they were being merged (e.g. below) and then mis-remembering
that as "rules disappear".

If I run into this again, I'll try to keep proper records so I can file
a proper bug report!

    root@not-omega:/home/twb# nft -f tmp.nft >before
    root@not-omega:/home/twb# nft list ruleset >after
    root@not-omega:/home/twb# GIT_PAGER=cat git diff -U999 before after
    diff --git a/before b/after
    index dc38326..ad39c3a 100644
    --- a/before
    +++ b/after
    @@ -1,28 +1,27 @@
     table inet my_filter {
            map ICMPv6_RFC4890_policy {
                    type icmpv6_type : verdict
                    flags interval
    -               elements = { 0,
    -                            destination-unreachable : accept,
    -                            5 : drop,
    -                            100 : drop,
    -                            102 : drop,
    +               elements = { 1-4 : accept,
    +                            5-99 : drop,
    +                            100-101 : drop,
    +                            102-126 : drop,
                                 127 : drop,
    -                            echo-request : accept,
    -                            mld-listener-query : accept,
    -                            nd-router-solicit : accept,
    +                            128-129 : accept,
    +                            130-132 : accept,
    +                            133-136 : accept,
                                 nd-redirect : drop,
                                 router-renumbering : drop,
    -                            139 : drop,
    -                            ind-neighbor-solicit : accept,
    +                            139-140 : drop,
    +                            141-142 : accept,
                                 mld2-listener-report : accept,
    -                            144 : accept,
    -                            148 : accept,
    +                            144-147 : accept,
    +                            148-149 : accept,
                                 150 : drop,
    -                            151 : accept,
    -                            154 : drop,
    -                            200 : drop,
    -                            202 : drop,
    +                            151-153 : accept,
    +                            154-199 : drop,
    +                            200-201 : drop,
    +                            202-254 : drop,
                                 255 : drop }
            }
     }


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is viewing a "candidate" ruleset in 'nft list ruleset' format possible?
  2020-04-30  3:25       ` Trent W. Buck
@ 2020-04-30  8:05         ` Trent W. Buck
  0 siblings, 0 replies; 8+ messages in thread
From: Trent W. Buck @ 2020-04-30  8:05 UTC (permalink / raw)
  To: netfilter

[-- Attachment #1: Type: text/plain, Size: 1533 bytes --]

trentbuck@gmail.com (Trent W. Buck) writes:

> Duncan Roe <duncan_roe@optusnet.com.au> writes:
>
>> On Wed, Apr 22, 2020 at 12:34:26PM -0400, Martin Gignac wrote:
>>> > You can simply put "list ruleset" at the bottom of the foo.nft file.
>>> > However in my experience this routinely gives outright wrong rulesets
>>> > (as at nftables 0.9.1), so I don't trust it.
>>
>> "list ruleset" at the bottom of an nft script is completely accurate.
>> The command "nft list ruleset" discards portions of rules that are implicit, in the
>> interests of brevity.
>
> Sorry, I don't have a testable example.
> If I run into this again, I'll try to keep proper records so I can file
> a proper bug report!

Hooray, I got one (attached).

You can see "list ruleset" inside /etc/nftables.conf ends with

    table inet my_filter {
    }

where running "nft list ruleset" immediately afterwards, it shows all
the chains and rules that are actually there:

    table inet my_filter {
            chain my_input {
                    type filter hook input priority filter; policy drop;
                    jump my_prologue comment "deal with boring conntrack/loopback/ICMP/ICMPv6"
                    tcp dport 22 accept
                    jump my_epilogue
            }
    [...]
    }

It happens reliably if I run "nft delete table inet my_filter" before "/etc/nftables.conf",
but NOT if I run  "/etc/nftables.conf" before "/etc/nftables.conf".

To me this feels like "list ruleset" is sometimes running before the block
immediately before it.


[-- Attachment #2: transcript showing "list ruleset" inside foo.nft giving weird output --]
[-- Type: text/plain, Size: 11808 bytes --]

root@zippy:~# nft delete table inet my_filter
root@zippy:~# /etc/nftables.conf
table ip filter {
	chain INPUT {
		type filter hook input priority filter; policy accept;
		iifname "virbr1" meta l4proto udp udp dport 53 counter packets 0 bytes 0 accept
		iifname "virbr1" meta l4proto tcp tcp dport 53 counter packets 0 bytes 0 accept
		iifname "virbr1" meta l4proto udp udp dport 67 counter packets 0 bytes 0 accept
		iifname "virbr1" meta l4proto tcp tcp dport 67 counter packets 0 bytes 0 accept
		iifname "virbr0" meta l4proto udp udp dport 53 counter packets 0 bytes 0 accept
		iifname "virbr0" meta l4proto tcp tcp dport 53 counter packets 0 bytes 0 accept
		iifname "virbr0" meta l4proto udp udp dport 67 counter packets 0 bytes 0 accept
		iifname "virbr0" meta l4proto tcp tcp dport 67 counter packets 0 bytes 0 accept
	}

	chain FORWARD {
		type filter hook forward priority filter; policy accept;
		iifname "virbr1" oifname "virbr1" counter packets 0 bytes 0 accept
		oifname "virbr1" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
		oifname "virbr0" ip daddr 192.168.122.0/24 ct state related,established counter packets 0 bytes 0 accept
		iifname "virbr0" ip saddr 192.168.122.0/24 counter packets 0 bytes 0 accept
		iifname "virbr0" oifname "virbr0" counter packets 0 bytes 0 accept
		oifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
	}

	chain OUTPUT {
		type filter hook output priority filter; policy accept;
		oifname "virbr1" meta l4proto udp udp dport 68 counter packets 0 bytes 0 accept
		oifname "virbr0" meta l4proto udp udp dport 68 counter packets 0 bytes 0 accept
	}
}
table ip6 filter {
	chain INPUT {
		type filter hook input priority filter; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority filter; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority filter; policy accept;
	}
}
table bridge filter {
	chain INPUT {
		type filter hook input priority filter; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority filter; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority filter; policy accept;
	}
}
table ip mangle {
	chain PREROUTING {
		type filter hook prerouting priority mangle; policy accept;
	}

	chain INPUT {
		type filter hook input priority mangle; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority mangle; policy accept;
	}

	chain OUTPUT {
		type route hook output priority mangle; policy accept;
	}

	chain POSTROUTING {
		type filter hook postrouting priority mangle; policy accept;
		oifname "virbr1" meta l4proto udp udp dport 68 counter packets 0 bytes 0 # CHECKSUM fill
		oifname "virbr0" meta l4proto udp udp dport 68 counter packets 0 bytes 0 # CHECKSUM fill
	}
}
table ip nat {
	chain PREROUTING {
		type nat hook prerouting priority dstnat; policy accept;
	}

	chain INPUT {
		type nat hook input priority 100; policy accept;
	}

	chain POSTROUTING {
		type nat hook postrouting priority srcnat; policy accept;
		ip saddr 192.168.122.0/24 ip daddr 224.0.0.0/24 counter packets 0 bytes 0 return
		ip saddr 192.168.122.0/24 ip daddr 255.255.255.255 counter packets 0 bytes 0 return
		meta l4proto tcp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade to :1024-65535 
		meta l4proto udp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade to :1024-65535 
		ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade 
	}

	chain OUTPUT {
		type nat hook output priority -100; policy accept;
	}
}
table ip sshguard {
	set attackers {
		type ipv4_addr
		flags interval
	}

	chain blacklist {
		type filter hook input priority filter - 10; policy accept;
		ip saddr @attackers drop
	}
}
table ip6 sshguard {
	set attackers {
		type ipv6_addr
		flags interval
	}

	chain blacklist {
		type filter hook input priority filter - 10; policy accept;
		ip6 saddr @attackers drop
	}
}
table inet my_filter {
}
root@zippy:~# nft list ruleset
table ip filter {
	chain INPUT {
		type filter hook input priority filter; policy accept;
		iifname "virbr1" meta l4proto udp udp dport 53 counter packets 0 bytes 0 accept
		iifname "virbr1" meta l4proto tcp tcp dport 53 counter packets 0 bytes 0 accept
		iifname "virbr1" meta l4proto udp udp dport 67 counter packets 0 bytes 0 accept
		iifname "virbr1" meta l4proto tcp tcp dport 67 counter packets 0 bytes 0 accept
		iifname "virbr0" meta l4proto udp udp dport 53 counter packets 0 bytes 0 accept
		iifname "virbr0" meta l4proto tcp tcp dport 53 counter packets 0 bytes 0 accept
		iifname "virbr0" meta l4proto udp udp dport 67 counter packets 0 bytes 0 accept
		iifname "virbr0" meta l4proto tcp tcp dport 67 counter packets 0 bytes 0 accept
	}

	chain FORWARD {
		type filter hook forward priority filter; policy accept;
		iifname "virbr1" oifname "virbr1" counter packets 0 bytes 0 accept
		oifname "virbr1" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
		oifname "virbr0" ip daddr 192.168.122.0/24 ct state related,established counter packets 0 bytes 0 accept
		iifname "virbr0" ip saddr 192.168.122.0/24 counter packets 0 bytes 0 accept
		iifname "virbr0" oifname "virbr0" counter packets 0 bytes 0 accept
		oifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
		iifname "virbr0" counter packets 0 bytes 0 reject
		iifname "virbr1" counter packets 0 bytes 0 reject
	}

	chain OUTPUT {
		type filter hook output priority filter; policy accept;
		oifname "virbr1" meta l4proto udp udp dport 68 counter packets 0 bytes 0 accept
		oifname "virbr0" meta l4proto udp udp dport 68 counter packets 0 bytes 0 accept
	}
}
table ip6 filter {
	chain INPUT {
		type filter hook input priority filter; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority filter; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority filter; policy accept;
	}
}
table bridge filter {
	chain INPUT {
		type filter hook input priority filter; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority filter; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority filter; policy accept;
	}
}
table ip mangle {
	chain PREROUTING {
		type filter hook prerouting priority mangle; policy accept;
	}

	chain INPUT {
		type filter hook input priority mangle; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority mangle; policy accept;
	}

	chain OUTPUT {
		type route hook output priority mangle; policy accept;
	}

	chain POSTROUTING {
		type filter hook postrouting priority mangle; policy accept;
		oifname "virbr1" meta l4proto udp udp dport 68 counter packets 0 bytes 0 # CHECKSUM fill
		oifname "virbr0" meta l4proto udp udp dport 68 counter packets 0 bytes 0 # CHECKSUM fill
	}
}
table ip nat {
	chain PREROUTING {
		type nat hook prerouting priority dstnat; policy accept;
	}

	chain INPUT {
		type nat hook input priority 100; policy accept;
	}

	chain POSTROUTING {
		type nat hook postrouting priority srcnat; policy accept;
		ip saddr 192.168.122.0/24 ip daddr 224.0.0.0/24 counter packets 0 bytes 0 return
		ip saddr 192.168.122.0/24 ip daddr 255.255.255.255 counter packets 0 bytes 0 return
		meta l4proto tcp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade to :1024-65535 
		meta l4proto udp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade to :1024-65535 
		ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade 
	}

	chain OUTPUT {
		type nat hook output priority -100; policy accept;
	}
}
table ip sshguard {
	set attackers {
		type ipv4_addr
		flags interval
	}

	chain blacklist {
		type filter hook input priority filter - 10; policy accept;
		ip saddr @attackers drop
	}
}
table ip6 sshguard {
	set attackers {
		type ipv6_addr
		flags interval
	}

	chain blacklist {
		type filter hook input priority filter - 10; policy accept;
		ip6 saddr @attackers drop
	}
}
table inet my_filter {
	chain my_input {
		type filter hook input priority filter; policy drop;
		jump my_prologue comment "deal with boring conntrack/loopback/ICMP/ICMPv6"
		tcp dport 22 accept
		jump my_epilogue
	}

	chain my_forward {
		type filter hook forward priority filter; policy drop;
		jump my_prologue comment "deal with boring conntrack/loopback/ICMP/ICMPv6"
		jump my_epilogue
	}

	chain my_prologue {
		ct state vmap { invalid : drop, established : accept, related : accept }
		ct status dnat accept
		meta iiftype loopback accept
		icmp type echo-request accept
		icmpv6 type { echo-request, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
	}

	chain my_epilogue {
	}
}
root@zippy:~# cat /etc/nftables.conf
#!/usr/sbin/nft --file

## NOTE: we add+delete each table (not "flush ruleset"), because
##       otherwise we would wipe out sshguard & libvirtd tables.
#flush ruleset
add table inet my_filter        # idempotent
delete table inet my_filter     # not idempotent


table inet my_filter {
    chain my_input {
        type filter hook input priority filter
        policy drop
        jump my_prologue  comment "deal with boring conntrack/loopback/ICMP/ICMPv6"

        # YOUR RULES HERE.
        # NOTE: service names resolve via nss (/etc/hosts) only in nft 0.9.1+!
        tcp dport ssh  accept
        jump my_epilogue
    }
    chain my_forward {
        type filter hook forward priority filter
        policy drop
        jump my_prologue  comment "deal with boring conntrack/loopback/ICMP/ICMPv6"
        # YOUR RULES HERE.
        jump my_epilogue
    }
    # We want output to be "allow all", so we don't even create a chain.
    #chain my_output {
    #    type filter hook output priority filter
    #    policy accept
    #}

    chain my_prologue {
        ct state vmap { established: accept, related: accept, invalid: drop }
        ct status dnat  accept
        iiftype loopback  accept
        icmp type echo-request  accept
        icmpv6 type {
            echo-request,
            nd-neighbor-solicit,
            nd-router-advert,
            nd-neighbor-advert }  accept
    }
    chain my_epilogue {
    }
}

# This is here to aid debugging.
# Note that its output WILL NOT MATCH a later "nft list ruleset".
list ruleset
root@zippy:~# dpkg-query -W nftables
nftables	0.9.3-2~bpo10+1
root@zippy:~# nft --version
nftables v0.9.3 (Topsy)
root@zippy:~# uname -a
Linux zippy 5.4.0-0.bpo.4-amd64 #1 SMP Debian 5.4.19-1~bpo10+1 (2020-03-09) x86_64 GNU/Linux
root@zippy:~# 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-04-30  8:05 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-04-19  2:12 Is viewing a "candidate" ruleset in 'nft list ruleset' format possible? Martin Gignac
2020-04-22  4:51 ` Trent W. Buck
2020-04-22 16:34   ` Martin Gignac
2020-04-23  2:06     ` Duncan Roe
2020-04-23 12:10       ` Martin Gignac
2020-04-30  3:25       ` Trent W. Buck
2020-04-30  8:05         ` Trent W. Buck
2020-04-30  3:10     ` Trent W. Buck

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox