From 026421fd6eeac0f4739bca52d074c1fe54c4bc84 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 28 Sep 2026 20:48:24 +0200 Subject: [PATCH] fail2ban: ban through an action every machine has jail.local named ufw as the ban action. Two machines on this mesh have no ufw, and fail2ban does not check: it starts, the jail reads the log, counts the attempts, runs the ban command, gets 127 -- 'ufw: command not found' -- and logs an error nobody reads. The service is active, the mesh reports the module applied, and the machine is not protected. Proven by banning a documentation address on such a machine today. The replacement is this module's own dualchain action, already used by the recidive jail on all four machines, so it is not a new dependency. It bans in DOCKER-USER as well as INPUT, which ufw's action did not, and it bans all ports, which ufw's action did. --- modules/fail2ban/module.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/fail2ban/module.json b/modules/fail2ban/module.json index fcf27f3..9739868 100644 --- a/modules/fail2ban/module.json +++ b/modules/fail2ban/module.json @@ -33,7 +33,7 @@ "type": "file", "path": "/etc/fail2ban/jail.local", "mode": "0644", - "content": "[INCLUDES]\n\nbefore = paths-arch.conf\n\n[DEFAULT]\n\n# Never act on the machine itself or on a tunnel peer: the mesh's private range is\n# ${machine:mesh-range}, named here rather than written as a value the module cannot\n# know (novox/hq ADR 0112). Without this, fail2ban could ban the mesh's own nodes.\nignoreip = 127.0.0.1/8 ::1 ${machine:mesh-range}\n\nbantime = 10m\nfindtime = 10m\nmaxretry = 5\n\nbanaction = ufw\nbanaction_allports = iptables-allports\n\n[sshd]\nenabled = true\nport = ssh\nlogpath = %(sshd_log)s\nbackend = %(sshd_backend)s\n" + "content": "[INCLUDES]\n\nbefore = paths-arch.conf\n\n[DEFAULT]\n\n# Never act on the machine itself or on a tunnel peer: the mesh's private range is\n# ${machine:mesh-range}, named here rather than written as a value the module cannot\n# know (novox/hq ADR 0112). Without this, fail2ban could ban the mesh's own nodes.\nignoreip = 127.0.0.1/8 ::1 ${machine:mesh-range}\n\nbantime = 10m\nfindtime = 10m\nmaxretry = 5\n\n# Ban through iptables, not through a firewall front-end the machine may not have. ufw is\n# installed on two of this mesh's machines and absent on the other two, and fail2ban finds out\n# only at ban time: the service reports healthy, the jail counts the attempt, the ban command\n# exits 127, and nothing is blocked. Proven on 2026-09-28 -- 'ufw: command not found' on a\n# machine the mesh reported as protected.\n#\n# The action below is this module's own, already used by the recidive jail on every machine\n# here, and it bans in DOCKER-USER as well as INPUT, so a container's published port is\n# covered too.\nbanaction = iptables-allports-dualchain\nbanaction_allports = iptables-allports-dualchain\n\n[sshd]\nenabled = true\nport = ssh\nlogpath = %(sshd_log)s\nbackend = %(sshd_backend)s\n" }, { "id": "jail-sshd",