Skip to content

Commit cd9e741

Browse files
committed
(WIP) Install fail2ban using system manager
1 parent 8fac60d commit cd9e741

File tree

5 files changed

+119
-1
lines changed

5 files changed

+119
-1
lines changed

nix/systemConfigs.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{ self, inputs, ... }:
22
let
33
mkModules = system: [
4+
self.systemModules.fail2ban
45
({
56
services.nginx.enable = true;
67
nixpkgs.hostPlatform = system;
8+
supabase.services.fail2ban.enable = true;
79
})
810
];
911

nix/systemModules/default.nix

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
{
55
imports = [ ./tests ];
66
flake = {
7-
systemModules = { };
7+
systemModules = {
8+
fail2ban = ./fail2ban.nix;
9+
};
810
};
911
}

nix/systemModules/dummy-sshd.nix

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{ lib, ... }:
2+
{
3+
options = {
4+
services.openssh = lib.mkOption {
5+
type = lib.types.attrs;
6+
default = { };
7+
};
8+
};
9+
}

nix/systemModules/fail2ban.nix

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
{
2+
lib,
3+
nixosModulesPath,
4+
config,
5+
...
6+
}:
7+
let
8+
cfg = config.supabase.services.fail2ban;
9+
in
10+
{
11+
imports = [
12+
# We use a dummmy sshd module to workaround this error when importing "/services/networking/ssh/sshd.nix":
13+
# error: The option `users' in module `/nix/store/...-source/nix/modules'
14+
# would be a parent of the following options, but its type `attribute set' does not support nested options.
15+
# - option(s) with prefix `users.users' in module `/nix/store/...-source/nixos/modules/services/networking/ssh/sshd.nix'
16+
./dummy-sshd.nix
17+
]
18+
++ map (path: nixosModulesPath + path) [
19+
"/services/security/fail2ban.nix"
20+
];
21+
22+
options = {
23+
supabase.services.fail2ban = {
24+
enable = lib.mkEnableOption "Fail2Ban";
25+
};
26+
};
27+
28+
config = lib.mkIf cfg.enable {
29+
# TODO: (last bit form Ansible task)
30+
# - name: Configure journald
31+
# copy:
32+
# src: files/fail2ban_config/jail-ssh.conf
33+
# dest: /etc/fail2ban/jail.d/sshd.local
34+
# when: debpkg_mode or nixpkg_mode
35+
supabase.services.fail2ban = {
36+
enable = true; # FIXME: fail2ban was disabled in ansible/tasks/setup-fail2ban.yml
37+
bantime = "3600";
38+
jails = {
39+
postgresql = {
40+
settings = {
41+
enabled = true;
42+
port = "5432";
43+
protocol = "tcp";
44+
filter = "postgresql";
45+
logpath = "/var/log/postgresql/auth-failures.csv";
46+
maxretry = 3;
47+
ignoreip = "192.168.0.0/16 172.17.1.0/20";
48+
};
49+
};
50+
pgbouncer = {
51+
settings = {
52+
enabled = true;
53+
port = "6543";
54+
protocol = "tcp";
55+
filter = "pgbouncer";
56+
backend = "systemd[journalflags=1]";
57+
maxretry = 3;
58+
};
59+
};
60+
};
61+
# TODO: extraPackages = [ pkgs.nftables ];
62+
};
63+
64+
environment.etc = {
65+
"fail2ban/jail.local".text = ''
66+
[DEFAULT]
67+
banaction = nftables-multiport
68+
banaction_allports = nftables-allports
69+
'';
70+
71+
"fail2ban/filter.d/postgresql.conf".text = ''
72+
[Definition]
73+
failregex = ^.*,.*,.*,.*,"<HOST>:.*password authentication failed for user.*$
74+
ignoreregex = ^.*,.*,.*,.*,"127\.0\.0\.1.*password authentication failed for user.*$
75+
^.*,.*,.*,.*,"<HOST>:.*password authentication failed for user ""supabase_admin".*$
76+
^.*,.*,.*,.*,"<HOST>:.*password authentication failed for user ""supabase_auth_admin".*$
77+
^.*,.*,.*,.*,"<HOST>:.*password authentication failed for user ""supabase_storage_admin".*$
78+
^.*,.*,.*,.*,"<HOST>:.*password authentication failed for user ""authenticator".*$
79+
^.*,.*,.*,.*,"<HOST>:.*password authentication failed for user ""pgbouncer".*$
80+
'';
81+
82+
"fail2ban/filter.d/pgbouncer.conf".text = ''
83+
[Definition]
84+
failregex = ^.+@<HOST>:.+password authentication failed$
85+
journalmatch = _SYSTEMD_UNIT=pgbouncer.service
86+
'';
87+
};
88+
89+
systemd.services.fail2ban = {
90+
wantedBy = lib.mkForce [
91+
"system-manager.target"
92+
];
93+
# TODO:
94+
# after = [ "nftables.service" ];
95+
# wants = [ "nftables.service" ];
96+
};
97+
};
98+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# from time import sleep
2+
3+
4+
def test_fail2ban_service(host):
5+
# sleep(5000) # Handy for interactive debugging (with docker exec -it $CONTAINER_ID /bin/bash)
6+
assert host.service("fail2ban.service").is_valid
7+
assert host.service("fail2ban.service").is_running, "Fail2Ban service should be running but failed: {}".format(host.run("systemctl status fail2ban.service").stdout)

0 commit comments

Comments
 (0)