# fail2ban action: drop banned sources at the nftables PREROUTING hook. # # Why this exists instead of the stock `nftables` action: # # Traffic to a published container port (443, 2222) is DNAT'd in prerouting and # then traverses FORWARD -- it never reaches the INPUT hook. fail2ban's default # actions install their rules on INPUT, so on a podman host they drop nothing # at all while `fail2ban-client status` cheerfully reports active bans. It fails # silently, which is the worst way for a security control to fail. # # Hooking at prerouting with priority -300 (raw) puts us ahead of both the DNAT # that redirects the packet and netavark's own chains, so the drop applies to # host-terminated and container-bound traffic alike. # # Verify with a real ban drill -- see docs/runbook.md. [Definition] actionstart = nft add table inet f2b-prerouting nft add chain inet f2b-prerouting preroute '{ type filter hook prerouting priority -300 ; policy accept ; }' nft add set inet f2b-prerouting f2b--v4 '{ type ipv4_addr ; flags interval ; }' nft add set inet f2b-prerouting f2b--v6 '{ type ipv6_addr ; flags interval ; }' nft add rule inet f2b-prerouting preroute ip saddr @f2b--v4 drop nft add rule inet f2b-prerouting preroute ip6 saddr @f2b--v6 drop # Flush rather than delete: the preroute rules still reference these sets, so a # delete would be refused. Emptying them drops every ban, which is what stopping # the jail means. actionstop = nft flush set inet f2b-prerouting f2b--v4 2>/dev/null || true nft flush set inet f2b-prerouting f2b--v6 2>/dev/null || true # If something flushed our table out from under us, actionstart runs again. actioncheck = nft list set inet f2b-prerouting f2b--v4 >/dev/null 2>&1 # Family is derived from the address itself rather than a fail2ban tag, so this # stays correct across fail2ban versions that disagree about . actionban = case "" in \ *:*) nft add element inet f2b-prerouting f2b--v6 '{ }' ;; \ *) nft add element inet f2b-prerouting f2b--v4 '{ }' ;; \ esac actionunban = case "" in \ *:*) nft delete element inet f2b-prerouting f2b--v6 '{ }' 2>/dev/null || true ;; \ *) nft delete element inet f2b-prerouting f2b--v4 '{ }' 2>/dev/null || true ;; \ esac [Init] name = default