I've been trying to follow the ArchWiki instructions on hardening Fail2Ban:
https://wiki.archlinux.org/title/Fail2ban#Service_hardening
Specifically I've created a drop-in file as described and started the service. The issue is that I see log entries like:
fail2ban.actions [1500]: NOTICE [sshd] Ban xxx.xxx.xxx.xxx
fail2ban.utils [1500]: ERROR 7f76a9d13550 -- exec: { iptables -w -C f2b-sshd -j RETURN >/dev/null 2>&1; } || { iptables -w -N f2b-sshd || true; iptables -w -A f2b-sshd -j RETURN; }
for proto in $(echo 'tcp' | sed 's/,/ /g'); do
{ iptables -w -C INPUT -p $proto -m multiport --dports ssh -j f2b-sshd >/dev/null 2>&1; } || { iptables -w -I INPUT -p $proto -m multiport --dports ssh -j f2b-sshd; }
done
fail2ban.utils [1500]: ERROR 7f76a9d13550 -- stderr: "Fatal: can't open lock file /run/xtables.lock: Read-only file system"
fail2ban.utils [1500]: ERROR 7f76a9d13550 -- stderr: "Fatal: can't open lock file /run/xtables.lock: Read-only file system"
fail2ban.utils [1500]: ERROR 7f76a9d13550 -- stderr: "Fatal: can't open lock file /run/xtables.lock: Read-only file system"
fail2ban.utils [1500]: ERROR 7f76a9d13550 -- returned 4
fail2ban.actions [1500]: ERROR Failed to execute ban jail 'sshd' action 'iptables-multiport' info 'ActionInfo({'ip': 'xxx.xxx.xxx.xxx', 'family': 'inet4', 'fid': <function Actions.ActionInfo.<lambda> at 0x7f76b0c713f0>, 'raw-ticket': <function Actions.ActionInfo.<lambda> at 0x7f76b0c71ab0>})': Error starting action Jail('sshd')/iptables-multiport: 'Script error'
even though systemctl show fail2ban.service | grep xtables
shows that /run/xtables.lock
is listed in ReadWritePaths
.
I presume this is because the file doesn't exist when the service starts, and hence can't be mounted read/write into sandbox. I can work around this by running:
sudo touch /run/xtables.lock
and restarting the service, but have to do this every time the server is restarted (/run
is tmpfs
).
Not sure what the best way to fix this is. I thought I might be able to use ExecStartPre
to run that touch
command, but it seems that is run in the sandbox as well so doesn't have write access to /run
.