# Fail2Ban configuration file
#
# Author: Daniel Black
# Author: Cyril Jaquier
# Modified: Yaroslav O. Halchenko <debian@onerussian.com>
# 			made active on all ports from original iptables.conf
# Modified: Alexander Belykh <albel727@ngs.ru>
#                       adapted for nftables
#
# This is a included configuration file and includes the definitions for the nftables
# used in all nftables based actions by default.
#
# The user can override the defaults in nftables-common.local
# Example: redirect flow to honeypot
#
# [Init]
# table_family = ip
# chain_type = nat
# chain_hook = prerouting
# chain_priority = -50
# blocktype = counter redirect to 2222

[INCLUDES]

after = nftables-common.local

[Definition]

# Option:  type
# Notes.:  type of the action.
# Values:  [ multiport | allports ]  Default: multiport
#
type = multiport

rule_match-custom =
rule_match-allports = meta l4proto \{ <protocol> \}
rule_match-multiport = $proto dport \{ $(echo '<port>' | sed s/:/-/g) \}
match = <rule_match-<type>>

# Option:  rule_stat
# Notes.:  statement for nftables filter rule.
#          leaving it empty will block all (include udp and icmp)
# Values:  nftables statement
#
rule_stat = %(match)s <addr_family> saddr @<addr_set> <blocktype>

# optional interator over protocol's:
_nft_for_proto-custom-iter =
_nft_for_proto-custom-done =
_nft_for_proto-allports-iter =
_nft_for_proto-allports-done =
_nft_for_proto-multiport-iter = for proto in $(echo '<protocol>' | sed 's/,/ /g'); do
_nft_for_proto-multiport-done = done

_nft_list = <nftables> -a list chain <table_family> <table> <chain>
_nft_get_handle_id = grep -oP '@<addr_set>\s+.*\s+\Khandle\s+(\d+)$'

_nft_add_set = <nftables> add set <table_family> <table> <addr_set> \{ type <addr_type>\; \}
              <_nft_for_proto-<type>-iter>
              <nftables> add rule <table_family> <table> <chain> %(rule_stat)s
              <_nft_for_proto-<type>-done>
_nft_del_set = { %(_nft_list)s | %(_nft_get_handle_id)s; } | while read -r hdl; do
               <nftables> delete rule <table_family> <table> <chain> $hdl; done
              <nftables> delete set <table_family> <table> <addr_set>

# Option:  _nft_shutdown_table
# Notes.:  command executed after the stop in order to delete table (it checks that no sets are available):
# Values:  CMD
#
_nft_shutdown_table = { <nftables> list table <table_family> <table> | grep -qP '^\s+set\s+'; } || {
                        <nftables> delete table <table_family> <table>
                      }

# Option:  actionstart
# Notes.:  command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values:  CMD
#
actionstart = <nftables> add table <table_family> <table>
              <nftables> -- add chain <table_family> <table> <chain> \{ type <chain_type> hook <chain_hook> priority <chain_priority> \; \}
              %(_nft_add_set)s

# Option:  actionflush
# Notes.:  command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action);
#          uses `nft flush set ...` and as fallback (e. g. unsupported) recreates the set (with references)
# Values:  CMD
#
actionflush = { <nftables> flush set <table_family> <table> <addr_set> 2> /dev/null; } || {
              %(_nft_del_set)s
              %(_nft_add_set)s
              }

# Option:  actionstop
# Notes.:  command executed at the stop of jail (or at the end of Fail2Ban)
# Values:  CMD
#
actionstop = %(_nft_del_set)s
             <_nft_shutdown_table>

# Option:  actioncheck
# Notes.:  command executed once before each actionban command
# Values:  CMD
#
actioncheck = <nftables> list chain <table_family> <table> <chain> | grep -q '@<addr_set>[ \t]'

# Option:  actionban
# Notes.:  command executed when banning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
actionban = <nftables> add element <table_family> <table> <addr_set> \{ <ip> \}

# Option:  actionunban
# Notes.:  command executed when unbanning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
actionunban = <nftables> delete element <table_family> <table> <addr_set> \{ <ip> \}

[Init]

# Option:  table
# Notes.:  main table to store chain and sets (automatically created on demand)
# Values:  STRING  Default: f2b-table
table = f2b-table

# Option:  table_family
# Notes.:  address family to work in
# Values:  [ip | ip6 | inet]  Default: inet
table_family = inet

# Option:  chain
# Notes.:  main chain to store rules
# Values:  STRING  Default: f2b-chain
chain = f2b-chain

# Option:  chain_type
# Notes.:  refers to the kind of chain to be created
# Values:  [filter | route | nat]  Default: filter
#
chain_type = filter

# Option:  chain_hook
# Notes.:  refers to the kind of chain to be created
# Values:  [ prerouting | input | forward | output | postrouting ]  Default: input
#
chain_hook = input

# Option:  chain_priority
# Notes.:  priority in the chain.
# Values:  NUMBER  Default: -1
#
chain_priority = -1

# Option:  addr_type
# Notes.:  address type to work with
# Values:  [ipv4_addr | ipv6_addr]  Default: ipv4_addr
#
addr_type = ipv4_addr

# Default name of the filtering set
#
name = default

# Option:  port
# Notes.:  specifies port to monitor
# Values:  [ NUM | STRING ]  Default:
#
port = ssh

# Option:  protocol
# Notes.:  internally used by config reader for interpolations.
# Values:  [ tcp | udp ] Default: tcp
#
protocol = tcp

# Option:  blocktype
# Note:    This is what the action does with rules. This can be any jump target
#          as per the nftables man page (section 8). Common values are drop,
#          reject, reject with icmpx type host-unreachable, redirect to 2222
# Values:  STRING
blocktype = reject

# Option:  nftables
# Notes.:  Actual command to be executed, including common to all calls options
# Values:  STRING
nftables = nft

# Option: addr_set
# Notes.: The name of the nft set used to store banned addresses
# Values: STRING
addr_set = addr-set-<name>

# Option: addr_family
# Notes.: The family of the banned addresses
# Values: [ ip | ip6 ]
addr_family = ip

[Init?family=inet6]
addr_family = ip6
addr_type = ipv6_addr
addr_set = addr6-set-<name>
