How to resolve "No chain/target/match by that name" when using iptables-multiport and Fail2Ban
This issue isn't specifically related to Fail2Ban but is a common way for it to present itself.
The Fail2Ban log output will show something similar to:
2020-06-22 16:18:09,356 fail2ban.actions [17988]: ERROR Failed to execute ban jail 'sasl' action 'iptables-multiport' info 'ActionInfo({'ip': '1.2.3.4', 'fid': <function <lambda> at 0x7f1a0381aa28>, 'family': 'inet4', 'raw-ticket': <function <lambda> at 0x7f1a0381aed8>})': Error starting action Jail('sasl')/iptables-multiport: 'Script error'
2020-06-22 16:18:09,357 fail2ban.actions [17988]: NOTICE [sasl] Ban 1.2.3.4
2020-06-22 16:18:09,376 fail2ban.utils [17988]: ERROR 7f1a0377d3f0 -- exec: iptables -w -N f2b-sasl
iptables -w -A f2b-sasl -j RETURN
iptables -w -I INPUT -p tcp -m multiport --dports 25,587 -j f2b-sasl
2020-06-22 16:18:09,376 fail2ban.utils [17988]: ERROR 7f1a0377d3f0 -- stderr: 'iptables: Chain already exists.'
2020-06-22 16:18:09,376 fail2ban.utils [17988]: ERROR 7f1a0377d3f0 -- stderr: 'iptables: No chain/target/match by that name.'
2020-06-22 16:18:09,377 fail2ban.utils [17988]: ERROR 7f1a0377d3f0 -- returned 1
The issue is likely caused by using iptables-multiport on a server which doesn't (currently) support it.
Firstly check the command manually to confirm it still errors:
# iptables -w -I INPUT -p tcp -m multiport --dports 25,587 -j f2b-sasl
iptables: No chain/target/match by that name.
Check to see if the iptables-multiport module is loaded:
# cat /proc/net/ip_tables_matches
state
icmp
udplite
udp
tcp
If it's not there, attempt to load it, if available:
# modprobe -v xt_multiport
insmod /lib/modules/2.6.32-754.27.1.el6.x86_64/kernel/net/netfilter/xt_multiport.ko
# cat /proc/net/ip_tables_matches
multiport
multiport
state
icmp
udplite
udp
tcp
If it's now listed, you should be able to add IPTables rules as expected and Fail2Ban should work. If not, and a reboot doesn't help, you'll need to modify Fail2Ban to not use multiport.
One way to do this is to add a custom iptables action and split the ports manually. Create actions.d/iptables-custom-multi.conf
with the following content:
# Fail2Ban configuration file for legacy IPTables multiport support
#
# Author: James Lawrie <james@silvermouse.net>
#
#
[INCLUDES]
before = iptables-common.conf
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart = <iptables> -N f2b-<name>
<iptables> -A f2b-<name> -j <returntype>
echo <port> | sed -n 1'p' | tr ',' '\n' | while read port; do
<iptables> -I <chain> -p <protocol> --dport $port -j f2b-<name>
done
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop = echo <port> | sed -n 1'p' | tr ',' '\n' | while read port; do
<iptables> -D <chain> -p <protocol> --dport $port -j f2b-<name>
done
<iptables> -F f2b-<name>
<iptables> -X f2b-<name>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \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 = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype>
# 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 = <iptables> -D f2b-<name> -s <ip> -j <blocktype>
[Init]
And then in your jail.local
file set the banaction to this new action:
[sasl]
enabled = true
port = 25,587
filter = postfix-sasl
logpath = /var/log/maillog
banaction = iptables-custom-multi
maxretry = 10