emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/nftables-mode 794a6e6774 10/41: limit ICMP by type, tw


From: Stefan Monnier
Subject: [elpa] externals/nftables-mode 794a6e6774 10/41: limit ICMP by type, tweak notes, expand on iif vs iifname, document "flush table" gotcha
Date: Mon, 23 May 2022 09:27:22 -0400 (EDT)

branch: externals/nftables-mode
commit 794a6e67745a92cae2c104872c6902e3f6364edd
Author: Trent W. Buck <trentbuck@gmail.com>
Commit: Trent W. Buck <trentbuck@gmail.com>

    limit ICMP by type, tweak notes, expand on iif vs iifname, document "flush 
table" gotcha
---
 nftables-host.nft | 83 +++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 69 insertions(+), 14 deletions(-)

diff --git a/nftables-host.nft b/nftables-host.nft
index 38fdef5cdc..d218446a4f 100644
--- a/nftables-host.nft
+++ b/nftables-host.nft
@@ -62,31 +62,56 @@
 ####
 #### NOTE: "table x" is implicitly "table ip x", which is IPv4 only.
 ####       If you want dual-stack, say "table inet x".
+####
+#### NOTE: "iif lo" is resolved at ruleset load time into an interface
+####       NUMBER inside the kernel; whereas "iifname lo" remains a
+####       string.  This means that:
+####
+####        * "iifname" is ~10 times slower than "iif" for every
+####          packet considered (strcmp versus ==).
+####
+####        * If you load a ruleset with "iif foo" before foo exists,
+####          the load will fail, LEAVING YOU UNPROTECTED!
+####
+####        * If you load a ruleset with "iif foo" and then foo is
+####          removed and readded (e.g. ppp0 for a flaky ADSL link),
+####          what happens?
+####
+####        * Rule of thumb: always use "iifname" (not "iif").
 
 
+# NOTE: this will remove *ALL* tables --- including tables set up by
+#       other things (e.g. sshguard)!
+#
+#       In theory you can flush just your own rules, e.g.
+#
+#           flush table inet my_filter
+#
+# FIXME: I tried that, and I got locked out of SSH!
+#        What it did was remove all the rules, but NOT the chains, so
+#        the default-deny policy dropped EVERYTHING!!!
 flush ruleset
 
+
 table inet my_filter {
     chain my_input {
         type filter hook input priority filter
         policy drop
         # Typically 99%+ of packets are part of an already-established flow.
         # Allow those first, so we're a fast, stateful firewall.
-        # The rest SHOULD be "ct state new" (or untracked).
+        # After this only "ct state new" (or "ct state untracked") will remain.
         # FIXME: is a vmap here better (more efficient) than two separate 
rules?
         # FIXME: {established or related: accept} does not match correctly!
         ct state vmap { established: accept, related: accept, invalid: drop }
+
         # Loopback traffic is needed for e.g. NFS RPC, and for debugging.
-        # NOTE: assumes exactly one loopback interface named "lo" that already 
exists.
-        # FIXME: why "iif lo" not "ifftype loopback"?  Is it just inertia?
-        iiftype loopback accept
+        # FIXME: is iiftype here better than iif/iifname?
+        iiftype loopback  accept
 
-        # Allow arbitrary IPv4/ICMP and IPv6/ICMPv6.
-        # FIXME: this is too broad -- narrow this!
-        # FIXME: rate-limit (some) ICMPv4 by source IP?
-        ip protocol icmp accept
-        # FIXME: should we limit to "ip6 nexthdr icmpv6"?
-        icmpv6 type vmap @ICMPv6_RFC4890_policy
+        # Allow *some* kinds of IPv4/ICMP and IPv6/ICMPv6.
+        # FIXME: are "ip protocol icmp" and "ip6 nexthdr icmpv6" needed?
+        ip protocol icmp  icmp type vmap @ICMP_policy
+        ip6 nexthdr icmpv6  icmpv6 type vmap @ICMPv6_RFC4890_policy
 
         # YOUR RULES HERE.
         # NOTE: service names resolve via nss (/etc/hosts) only in nft 0.9.1+!
@@ -95,8 +120,8 @@ table inet my_filter {
         ##FOR "router" EXAMPLE### NOTE: "iif foo" must exist at ruleset load 
time.
         ##FOR "router" EXAMPLE###       If your ruleset starts BEFORE udev 
and/or systemd-networkd are READY=1,
         ##FOR "router" EXAMPLE###       consider using 'iifname lan' instead 
of "iif lan".
-        tcp dport ssh accept
-        tcp dport { http, https } accept
+        tcp dport ssh  accept
+        tcp dport { http, https }  accept
         ##FOR "router" EXAMPLE##iif enp11s0 tcp dport domain accept
         ##FOR "router" EXAMPLE##iif enp11s0 udp dport { domain, ntp, bootps } 
accept
 
@@ -118,6 +143,10 @@ table inet my_filter {
     }
 
     # 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
+    #}
 
 
     # Allow all ICMPv6 is wrong (insecure);
@@ -164,8 +193,34 @@ table inet my_filter {
                   255: drop,    # RFC 4890 4.3.5 & 4.4.5 extension type numbers
         }
     }
-}
 
-list ruleset
+    # NOTE: I couldn't find an RFC for ICMPv4 firewall, so
+    #       I am adopting the following heuristic:
+    #
+    #        1. if there is an ICMPv6 equivalent, follow RFC4890.
+    #        2. if deprecated or experimental or reserved or unallocated, drop.
+    #        3. NOT rate-limiting ping for now, because ICBF.
+    #        4. NOT filtering by type.code (only type) for now, because ICBF.
+    map ICMP_policy {
+        type icmp_type : verdict
+        flags interval
+        elements = {            #FIXME: icmp type 5 12 13 14 40
+            destination-unreachable: accept, # RFC 4890 4.3.1 essential errors
+                      time-exceeded: accept, # RFC 4890 4.3.1 essential errors
+                  parameter-problem: accept, # RFC 4890 4.3.1 essential errors
+                       echo-request: accept, # RFC 4890 4.3.1 echo (ping)
+                         echo-reply: accept, # RFC 4890 4.3.1 echo (ping)
+                      source-quench: drop,   # deprecated
+                            1 -   2: drop,   # unassigned
+                            6 -   7: drop,   # deprecated / unassigned
+                            9 -  10: accept, # RFC 4890 4.3.3 & 4.4.1 (IRDP - 
alternative to DHCPv4??)
+                           15 - 255: drop,   # deprecated / unassigned / 
reserved / experimental
+        }
+    }
 
+}
 
+# This is here to aid debugging.
+# Note that its output WILL NOT MATCH a later "nft list rulset".
+# Also, it is buggy, e.g. the ICMPv6_RFC4890_policy it prints has gibberish in 
v0.9.1.
+list ruleset



reply via email to

[Prev in Thread] Current Thread [Next in Thread]