diff --git a/config/action.d/nftables.conf b/config/action.d/nftables.conf index 79efbde2..49e2e917 100644 --- a/config/action.d/nftables.conf +++ b/config/action.d/nftables.conf @@ -32,8 +32,9 @@ after = nftables-common.local # type = multiport +rule_match-custom = rule_match-allports = meta l4proto \{ \} -rule_match-multiport = dport \{ \} +rule_match-multiport = $proto dport \{ \} match = > # Option: rule_stat @@ -43,6 +44,14 @@ match = > # rule_stat = %(match)s saddr @ +# 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 '' | sed 's/,/ /g'); do +_nft_for_proto-multiport-done = done + # 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 @@ -50,17 +59,19 @@ rule_stat = %(match)s saddr @ actionstart = add table f2b-table -- add chain f2b-table f2b-chain \{ type hook priority \; \} add set f2b-table \{ type \; \} + <_nft_for_proto--iter> add rule f2b-table f2b-chain %(rule_stat)s + <_nft_for_proto--done> _nft_list = -a list chain f2b-table f2b-chain -_nft_get_handle_id = grep -m1 '@ ' | grep -oe ' handle [0-9]*' +_nft_get_handle_id = grep -oP '@ .* \Khandle (\d+)$' # Option: actionstop # Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # -actionstop = HANDLE_ID=$(%(_nft_list)s | %(_nft_get_handle_id)s) - delete rule f2b-table f2b-chain $HANDLE_ID +actionstop = $(%(_nft_list)s | %(_nft_get_handle_id)s) | while read -r hdl ; do + delete rule f2b-table f2b-chain $hdl; done delete set f2b-table # Option: actioncheck diff --git a/fail2ban/tests/servertestcase.py b/fail2ban/tests/servertestcase.py index 6375ea24..aaa5c42c 100644 --- a/fail2ban/tests/servertestcase.py +++ b/fail2ban/tests/servertestcase.py @@ -1257,29 +1257,32 @@ class ServerConfigReaderTests(LogCaptureTestCase): # etc. testJailsActions = ( # nftables-multiport -- - ('j-w-nft-mp', 'nftables-multiport[name=%(__name__)s, port="http,https", protocol="tcp"]', { + ('j-w-nft-mp', 'nftables-multiport[name=%(__name__)s, port="http,https", protocol="tcp,udp,sctp"]', { 'ip4': ('ip ', 'ipv4_addr', 'addr-'), 'ip6': ('ip6 ', 'ipv6_addr', 'addr6-'), '*-start': ( r"`nft add table inet f2b-table`", r"`nft -- add chain inet f2b-table f2b-chain \{ type filter hook input priority -1 \; \}`", + # iterator over protocol is same for both families: + r"`for proto in $(echo 'tcp,udp,sctp' | sed 's/,/ /g'); do`", + r"`done`", ), 'ip4-start': ( r"`nft add set inet f2b-table addr-set-j-w-nft-mp \{ type ipv4_addr\; \}`", - r"`nft add rule inet f2b-table f2b-chain tcp dport \{ http,https \} ip saddr @addr-set-j-w-nft-mp reject`", + r"`nft add rule inet f2b-table f2b-chain $proto dport \{ http,https \} ip saddr @addr-set-j-w-nft-mp reject`", ), 'ip6-start': ( r"`nft add set inet f2b-table addr6-set-j-w-nft-mp \{ type ipv6_addr\; \}`", - r"`nft add rule inet f2b-table f2b-chain tcp dport \{ http,https \} ip6 saddr @addr6-set-j-w-nft-mp reject`", + r"`nft add rule inet f2b-table f2b-chain $proto dport \{ http,https \} ip6 saddr @addr6-set-j-w-nft-mp reject`", ), 'flush': ( # todo ), 'stop': ( - "`HANDLE_ID=$(nft -a list chain inet f2b-table f2b-chain | grep -m1 '@addr-set-j-w-nft-mp ' | grep -oe ' handle [0-9]*')`", - "`nft delete rule inet f2b-table f2b-chain $HANDLE_ID`", + "`$(nft -a list chain inet f2b-table f2b-chain | grep -oP '@addr-set-j-w-nft-mp .* \Khandle (\d+)$') | while read -r hdl`", + "`nft delete rule inet f2b-table f2b-chain $hdl; done`", "`nft delete set inet f2b-table addr-set-j-w-nft-mp`", - "`HANDLE_ID=$(nft -a list chain inet f2b-table f2b-chain | grep -m1 '@addr6-set-j-w-nft-mp ' | grep -oe ' handle [0-9]*')`", - "`nft delete rule inet f2b-table f2b-chain $HANDLE_ID`", + "`$(nft -a list chain inet f2b-table f2b-chain | grep -oP '@addr6-set-j-w-nft-mp .* \Khandle (\d+)$') | while read -r hdl`", + "`nft delete rule inet f2b-table f2b-chain $hdl; done`", "`nft delete set inet f2b-table addr6-set-j-w-nft-mp`", ), 'ip4-check': ( @@ -1320,11 +1323,11 @@ class ServerConfigReaderTests(LogCaptureTestCase): # todo ), 'stop': ( - "`HANDLE_ID=$(nft -a list chain inet f2b-table f2b-chain | grep -m1 '@addr-set-j-w-nft-ap ' | grep -oe ' handle [0-9]*')`", - "`nft delete rule inet f2b-table f2b-chain $HANDLE_ID`", + "`$(nft -a list chain inet f2b-table f2b-chain | grep -oP '@addr-set-j-w-nft-ap .* \Khandle (\d+)$') | while read -r hdl`", + "`nft delete rule inet f2b-table f2b-chain $hdl; done`", "`nft delete set inet f2b-table addr-set-j-w-nft-ap`", - "`HANDLE_ID=$(nft -a list chain inet f2b-table f2b-chain | grep -m1 '@addr6-set-j-w-nft-ap ' | grep -oe ' handle [0-9]*')`", - "`nft delete rule inet f2b-table f2b-chain $HANDLE_ID`", + "`$(nft -a list chain inet f2b-table f2b-chain | grep -oP '@addr6-set-j-w-nft-ap .* \Khandle (\d+)$') | while read -r hdl`", + "`nft delete rule inet f2b-table f2b-chain $hdl; done`", "`nft delete set inet f2b-table addr6-set-j-w-nft-ap`", ), 'ip4-check': (