feat: add fail2ban setup for services
Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
This commit is contained in:
parent
12cf2f3701
commit
4cb83f945d
@ -58,9 +58,34 @@
|
|||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = "http://localhost:8096/";
|
proxyPass = "http://localhost:8096/";
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.fail2ban.jails.jellyfin = {
|
||||||
|
enabled = true;
|
||||||
|
filter = "jellyfin";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
jellyfin = {
|
||||||
|
target = "fail2ban/filter.d/jellyfin.conf";
|
||||||
|
text = ''
|
||||||
|
[INCLUDES]
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
failregex = ^.*Authentication request for .* has been denied \(IP: "<ADDR>"\)\.
|
||||||
|
ignoreregex =
|
||||||
|
journalmatch = _SYSTEMD_UNIT=jellyfin.service
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -22,5 +22,20 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
environment.etc = {
|
||||||
|
jellyseerr = {
|
||||||
|
target = "fail2ban/filter.d/jellyseerr.conf";
|
||||||
|
text = ''
|
||||||
|
[INCLUDES]
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
failregex = ^.*\[warn\]\[API\]: Failed sign-in attempt using invalid Overseerr password {"ip":"<HOST>","email":
|
||||||
|
^.*\[warn\]\[Auth\]: Failed login attempt from user with incorrect Jellyfin credentials {"account":{"ip":"<HOST>","email":
|
||||||
|
ignoreregex =
|
||||||
|
journalmatch = _SYSTEMD_UNIT=jellyseerr.service
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
67
modules/nixos/services/fail2ban/default.nix
Normal file
67
modules/nixos/services/fail2ban/default.nix
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
options.snowflake.services.fail2ban = {
|
||||||
|
enable = lib.mkEnableOption "Enable fail2ban service";
|
||||||
|
|
||||||
|
extraIgnoreIPs = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [];
|
||||||
|
description = "List of IPs to ignore for fail2ban alongside the default local subnets and loopback";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = let
|
||||||
|
cfg = config.snowflake.services.fail2ban;
|
||||||
|
in
|
||||||
|
lib.mkIf cfg.enable {
|
||||||
|
services.fail2ban = {
|
||||||
|
enable = true;
|
||||||
|
maxretry = 3;
|
||||||
|
banaction-allports = "iptables-allports";
|
||||||
|
|
||||||
|
bantime-increment = {
|
||||||
|
enable = true;
|
||||||
|
maxtime = "168h";
|
||||||
|
factor = "4";
|
||||||
|
};
|
||||||
|
|
||||||
|
ignoreIPs =
|
||||||
|
[
|
||||||
|
"192.168.69.0/16"
|
||||||
|
"172.16.0.0/12"
|
||||||
|
"127.0.0.0/8"
|
||||||
|
]
|
||||||
|
++ cfg.extraIgnoreIPs;
|
||||||
|
|
||||||
|
jails = {
|
||||||
|
DEFAULT = {
|
||||||
|
blocktype = "DROP";
|
||||||
|
bantime = "6h";
|
||||||
|
findtime = "6h";
|
||||||
|
};
|
||||||
|
|
||||||
|
sshd = {
|
||||||
|
settings = {
|
||||||
|
enabled = true;
|
||||||
|
findtime = "1d";
|
||||||
|
maxretry = 4;
|
||||||
|
mode = "aggressive";
|
||||||
|
port = "ssh";
|
||||||
|
logpath = "%(sshd_log)s";
|
||||||
|
backend = "%(sshd_backend)s";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
port-scan = {
|
||||||
|
filter = "port-scan";
|
||||||
|
action = "iptables-allports[name=port-scan]";
|
||||||
|
bantime = 86400;
|
||||||
|
maxretry = 2;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -108,5 +108,22 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.fail2ban.jails.gitea = {
|
||||||
|
enabled = true;
|
||||||
|
filter = "gitea";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
gitea = {
|
||||||
|
target = "fail2ban/filter.d/gitea.conf";
|
||||||
|
text = ''
|
||||||
|
[Definition]
|
||||||
|
failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
|
||||||
|
ignoreregex =
|
||||||
|
journalmatch = _SYSTEMD_UNIT=gitea.service
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -47,5 +47,25 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.fail2ban.jails.immich = {
|
||||||
|
enabled = true;
|
||||||
|
filter = "immich";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
immich = {
|
||||||
|
target = "fail2ban/filter.d/immich.conf";
|
||||||
|
text = ''
|
||||||
|
[INCLUDES]
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
|
||||||
|
ignoreregex =
|
||||||
|
journalmatch = _SYSTEMD_UNIT=immich-server.service
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
{ config, lib, ... }:
|
|
||||||
{
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
options.snowflake.services.miniflux = {
|
options.snowflake.services.miniflux = {
|
||||||
enable = lib.mkEnableOption "Enable miniflux service";
|
enable = lib.mkEnableOption "Enable miniflux service";
|
||||||
|
|
||||||
@ -20,10 +23,9 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config =
|
config = let
|
||||||
let
|
cfg = config.snowflake.services.miniflux;
|
||||||
cfg = config.snowflake.services.miniflux;
|
in
|
||||||
in
|
|
||||||
lib.mkIf cfg.enable {
|
lib.mkIf cfg.enable {
|
||||||
age.secrets.miniflux = {
|
age.secrets.miniflux = {
|
||||||
inherit (cfg.adminTokenFile) file;
|
inherit (cfg.adminTokenFile) file;
|
||||||
@ -49,7 +51,6 @@
|
|||||||
proxyPass = "http://localhost:${toString cfg.listenPort}";
|
proxyPass = "http://localhost:${toString cfg.listenPort}";
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
'';
|
'';
|
||||||
@ -57,5 +58,22 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.fail2ban.jails.miniflux = {
|
||||||
|
enabled = true;
|
||||||
|
filter = "miniflux";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
miniflux = {
|
||||||
|
target = "fail2ban/filter.d/miniflux.conf";
|
||||||
|
text = ''
|
||||||
|
[Definition]
|
||||||
|
failregex = ^.*msg="[^"]*(Incorrect|Invalid) username or password[^"]*".*client_ip=<ADDR>
|
||||||
|
ignoreregex =
|
||||||
|
journalmatch = _SYSTEMD_UNIT=miniflux.service
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,6 @@
|
|||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
proxy_request_buffering off;
|
proxy_request_buffering off;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
client_max_body_size 0;
|
client_max_body_size 0;
|
||||||
|
@ -73,5 +73,22 @@
|
|||||||
echo ${path}/exported/
|
echo ${path}/exported/
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.fail2ban.jails.paperless = {
|
||||||
|
enabled = true;
|
||||||
|
filter = "paperless";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
paperless-ngx = {
|
||||||
|
target = "fail2ban/filter.d/paperless.conf";
|
||||||
|
text = ''
|
||||||
|
[Definition]
|
||||||
|
failregex = Login failed for user `.*` from (?:IP|private IP) `<HOST>`\.$
|
||||||
|
ignoreregex =
|
||||||
|
journalmatch = _SYSTEMD_UNIT=paperless-web.service
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -77,5 +77,20 @@
|
|||||||
snowflake.services.backups.config.vaultwarden.paths = [
|
snowflake.services.backups.config.vaultwarden.paths = [
|
||||||
"/var/lib/bitwarden_rs"
|
"/var/lib/bitwarden_rs"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
vaultwarden = {
|
||||||
|
target = "fail2ban/filter.d/vaultwarden.conf";
|
||||||
|
text = ''
|
||||||
|
[INCLUDES]
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
|
||||||
|
ignoreregex =
|
||||||
|
journalmatch = _SYSTEMD_UNIT=vaultwarden.service
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user