fail2ban nginx jail: read the journal (NixOS nginx logs errors to stderr, not error.log)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
This commit is contained in:
2026-09-07 21:08:22 +00:00
co-authored by Claude Fable 5.1
parent 666509d53d
commit 536d621865
2 changed files with 7 additions and 4 deletions
+2 -1
View File
@@ -268,7 +268,8 @@ dig +short @<ip> ns-acme.commoninternet.net # acme-dns answering on the public
The opencode UI: `curl -s --resolve oc.ci.commoninternet.net:443:<ip> -o /dev/null -w '%{http_code}' https://oc.ci.commoninternet.net/` The opencode UI: `curl -s --resolve oc.ci.commoninternet.net:443:<ip> -o /dev/null -w '%{http_code}' https://oc.ci.commoninternet.net/`
→ 401 without credentials, 200 with `-u oc:<password>`; `fail2ban-client status nginx-http-auth` → 401 without credentials, 200 with `-u oc:<password>`; `fail2ban-client status nginx-http-auth`
counts the failures. counts the failures (it reads nginx's journal — NixOS nginx logs to stderr, not to
/var/log/nginx/error.log).
When it is healthy: `sudo nixos-rebuild switch --flake .#cc-ci` (same config, now also the boot When it is healthy: `sudo nixos-rebuild switch --flake .#cc-ci` (same config, now also the boot
default). **If you are migrating from another host, do §6 before letting it serve anything**: right default). **If you are migrating from another host, do §6 before letting it serve anything**: right
+5 -3
View File
@@ -58,7 +58,7 @@
}; };
# ---- fail2ban: sshd (password auth is off, this stops the log noise and slow brute force) and # ---- fail2ban: sshd (password auth is off, this stops the log noise and slow brute force) and
# the opencode UI's basic auth (nginx logs 401s with the real client IP to its error log; the # the opencode UI's basic auth (nginx logs 401s with the real client IP to the journal; the
# built-in nginx-http-auth filter matches them). Those clients arrive through traefik's # built-in nginx-http-auth filter matches them). Those clients arrive through traefik's
# docker-published 443, which iptables FORWARDs rather than INPUTs, so the ban for that jail # docker-published 443, which iptables FORWARDs rather than INPUTs, so the ban for that jail
# goes into the DOCKER-USER chain — an INPUT rule would never see the traffic. # goes into the DOCKER-USER chain — an INPUT rule would never see the traffic.
@@ -71,8 +71,10 @@
jails.nginx-http-auth.settings = { jails.nginx-http-auth.settings = {
enabled = true; enabled = true;
filter = "nginx-http-auth"; filter = "nginx-http-auth";
logpath = "/var/log/nginx/error.log"; # NixOS nginx logs errors to stderr → the journal, not /var/log/nginx/error.log (which
backend = "auto"; # exists but stays empty). Read the unit's journal instead.
backend = "systemd";
journalmatch = "_SYSTEMD_UNIT=nginx.service";
banaction = "iptables-allports"; banaction = "iptables-allports";
chain = "DOCKER-USER"; chain = "DOCKER-USER";
}; };