diff --git a/flake.lock b/flake.lock index 28177bd3..8073e81f 100644 --- a/flake.lock +++ b/flake.lock @@ -114,11 +114,11 @@ "uv2nix": "uv2nix" }, "locked": { - "lastModified": 1758177015, - "narHash": "sha256-PCUWdbaxayY3YfSjVlyddBMYoGvSaRysd5AmZ8gqSFs=", + "lastModified": 1759322529, + "narHash": "sha256-yiv/g/tiJI3PI95F7vhTnaf1TDsIkFLrmmFTjWfb6pQ=", "owner": "nix-community", "repo": "authentik-nix", - "rev": "4c626ed84cc0f1278bfba0f534efd6cba2788d75", + "rev": "69fac057b2e553ee17c9a09b822d735823d65a6c", "type": "github" }, "original": { @@ -130,16 +130,16 @@ "authentik-src": { "flake": false, "locked": { - "lastModified": 1758035356, - "narHash": "sha256-DkvxDwHCfSqEpZ9rRXNR8MP0Mz/y1kHAr38exrHQ39c=", + "lastModified": 1759190535, + "narHash": "sha256-pIzDaoDWc58cY/XhsyweCwc4dfRvkaT/zqsV1gDSnCI=", "owner": "goauthentik", "repo": "authentik", - "rev": "680feaefa17934471a6b33ebc35caf5b64120404", + "rev": "8d3a289d12c7de2f244c76493af7880f70d08af2", "type": "github" }, "original": { "owner": "goauthentik", - "ref": "version/2025.8.3", + "ref": "version/2025.8.4", "repo": "authentik", "type": "github" } @@ -212,11 +212,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1759214609, - "narHash": "sha256-+V3SeMjAMd9j9JTECk9oc0gWhtsk79rFEbYf/tHjywo=", + "lastModified": 1759301100, + "narHash": "sha256-hmiTEoVAqLnn80UkreCNunnRKPucKvcg5T4/CELEtbw=", "owner": "nix-community", "repo": "fenix", - "rev": "f93a2d7225bc7a93d3379acff8fe722e21d97852", + "rev": "0956bc5d1df2ea800010172c6bc4470d9a22cb81", "type": "github" }, "original": { @@ -571,11 +571,11 @@ }, "hardware": { "locked": { - "lastModified": 1758663926, - "narHash": "sha256-6CFdj7Xs616t1W4jLDH7IohAAvl5Dyib3qEv/Uqw1rk=", + "lastModified": 1759261527, + "narHash": "sha256-wPd5oGvBBpUEzMF0kWnXge0WITNsITx/aGI9qLHgJ4g=", "owner": "nixos", "repo": "nixos-hardware", - "rev": "170ff93c860b2a9868ed1e1102d4e52cb3d934e1", + "rev": "e087756cf4abbe1a34f3544c480fc1034d68742f", "type": "github" }, "original": { @@ -610,11 +610,11 @@ ] }, "locked": { - "lastModified": 1759236626, - "narHash": "sha256-1BjCUU2csqhR5umGYFnOOTU8r8Bi+bnB2SLsr0FLcws=", + "lastModified": 1759331616, + "narHash": "sha256-LVpodobJvJM5rmfh2sFBHPNX0PYpNbbHzx/gprlKGGg=", "owner": "nix-community", "repo": "home-manager", - "rev": "9e0453a9b0c8ef22de0355b731d712707daa6308", + "rev": "5890176f856dcaf55f3ab56b25d4138657531cbd", "type": "github" }, "original": { @@ -803,11 +803,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1759169434, - "narHash": "sha256-1u6kq88ICeE9IiJPditYa248ZoEqo00kz6iUR+jLvBQ=", + "lastModified": 1759318697, + "narHash": "sha256-iCL/F+rlgzgBfG4QURfjBrxVBMPsXCzZKHXn1SNBshc=", "owner": "hyprwm", "repo": "hyprland", - "rev": "38c1e72c9d81fcdad8f173e06102a5da18836230", + "rev": "e0c96276df75accc853a30186ae5de580b2c725f", "type": "github" }, "original": { @@ -1626,11 +1626,11 @@ "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1759134797, - "narHash": "sha256-YPi+jL3tx/yC5J5l7/OB7Lnlr9BMTzYnZtm7tRJzUNg=", + "lastModified": 1759245522, + "narHash": "sha256-H4Hx/EuMJ9qi1WzPV4UG2bbZiDCdREtrtDvYcHr0kmk=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "062ac7a5451e8e92a32e22a60d86882d6a034f3f", + "rev": "a6bc4a4bbe6a65b71cbf76a0cf528c47a8d9f97f", "type": "github" }, "original": { diff --git a/modules/server/authentik/default.nix b/modules/server/authentik/default.nix index 45895d5d..e23f4d6b 100644 --- a/modules/server/authentik/default.nix +++ b/modules/server/authentik/default.nix @@ -66,7 +66,7 @@ in { jails = { authentik = { serviceName = "authentik"; - failRegex = "^.*Username or password is incorrect. Try again. IP: . Username: .*.$"; + failregex = ^.*Username or password is incorrect.*IP:\s* }; }; }; diff --git a/modules/server/fail2ban/default.nix b/modules/server/fail2ban/default.nix index f50112d3..237bf5e5 100644 --- a/modules/server/fail2ban/default.nix +++ b/modules/server/fail2ban/default.nix @@ -4,11 +4,9 @@ config, pkgs, ... -}: -let +}: let cfg = config.server.fail2ban; -in -{ +in { options.server.fail2ban = { enable = lib.mkEnableOption { description = "Enable cloudflare fail2ban"; @@ -17,7 +15,7 @@ in description = "File containing your API key, scoped to Firewall Rules: Edit"; type = lib.types.str; example = lib.literalExpression '' - Authorization: Bearer Qj06My1wXJEzcW46QCyjFbSMgVtwIGfX63Ki3NOj79o= + Authorization: Bearer vH6-p0y=i4w3n7TjKqZ@x8D_lR!A9b2cOezXgUuJdE5F ''' ''; }; @@ -57,54 +55,54 @@ in pkgs.jq ]; - jails = lib.attrsets.mapAttrs (name: value: { - settings = { - bantime = "30d"; - findtime = "1h"; - enabled = true; - backend = "systemd"; - journalmatch = "_SYSTEMD_UNIT=${value.serviceName}.service"; - port = "http,https"; - filter = "${name}"; - maxretry = 3; - action = "cloudflare-token-agenix"; - }; - }) cfg.jails; + jails = + lib.attrsets.mapAttrs (name: value: { + settings = { + bantime = "24h"; + findtime = "10m"; + enabled = true; + backend = "systemd"; + journalmatch = "_SYSTEMD_UNIT=${value.serviceName}.service"; + port = "http,https"; + filter = "${name}"; + maxretry = 3; + action = "cloudflare-token-agenix"; + }; + }) + cfg.jails; }; environment.etc = lib.attrsets.mergeAttrsList [ (lib.attrsets.mapAttrs' ( - name: value: - (lib.nameValuePair "fail2ban/filter.d/${name}.conf" { - text = '' - [Definition] - failregex = ${value.failRegex} - ignoreregex = ${value.ignoreRegex} - ''; - }) - ) cfg.jails) + name: value: (lib.nameValuePair "fail2ban/filter.d/${name}.conf" { + text = '' + [Definition] + failregex = ${value.failRegex} + ignoreregex = ${value.ignoreRegex} + ''; + }) + ) + cfg.jails) { - "fail2ban/action.d/cloudflare-token-agenix.conf".text = - let - notes = "Fail2Ban on ${config.networking.hostName}"; - cfapi = "https://api.cloudflare.com/client/v4/zones/${cfg.zoneId}/firewall/access_rules/rules"; - in - '' - [Definition] - actionstart = - actionstop = - actioncheck = - actionunban = id=$(curl -s -X GET "${cfapi}" \ - -H @${cfg.apiKeyFile} -H "Content-Type: application/json" \ - | jq -r '.result[] | select(.notes == "${notes}" and .configuration.target == "ip" and .configuration.value == "") | .id') - if [ -z "$id" ]; then echo "id for cannot be found"; exit 0; fi; \ - curl -s -X DELETE "${cfapi}/$id" \ - -H @${cfg.apiKeyFile} -H "Content-Type: application/json" \ - --data '{"cascade": "none"}' - actionban = curl -X POST "${cfapi}" -H @${cfg.apiKeyFile} -H "Content-Type: application/json" --data '{"mode":"block","configuration":{"target":"ip","value":""},"notes":"${notes}"}' - [Init] - name = cloudflare-token-agenix - ''; + "fail2ban/action.d/cloudflare-token-agenix.conf".text = let + notes = "Fail2Ban on ${config.networking.hostName}"; + cfapi = "https://api.cloudflare.com/client/v4/zones/${cfg.zoneId}/firewall/access_rules/rules"; + in '' + [Definition] + actionstart = + actionstop = + actioncheck = + actionunban = id=$(curl -s -X GET "${cfapi}" \ + -H @${cfg.apiKeyFile} -H "Content-Type: application/json" \ + | jq -r '.result[] | select(.notes == "${notes}" and .configuration.target == "ip" and .configuration.value == "") | .id') + if [ -z "$id" ]; then echo "id for cannot be found"; exit 0; fi; \ + curl -s -X DELETE "${cfapi}/$id" \ + -H @${cfg.apiKeyFile} -H "Content-Type: application/json" \ + --data '{"cascade": "none"}' + actionban = curl -X POST "${cfapi}" -H @${cfg.apiKeyFile} -H "Content-Type: application/json" --data '{"mode":"block","configuration":{"target":"ip","value":""},"notes":"${notes}"}' + [Init] + name = cloudflare-token-agenix + ''; } ]; };