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

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

[elpa] externals/nftables-mode 6e908b1d67 17/41: Got the IPS working at


From: Stefan Monnier
Subject: [elpa] externals/nftables-mode 6e908b1d67 17/41: Got the IPS working at last (inc IPv6), mua ha ha!
Date: Mon, 23 May 2022 09:27:23 -0400 (EDT)

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

    Got the IPS working at last (inc IPv6), mua ha ha!
---
 nftables-router.nft | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 122 insertions(+)

diff --git a/nftables-router.nft b/nftables-router.nft
index dd0bb69684..add19400c3 100644
--- a/nftables-router.nft
+++ b/nftables-router.nft
@@ -284,6 +284,7 @@ table inet my_filter {
         tcp dport {domain,ssh,http,https,smtp,submission,imaps}  accept
         udp dport {domain} accept
         # Allow additional special ports, but only to the server that serves 
them.
+        # UPDATE: sigh, apparently there is no conntrack helper for mosh, and 
bulk allowing a giant port range REALLY IS the recommended workaround. --twb, 
Aug 2019
         define russm.example.com = 127.254.254.254
         ip daddr $russm.example.com  udp dport 60000-61000  accept  comment 
"mosh (FIXME: write nf_conntrack_mosh.ko!)"
     }
@@ -319,6 +320,8 @@ table inet my_filter {
         # 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
+
+        jump my_IPS
     }
 
     chain my_epilogue {
@@ -329,6 +332,108 @@ table inet my_filter {
     }
 
 
+    ## An automated SSH (et al) brute-force blacklist.
+    ##
+    ## 1. if you brute-force port X more than Y times/minute,
+    ##    you're blacklisted for Z minutes.
+    ##
+    ## 2. if you are blacklisted and make ANY connection,
+    ##    you're blacklisted for Z minutes (i.e. countdown resets).
+    ##
+    ## 3. if you are blacklisted, all your new flows are dropped.
+    ##    (We used to TARPIT, to tie up attacker resources.
+    ##    That used xtables-addons and isn't supported in nftables 0.9.1.)
+    ##
+    ## Compared to sshguard or fail2ban or DenyHosts:
+    ##
+    ##  BONUS: installed on a gateway, protects the entire network.
+    ##
+    ##  BONUS: works even when syslogd is down, or /var/log is full, or
+    ##         the syslog "access denied" log format changes.
+    ##
+    ##  BONUS: works even when sshd (or whatever) is down.
+    ##         That is, if the host is off, the gateway will still trigger.
+    ##
+    ##  BONUS: works even when sshd (or whatever) is unused.
+    ##         If you never even run FTP or RDP, trigger on them!
+    ##
+    ##  MALUS: cannot ignore legitimate traffic.
+    ##
+    ##         For SSH, you can mitigate this by forcing your users to
+    ##         use ControlMaster.
+    ##
+    ##         For HTTPS and IMAPS, you're screwed --- those ALWAYS
+    ##         make 30+ connections at once (in IMAP's case, because
+    ##         IDLE extension sucks).
+    ##
+    ##         You can also mitigate this by having a "backdoor" open
+    ##         while blacklisted, which adds you to a temporary
+    ##         whitelist if you port knock in the right sequence.
+    ##
+    ##         The port knock sequence is a pre-shared key to your end
+    ##         users, with all the problems that a PSK involves!
+    ##
+    ##  MALUS: easy for an attacker to spoof SYNs to block a legitimate user?
+    ##         (See port knock mitigation, above)
+    ##
+    ##  MALUS: because we run this AFTER "ct state established accept",
+    ##         connections that are "in flight" when the ban hits
+    ##         are allowed to complete.
+    ##
+    ##         This happens in the wild where the attacker makes 100
+    ##         SSH connections in 1 second.
+    ##
+    ##         The alternative is to run this (relatively expensive)
+    ##         check on EVERY packet, instead of once per flow.
+    ##
+    ## I recommend:
+    ##
+    ##   * this IPS for low-rate (SSH w/ ControlMaster) and unused (FTP, RDP) 
services,
+    ##     on gateways, for flows originating from the internet / upstream.
+    ##
+    ##     For a list of ports to (maybe) IPS guard, consider the first N 
lines of:
+    ##
+    ##         sort -rnk3 /usr/share/nmap/nmap-services
+    ##
+    ##   * a basic firewall, and sshguard, on every host that runs a relevant 
service.
+    ##     (This includes SSH, so basically everything.)
+    ##     This also covers legitimately bursty traffic on imaps.
+    ##     Does this cover submission 587/tcp (postfix)?
+    ##
+    ##   * EXCEPT, sshguard doesn't do apache or nginx, so fail2ban on the www 
hosts?
+    ##
+    ##   * postscreen covers smtp (25/tcp).
+
+    chain my_IPS {
+        ct state != new  return  comment "Operate per-flow, not per-packet 
(my_prologue guarantees this anyway)"
+        iiftype != ppp  return  comment "IPS only protects against attacks 
from the internet"
+
+        # Track the rate of new connections (my_IPS_IPvX_meter).
+        # If someone (ip saddr) connects to a service (ip daddr . tcp dport) 
too often,
+        # then blacklist them (my_IPS_IPvX_blacklist).
+        tcp dport @my_IPS_TCP_ports  \
+            add @my_IPS_IPv4_meter { ip saddr . ip daddr . tcp dport  limit 
rate over 1/minute  burst 3 packets }  \
+            add @my_IPS_IPv4_blacklist { ip saddr }  \
+            log level audit log prefix "Blacklist SRC: "
+        tcp dport @my_IPS_TCP_ports  \
+            add @my_IPS_IPv6_meter { ip6 saddr . ip6 daddr . tcp dport  limit 
rate over 1/minute  burst 3 packets }  \
+            add @my_IPS_IPv6_blacklist { ip6 saddr }  \
+            log level audit log prefix "Blacklist SRC: "
+
+        # If someone is NOT whitelisted, and IS blacklisted, then drop their 
connection, AND reset their countdown.
+        # In other words, once blacklisted for brute-forcing SSH, you REMAIN 
blacklisted until you STFU for a while (on ALL ports).
+        ip saddr != @my_IPS_IPv4_whitelist  ip saddr @my_IPS_IPv4_blacklist  
update @my_IPS_IPv4_blacklist { ip saddr }  drop
+        ip6 saddr != @my_IPS_IPv6_whitelist  ip6 saddr @my_IPS_IPv6_blacklist  
update @my_IPS_IPv6_blacklist { ip6 saddr }  drop
+
+    }
+    set my_IPS_IPv4_meter     { type ipv4_addr . ipv4_addr . inet_service; 
timeout 10m; flags dynamic; }
+    set my_IPS_IPv6_meter     { type ipv6_addr . ipv6_addr . inet_service; 
timeout 10m; flags dynamic; }
+    set my_IPS_IPv4_blacklist { type ipv4_addr; timeout 10m; }
+    set my_IPS_IPv6_blacklist { type ipv6_addr; timeout 10m; }
+    set my_IPS_IPv4_whitelist { type ipv4_addr; timeout 10h; }
+    set my_IPS_IPv6_whitelist { type ipv6_addr; timeout 10h; }
+    set my_IPS_TCP_ports      { type inet_service; elements={ssh, telnet, 
ftp}; }
+
     # Allow all ICMPv6 is wrong (insecure);
     # Deny all ICMPv6 is wrong (breaks IPv6).
     # The following vmap merges RFC 4890 4.4 (for hosts) and 4.4 (for routers).
@@ -381,6 +486,23 @@ table inet my_filter {
     #        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.
+    #
+    # FIXME: duclicsic of #netfilter claims that "ct state related" implicitly 
handles
+    #        everything except echo-request:
+    #
+    #            <duclicsic> twb: if you accept related/established before 
dropping icmp it will work fine. destination unreachable messages are matched 
by related, echo replies are established, etc.
+    #            <twb> duclicsic: interesting; I didn't realize that.  That 
covers PMTUD at least
+    #            <duclicsic> twb: the only icmpv4 message you need to 
explicitly accept in a sensible config is echo-request
+    #            <twb> duclicsic: for ICMPv4, the only other thing I can see 
is RS/RA, which is probably not ACTUALLY needed
+    #            <duclicsic> no I don't think I've ever seen them used, but 
you'd know to expect them if you were using them I'm sure.
+    #            <twb> duclicsic: yeah except in the *even more* rare case 
where they're simply transiting through my network on the way somewhere else
+    #            <duclicsic> i don't think you'd ever want to forward an icmp 
rotuer solicitation or advertisement
+    #            <twb> duclicsic: oh yeah - DERP - RS/RA are dropped by the 
kernel automatically and do not transit a route (per RFC 4890)
+    #
+    #            <twb> duclicsic: do you have related Opinions about ICMPv6, 
or have you simply not bothered with IPv6 yet?
+    #            <duclicsic> twb: for v6 I accept echo-request, 
nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert
+    #            <twb> duclicsic: on gateways, or hosts, or both?
+    #            <duclicsic> twb: that's an example from my desktop here
     map ICMP_policy {
         type icmp_type : verdict
         flags interval



reply via email to

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