allow to use multiple protocols in multiport (single set with multiple rules in chain):

`banaction = nftables[type=multiport]` with `protocol="tcp,udp,sctp"` in jail replace 3 separate actions.
more robust if deleting multiple references to set (rules in chain)
pull/2254/head
sebres 2019-09-24 19:43:56 +02:00
parent c753ffb11d
commit abc4d9fe37
2 changed files with 29 additions and 15 deletions

View File

@ -32,8 +32,9 @@ after = nftables-common.local
# #
type = multiport type = multiport
rule_match-custom =
rule_match-allports = meta l4proto \{ <protocol> \} rule_match-allports = meta l4proto \{ <protocol> \}
rule_match-multiport = <protocol> dport \{ <port> \} rule_match-multiport = $proto dport \{ <port> \}
match = <rule_match-<type>> match = <rule_match-<type>>
# Option: rule_stat # Option: rule_stat
@ -43,6 +44,14 @@ match = <rule_match-<type>>
# #
rule_stat = %(match)s <addr_family> saddr @<addr_set> <blocktype> 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
# Option: actionstart # 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). # 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 # Values: CMD
@ -50,17 +59,19 @@ rule_stat = %(match)s <addr_family> saddr @<addr_set> <blocktype>
actionstart = <nftables> add table <table_family> f2b-table actionstart = <nftables> add table <table_family> f2b-table
<nftables> -- add chain <table_family> f2b-table f2b-chain \{ type <chain_type> hook <chain_hook> priority <chain_priority> \; \} <nftables> -- add chain <table_family> f2b-table f2b-chain \{ type <chain_type> hook <chain_hook> priority <chain_priority> \; \}
<nftables> add set <table_family> f2b-table <addr_set> \{ type <addr_type>\; \} <nftables> add set <table_family> f2b-table <addr_set> \{ type <addr_type>\; \}
<_nft_for_proto-<type>-iter>
<nftables> add rule <table_family> f2b-table f2b-chain %(rule_stat)s <nftables> add rule <table_family> f2b-table f2b-chain %(rule_stat)s
<_nft_for_proto-<type>-done>
_nft_list = <nftables> -a list chain <table_family> f2b-table f2b-chain _nft_list = <nftables> -a list chain <table_family> f2b-table f2b-chain
_nft_get_handle_id = grep -m1 '@<addr_set> ' | grep -oe ' handle [0-9]*' _nft_get_handle_id = grep -oP '@<addr_set> .* \Khandle (\d+)$'
# Option: actionstop # Option: actionstop
# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Notes.: command executed at the stop of jail (or at the end of Fail2Ban)
# Values: CMD # Values: CMD
# #
actionstop = HANDLE_ID=$(%(_nft_list)s | %(_nft_get_handle_id)s) actionstop = $(%(_nft_list)s | %(_nft_get_handle_id)s) | while read -r hdl ; do
<nftables> delete rule <table_family> f2b-table f2b-chain $HANDLE_ID <nftables> delete rule <table_family> f2b-table f2b-chain $hdl; done
<nftables> delete set <table_family> f2b-table <addr_set> <nftables> delete set <table_family> f2b-table <addr_set>
# Option: actioncheck # Option: actioncheck

View File

@ -1257,29 +1257,32 @@ class ServerConfigReaderTests(LogCaptureTestCase):
# etc. # etc.
testJailsActions = ( testJailsActions = (
# nftables-multiport -- # 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-'), 'ip4': ('ip ', 'ipv4_addr', 'addr-'), 'ip6': ('ip6 ', 'ipv6_addr', 'addr6-'),
'*-start': ( '*-start': (
r"`nft add table inet f2b-table`", r"`nft add table inet f2b-table`",
r"`nft -- add chain inet f2b-table f2b-chain \{ type filter hook input priority -1 \; \}`", 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': ( 'ip4-start': (
r"`nft add set inet f2b-table addr-set-j-w-nft-mp \{ type ipv4_addr\; \}`", 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': ( 'ip6-start': (
r"`nft add set inet f2b-table addr6-set-j-w-nft-mp \{ type ipv6_addr\; \}`", 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': ( 'flush': (
# todo # todo
), ),
'stop': ( '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 -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 $HANDLE_ID`", "`nft delete rule inet f2b-table f2b-chain $hdl; done`",
"`nft delete set inet f2b-table addr-set-j-w-nft-mp`", "`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 -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 $HANDLE_ID`", "`nft delete rule inet f2b-table f2b-chain $hdl; done`",
"`nft delete set inet f2b-table addr6-set-j-w-nft-mp`", "`nft delete set inet f2b-table addr6-set-j-w-nft-mp`",
), ),
'ip4-check': ( 'ip4-check': (
@ -1320,11 +1323,11 @@ class ServerConfigReaderTests(LogCaptureTestCase):
# todo # todo
), ),
'stop': ( '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 -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 $HANDLE_ID`", "`nft delete rule inet f2b-table f2b-chain $hdl; done`",
"`nft delete set inet f2b-table addr-set-j-w-nft-ap`", "`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 -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 $HANDLE_ID`", "`nft delete rule inet f2b-table f2b-chain $hdl; done`",
"`nft delete set inet f2b-table addr6-set-j-w-nft-ap`", "`nft delete set inet f2b-table addr6-set-j-w-nft-ap`",
), ),
'ip4-check': ( 'ip4-check': (