OOKNET                             [ /  search the index  ]  
──────────────────────────────────────────────────────────────────────────────────────
══════════════════════════════════════════════════════════════════════════════════════
OOKNET   [ /  search  ]  
────────────────────────────────────────────────
════════════════════════════════════════════════
 
HASH      e3e5771ea011
DATE      2025-02-01
SUBJECT   fail2ban: initial fail2ban configuration
FILES     6 CHANGED
HASH      e3e5771ea011
DATE      2025-02-01
SUBJECT   fail2ban: initial fail2ban
          configuration
FILES     6 CHANGED
 

diff --git a/README.md b/README.md
index 8a6bb0d..3ede678 100644
--- a/README.md
+++ b/README.md
@@ -4,11 +4,16 @@
 ## Overview
 
 The goals of this repository are:
-1. To maintain a centralized location for all my personal computing infrastructur
e
-2. To provide a place to experiment and learn about networking, administration, s
ecurity, unix, design, and programming
+
+1. To maintain a centralized location for all my personal computing
+   infrastructure
+2. To provide a place to experiment and learn about networking, administration,
+   security, unix, design, and programming
 
 > [!WARNING]
-> This repository is not intended to be used by anyone but myself. It is highly p
ersonalized and likely doesn't fit anyone else's needs. I maintain this repository
 publicly as a reference for anyone building something similar.
+> This repository isn't intended to be used by anyone but myself. It's highly
+> personalized and likely doesn't fit anyone else's needs. I maintain this
+> repository publicly as a reference for anyone building something similar.
 
 ## Features
 
@@ -40,8 +45,10 @@ As this project serves as a learning environment, its architect
ure changes
 frequently. While I'll try to keep this documentation current, what follows is a
 high-level overview of the current design.
 
-The current architecture enables straightfoward bootstrapping of new hosts while 
maintaining fine-grained configuration on a per-host basis. This is accomplished u
sing a roles and profiles pattern (similar to [Puppet's roles and profiles method]
(https://www.puppet.com/docs/puppet/7/the_roles_and_profiles_method.html)).
-
+The current architecture enables straightforward bootstrapping of new hosts
+while maintaining fine-grained configuration on a per-host basis. This is
+accomplished using a roles and profiles pattern (similar to
+[Puppet's roles and profiles method](https://www.puppet.com/docs/puppet/7/the_rol
es_and_profiles_method.html)).
 
 ### Roles
 
@@ -49,7 +56,7 @@ The current architecture enables straightfoward bootstrapping of
 new hosts while
 - **Server**: Headless systems running specific services
 
 Roles are declared via their own respective helper functions `mkWorkstation` and
-`mkServer`. Both being simple wrappers of
+`mkServer`. Both being thin wrappers of
 [`lib.nixosSystem`](https://github.com/NixOS/nixpkgs/blob/e5db80ae487b59b4e9f950d
68983ffb0575e26c6/flake.nix#L21)
 (also see [`lib.evalModules`](https://noogle.dev/f/lib/evalModules)). These
 functions serve to abstract the boilerplate, leaving a simple interface for
@@ -113,12 +120,13 @@ components:
 
 - **Compositor**: [Hyprland](https://github.com/hyprwm/Hyprland)
 - **Utilities**:
-   - **Idle**: [hypridle](https://github.com/hyprwm/hypridle)
-   - **Screen locker**: [hyprlock](https://github.com/hyprwm/hyprlock)
-   - **Wallpaper**: [hyprpaper](https://github.com/hyprwm/hyprpaper)
-   - **Bar**: [Waybar](https://github.com/Alexays/Waybar)
-   - **Notifications**: [Mako](https://github.com/emersion/mako)
-- **Colorscheme**: [Gruvbox extended](https://github.com/ooks-io/ooknet/blob/main
/outputs/hozen/default.nix)
+  - **Idle**: [hypridle](https://github.com/hyprwm/hypridle)
+  - **Screen locker**: [hyprlock](https://github.com/hyprwm/hyprlock)
+  - **Wallpaper**: [hyprpaper](https://github.com/hyprwm/hyprpaper)
+  - **Bar**: [Waybar](https://github.com/Alexays/Waybar)
+  - **Notifications**: [Mako](https://github.com/emersion/mako)
+- **Color Palette**:
+  [Gruvbox extended](https://github.com/ooks-io/ooknet/blob/main/outputs/hozen/de
fault.nix)
 
 ## Appreciation
 

diff --git a/README.md b/README.md
index 8a6bb0d..3ede678 100644
--- a/README.md
+++ b/README.md
@@ -4,11 +4,16 @@
 ## Overview
 
 The goals of this repository are:
-1. To maintain a centralized location for a
ll my personal computing infrastructure
-2. To provide a place to experiment and lea
rn about networking, administration, securit
y, unix, design, and programming
+
+1. To maintain a centralized location for a
ll my personal computing
+   infrastructure
+2. To provide a place to experiment and lea
rn about networking, administration,
+   security, unix, design, and programming
 
 > [!WARNING]
-> This repository is not intended to be use
d by anyone but myself. It is highly persona
lized and likely doesn't fit anyone else's n
eeds. I maintain this repository publicly as
 a reference for anyone building something s
imilar.
+> This repository isn't intended to be used
 by anyone but myself. It's highly
+> personalized and likely doesn't fit anyon
e else's needs. I maintain this
+> repository publicly as a reference for an
yone building something similar.
 
 ## Features
 
@@ -40,8 +45,10 @@ As this project serves as
 a learning environment, its architecture ch
anges
 frequently. While I'll try to keep this doc
umentation current, what follows is a
 high-level overview of the current design.
 
-The current architecture enables straightfo
ward bootstrapping of new hosts while mainta
ining fine-grained configuration on a per-ho
st basis. This is accomplished using a roles
 and profiles pattern (similar to [Puppet's 
roles and profiles method](https://www.puppe
t.com/docs/puppet/7/the_roles_and_profiles_m
ethod.html)).
-
+The current architecture enables straightfo
rward bootstrapping of new hosts
+while maintaining fine-grained configuratio
n on a per-host basis. This is
+accomplished using a roles and profiles pat
tern (similar to
+[Puppet's roles and profiles method](https:
//www.puppet.com/docs/puppet/7/the_roles_and
_profiles_method.html)).
 
 ### Roles
 
@@ -49,7 +56,7 @@ The current architecture e
nables straightfoward bootstrapping of new h
osts while
 - **Server**: Headless systems running spec
ific services
 
 Roles are declared via their own respective
 helper functions `mkWorkstation` and
-`mkServer`. Both being simple wrappers of
+`mkServer`. Both being thin wrappers of
 [`lib.nixosSystem`](https://github.com/NixO
S/nixpkgs/blob/e5db80ae487b59b4e9f950d68983f
fb0575e26c6/flake.nix#L21)
 (also see [`lib.evalModules`](https://noogl
e.dev/f/lib/evalModules)). These
 functions serve to abstract the boilerplate
, leaving a simple interface for
@@ -113,12 +120,13 @@ components:
 
 - **Compositor**: [Hyprland](https://github
.com/hyprwm/Hyprland)
 - **Utilities**:
-   - **Idle**: [hypridle](https://github.co
m/hyprwm/hypridle)
-   - **Screen locker**: [hyprlock](https://
github.com/hyprwm/hyprlock)
-   - **Wallpaper**: [hyprpaper](https://git
hub.com/hyprwm/hyprpaper)
-   - **Bar**: [Waybar](https://github.com/A
lexays/Waybar)
-   - **Notifications**: [Mako](https://gith
ub.com/emersion/mako)
-- **Colorscheme**: [Gruvbox extended](https
://github.com/ooks-io/ooknet/blob/main/outpu
ts/hozen/default.nix)
+  - **Idle**: [hypridle](https://github.com
/hyprwm/hypridle)
+  - **Screen locker**: [hyprlock](https://g
ithub.com/hyprwm/hyprlock)
+  - **Wallpaper**: [hyprpaper](https://gith
ub.com/hyprwm/hyprpaper)
+  - **Bar**: [Waybar](https://github.com/Al
exays/Waybar)
+  - **Notifications**: [Mako](https://githu
b.com/emersion/mako)
+- **Color Palette**:
+  [Gruvbox extended](https://github.com/ook
s-io/ooknet/blob/main/outputs/hozen/default.
nix)
 
 ## Appreciation
 
 

diff --git a/modules/nixos/base/openssh.nix b/modules/nixos/base/openssh.nix
index 72dee2c..22d7ced 100644
--- a/modules/nixos/base/openssh.nix
+++ b/modules/nixos/base/openssh.nix
@@ -1,82 +1,50 @@
 {
-  services.openssh = {
-    enable = true;
-    startWhenNeeded = true;
-    ports = [22];
-    settings = {
-      UseDns = true;
-      PubkeyAuthentication = "yes";
-      PermitRootLogin = "no";
-      PermitEmptyPasswords = "no";
-      PasswordAuthentication = false;
+  services = {
+    openssh = {
+      enable = true;
+      startWhenNeeded = true;
+      ports = [22];
+      settings = {
+        UseDns = true;
+        PubkeyAuthentication = "yes";
+        PermitRootLogin = "no";
+        PermitEmptyPasswords = "no";
+        PasswordAuthentication = false;
 
-      # disable support for .rhost files
-      IgnoreRhosts = "yes";
+        # disable support for .rhost files
+        IgnoreRhosts = "yes";
 
-      # by default openssh uses port 22
+        # by default openssh uses port 22
 
-      # restict key exchange, cipher, and MAC algorithms, as per <https://www.ssh
-audit.com>
-      KexAlgorithms = [
-        "[email protected]"
-        "curve25519-sha256"
-        "[email protected]"
-        "diffie-hellman-group18-sha512"
-        "diffie-hellman-group-exchange-sha256"
-        "diffie-hellman-group16-sha512"
-      ];
-      Ciphers = [
-        "[email protected]"
-        "[email protected]"
-        "aes256-ctr"
-        "aes192-ctr"
-        "[email protected]"
-        "aes128-ctr"
-      ];
-      Macs = [
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-      ];
-      /*
-      HostKeyAlgorithms = [
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-        "[email protected],ssh-ed25519"
-        "ssh-ed25519"
-        "rsa-sha2-512"
-        "rsa-sha2-256"
-      ];
-      CASignatureAlgorithms = [
-        "[email protected]"
-        "ssh-ed25519"
-        "rsa-sha2-512"
-        "rsa-sha2-256"
-      ];
-      GSSAPIKexAlgorithms = [
-        "gss-curve25519-sha256-"
-        "gss-group16-sha512"
-      ];
-      HostbasedAcceptedAlgorithms = [
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-        "ssh-ed25519,rsa-sha2-512"
-        "rsa-sha2-256"
-      ];
-      PubkeyAcceptedAlgorithms = [
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-        "ssh-ed25519"
-        "rsa-sha2-512"
-        "rsa-sha2-256"
-      ];
-      */
+        # restict key exchange, cipher, and MAC algorithms, as per <https://www.s
sh-audit.com>
+        KexAlgorithms = [
+          "[email protected]"
+          "curve25519-sha256"
+          "[email protected]"
+          "diffie-hellman-group18-sha512"
+          "diffie-hellman-group-exchange-sha256"
+          "diffie-hellman-group16-sha512"
+          "ecdh-sha2-nistp256"
+        ];
+        Ciphers = [
+          "[email protected]"
+          "aes128-ctr"
+          "aes192-ctr"
+          "aes256-ctr"
+          "[email protected]"
+          "[email protected]"
+        ];
+        Macs = [
+          "[email protected]"
+          "[email protected]"
+          "[email protected]"
+        ];
+      };
+    };
+    fail2ban.jails.sshd.settings = {
+      enable = true;
+      filter = "sshd";
+      mode = "aggressive";
     };
   };
 }

diff --git a/modules/nixos/base/openssh.nix 
b/modules/nixos/base/openssh.nix
index 72dee2c..22d7ced 100644
--- a/modules/nixos/base/openssh.nix
+++ b/modules/nixos/base/openssh.nix
@@ -1,82 +1,50 @@
 {
-  services.openssh = {
-    enable = true;
-    startWhenNeeded = true;
-    ports = [22];
-    settings = {
-      UseDns = true;
-      PubkeyAuthentication = "yes";
-      PermitRootLogin = "no";
-      PermitEmptyPasswords = "no";
-      PasswordAuthentication = false;
+  services = {
+    openssh = {
+      enable = true;
+      startWhenNeeded = true;
+      ports = [22];
+      settings = {
+        UseDns = true;
+        PubkeyAuthentication = "yes";
+        PermitRootLogin = "no";
+        PermitEmptyPasswords = "no";
+        PasswordAuthentication = false;
 
-      # disable support for .rhost files
-      IgnoreRhosts = "yes";
+        # disable support for .rhost files
+        IgnoreRhosts = "yes";
 
-      # by default openssh uses port 22
+        # by default openssh uses port 22
 
-      # restict key exchange, cipher, and M
AC algorithms, as per <https://www.ssh-audit
.com>
-      KexAlgorithms = [
-        "[email protected]
"
-        "curve25519-sha256"
-        "[email protected]"
-        "diffie-hellman-group18-sha512"
-        "diffie-hellman-group-exchange-sha2
56"
-        "diffie-hellman-group16-sha512"
-      ];
-      Ciphers = [
-        "[email protected]"
-        "[email protected]"
-        "aes256-ctr"
-        "aes192-ctr"
-        "[email protected]"
-        "aes128-ctr"
-      ];
-      Macs = [
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-      ];
-      /*
-      HostKeyAlgorithms = [
-        "[email protected]
m"
-        "[email protected]"
-        "[email protected]"
-        "[email protected],ssh-ed2
5519"
-        "ssh-ed25519"
-        "rsa-sha2-512"
-        "rsa-sha2-256"
-      ];
-      CASignatureAlgorithms = [
-        "[email protected]"
-        "ssh-ed25519"
-        "rsa-sha2-512"
-        "rsa-sha2-256"
-      ];
-      GSSAPIKexAlgorithms = [
-        "gss-curve25519-sha256-"
-        "gss-group16-sha512"
-      ];
-      HostbasedAcceptedAlgorithms = [
-        "[email protected]
m"
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-        "ssh-ed25519,rsa-sha2-512"
-        "rsa-sha2-256"
-      ];
-      PubkeyAcceptedAlgorithms = [
-        "[email protected]
m"
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-        "[email protected]"
-        "ssh-ed25519"
-        "rsa-sha2-512"
-        "rsa-sha2-256"
-      ];
-      */
+        # restict key exchange, cipher, and
 MAC algorithms, as per <https://www.ssh-aud
it.com>
+        KexAlgorithms = [
+          "[email protected]
om"
+          "curve25519-sha256"
+          "[email protected]"
+          "diffie-hellman-group18-sha512"
+          "diffie-hellman-group-exchange-sh
a256"
+          "diffie-hellman-group16-sha512"
+          "ecdh-sha2-nistp256"
+        ];
+        Ciphers = [
+          "[email protected]"
+          "aes128-ctr"
+          "aes192-ctr"
+          "aes256-ctr"
+          "[email protected]"
+          "[email protected]"
+        ];
+        Macs = [
+          "[email protected]"
+          "[email protected]"
+          "[email protected]"
+        ];
+      };
+    };
+    fail2ban.jails.sshd.settings = {
+      enable = true;
+      filter = "sshd";
+      mode = "aggressive";
     };
   };
 }
 

diff --git a/modules/nixos/base/security/README.md b/modules/nixos/base/security/R
EADME.md
new file mode 100644
index 0000000..d077a8d
--- /dev/null
+++ b/modules/nixos/base/security/README.md
@@ -0,0 +1,16 @@
+# Security
+
+Security related modules.
+
+## Resources
+
+- [ssh-audit](https://www.sshaudit.com/)
+- [madaidans-insecurities: Linux Hardening Guide](https://madaidans-insecurities.
github.io/guides/linux-hardening.html)
+- [Arch Linux wiki: Security](https://wiki.archlinux.org/title/Security)
+- [Whonix](https://www.whonix.org/wiki/Documentation)
+- [Kicksecure Documentation](https://www.kicksecure.com/wiki/Documentation)
+- [nix-bitcoin/hardened-extended.nix](https://github.com/fort-nix/nix-bitcoin/blo
b/master/modules/presets/hardened-extended.nix)
+- [nixpkgs hardened profile](https://github.com/NixOS/nixpkgs/blob/master/nixos/m
odules/profiles/hardened.nix)
+- [kernel-hardening-checke](https://github.com/a13xp0p0v/kernel-hardening-checker
)
+- [BlackIkeEagle: Kconfig hardening tests](https://blog.herecura.eu/blog/2020-05-
30-kconfig-hardening-tests)
+- [Linux Kernel Self-Protection Project: Reccomended Settings](https://kspp.githu
b.io/Recommended_Settings)

diff --git a/modules/nixos/base/security/REA
DME.md b/modules/nixos/base/security/README.
md
new file mode 100644
index 0000000..d077a8d
--- /dev/null
+++ b/modules/nixos/base/security/README.md
@@ -0,0 +1,16 @@
+# Security
+
+Security related modules.
+
+## Resources
+
+- [ssh-audit](https://www.sshaudit.com/)
+- [madaidans-insecurities: Linux Hardening 
Guide](https://madaidans-insecurities.github
.io/guides/linux-hardening.html)
+- [Arch Linux wiki: Security](https://wiki.
archlinux.org/title/Security)
+- [Whonix](https://www.whonix.org/wiki/Docu
mentation)
+- [Kicksecure Documentation](https://www.ki
cksecure.com/wiki/Documentation)
+- [nix-bitcoin/hardened-extended.nix](https
://github.com/fort-nix/nix-bitcoin/blob/mast
er/modules/presets/hardened-extended.nix)
+- [nixpkgs hardened profile](https://github
.com/NixOS/nixpkgs/blob/master/nixos/modules
/profiles/hardened.nix)
+- [kernel-hardening-checke](https://github.
com/a13xp0p0v/kernel-hardening-checker)
+- [BlackIkeEagle: Kconfig hardening tests](
https://blog.herecura.eu/blog/2020-05-30-kco
nfig-hardening-tests)
+- [Linux Kernel Self-Protection Project: Re
ccomended Settings](https://kspp.github.io/R
ecommended_Settings)
 

diff --git a/modules/nixos/base/security/default.nix b/modules/nixos/base/security
/default.nix
index b3b71f8..b3c4f37 100644
--- a/modules/nixos/base/security/default.nix
+++ b/modules/nixos/base/security/default.nix
@@ -4,6 +4,7 @@
     ./sudo.nix
     ./kernel.nix
     ./firewall.nix
+    ./fail2ban.nix
     #   ./auditing.nix
     # ./apparmor.nix
   ];

diff --git a/modules/nixos/base/security/def
ault.nix b/modules/nixos/base/security/defau
lt.nix
index b3b71f8..b3c4f37 100644
--- a/modules/nixos/base/security/default.ni
x
+++ b/modules/nixos/base/security/default.ni
x
@@ -4,6 +4,7 @@
     ./sudo.nix
     ./kernel.nix
     ./firewall.nix
+    ./fail2ban.nix
     #   ./auditing.nix
     # ./apparmor.nix
   ];
 

diff --git a/modules/nixos/base/security/fail2ban.nix b/modules/nixos/base/securit
y/fail2ban.nix
new file mode 100644
index 0000000..f83cab0
--- /dev/null
+++ b/modules/nixos/base/security/fail2ban.nix
@@ -0,0 +1,23 @@
+{pkgs, ...}: {
+  services.fail2ban = {
+    enable = true;
+    ignoreIP = [
+      "127.0.0.0/8"
+      "100.64.0.0/10"
+      "192.168.0.0/16"
+    ];
+    extraPackages = [
+      pkgs.ipset
+      pkgs.nftables
+    ];
+
+    bantime = "20m";
+    bantime-increment = {
+      enable = true;
+      multipliers = "4 8 16 32 128 256 512 2048 4116 8236 32944";
+      maxtime = "8760h"; # 1 year
+      overalljails = true;
+    };
+    maxretry = 3;
+  };
+}

diff --git a/modules/nixos/base/security/fai
l2ban.nix b/modules/nixos/base/security/fail
2ban.nix
new file mode 100644
index 0000000..f83cab0
--- /dev/null
+++ b/modules/nixos/base/security/fail2ban.n
ix
@@ -0,0 +1,23 @@
+{pkgs, ...}: {
+  services.fail2ban = {
+    enable = true;
+    ignoreIP = [
+      "127.0.0.0/8"
+      "100.64.0.0/10"
+      "192.168.0.0/16"
+    ];
+    extraPackages = [
+      pkgs.ipset
+      pkgs.nftables
+    ];
+
+    bantime = "20m";
+    bantime-increment = {
+      enable = true;
+      multipliers = "4 8 16 32 128 256 512 
2048 4116 8236 32944";
+      maxtime = "8760h"; # 1 year
+      overalljails = true;
+    };
+    maxretry = 3;
+  };
+}
 

diff --git a/modules/nixos/server/services/forgejo/default.nix b/modules/nixos/ser
ver/services/forgejo/default.nix
index 7cfd06e..f5df02a 100644
--- a/modules/nixos/server/services/forgejo/default.nix
+++ b/modules/nixos/server/services/forgejo/default.nix
@@ -4,8 +4,14 @@
   pkgs,
   ...
 }: let
-  inherit (config.ooknet.server) services domain;
   inherit (lib) mkIf elem getExe;
+
+  inherit (config.ooknet.server) services domain;
+  inherit (config.services) fail2ban;
+
+  settingsFormat = lib.generators.toINI {
+    mkKeyValue = lib.generators.mkKeyValueDefault {} " = ";
+  };
 in {
   config = mkIf (elem "forgejo" services) {
     networking.firewall.allowedTCPPorts = [2222];
@@ -62,25 +68,43 @@ in {
           }
         '';
       };
+
+      fail2ban.jails.forgejo.settings = {
+        filter = "forgejo";
+        mode = "aggressive";
+        action = "nftables-multiport";
+        maxretry = 5;
+        findTime = "24h";
+        bantime = "48h";
+      };
+    };
+    environment = {
+      etc."fail2ban/filter.d/forgejo.conf".text = mkIf fail2ban.enable (settingsF
ormat {
+        Definitions = {
+          failregex = "^.*(Failed authentication attempt|invalid credentials|Atte
mpted access of unknown user).";
+          journalmatch = "_SYSTEMD_UNIT=forgejo.service";
+        };
+      });
+
+      # credit to TLATER
+      # https://discourse.nixos.org/t/how-to-access-forgejo-cli/45370
+      systemPackages = let
+        cfg = config.services.forgejo;
+        forgejo-cli = pkgs.writeScriptBin "forgejo-cli" ''
+          #!${pkgs.runtimeShell}
+          cd ${cfg.stateDir}
+          sudo=exec
+          if [[ "$USER" != forgejo ]]; then
+            sudo='exec /run/wrappers/bin/sudo -u ${cfg.user} -g ${cfg.group} --pr
eserve-env=GITEA_WORK_DIR --preserve-env=GITEA_CUSTOM'
+          fi
+          # Note that these variable names will change
+          export GITEA_WORK_DIR=${cfg.stateDir}
+          export GITEA_CUSTOM=${cfg.customDir}
+          $sudo ${getExe cfg.package} "$@"
+        '';
+      in [
+        forgejo-cli
+      ];
     };
-    # credit to TLATER
-    # https://discourse.nixos.org/t/how-to-access-forgejo-cli/45370
-    environment.systemPackages = let
-      cfg = config.services.forgejo;
-      forgejo-cli = pkgs.writeScriptBin "forgejo-cli" ''
-        #!${pkgs.runtimeShell}
-        cd ${cfg.stateDir}
-        sudo=exec
-        if [[ "$USER" != forgejo ]]; then
-          sudo='exec /run/wrappers/bin/sudo -u ${cfg.user} -g ${cfg.group} --pres
erve-env=GITEA_WORK_DIR --preserve-env=GITEA_CUSTOM'
-        fi
-        # Note that these variable names will change
-        export GITEA_WORK_DIR=${cfg.stateDir}
-        export GITEA_CUSTOM=${cfg.customDir}
-        $sudo ${getExe cfg.package} "$@"
-      '';
-    in [
-      forgejo-cli
-    ];
   };
 }

diff --git a/modules/nixos/server/services/f
orgejo/default.nix b/modules/nixos/server/se
rvices/forgejo/default.nix
index 7cfd06e..f5df02a 100644
--- a/modules/nixos/server/services/forgejo/
default.nix
+++ b/modules/nixos/server/services/forgejo/
default.nix
@@ -4,8 +4,14 @@
   pkgs,
   ...
 }: let
-  inherit (config.ooknet.server) services d
omain;
   inherit (lib) mkIf elem getExe;
+
+  inherit (config.ooknet.server) services d
omain;
+  inherit (config.services) fail2ban;
+
+  settingsFormat = lib.generators.toINI {
+    mkKeyValue = lib.generators.mkKeyValueD
efault {} " = ";
+  };
 in {
   config = mkIf (elem "forgejo" services) {
     networking.firewall.allowedTCPPorts = [
2222];
@@ -62,25 +68,43 @@ in {
           }
         '';
       };
+
+      fail2ban.jails.forgejo.settings = {
+        filter = "forgejo";
+        mode = "aggressive";
+        action = "nftables-multiport";
+        maxretry = 5;
+        findTime = "24h";
+        bantime = "48h";
+      };
+    };
+    environment = {
+      etc."fail2ban/filter.d/forgejo.conf".
text = mkIf fail2ban.enable (settingsFormat 
{
+        Definitions = {
+          failregex = "^.*(Failed authentic
ation attempt|invalid credentials|Attempted 
access of unknown user).";
+          journalmatch = "_SYSTEMD_UNIT=for
gejo.service";
+        };
+      });
+
+      # credit to TLATER
+      # https://discourse.nixos.org/t/how-t
o-access-forgejo-cli/45370
+      systemPackages = let
+        cfg = config.services.forgejo;
+        forgejo-cli = pkgs.writeScriptBin "
forgejo-cli" ''
+          #!${pkgs.runtimeShell}
+          cd ${cfg.stateDir}
+          sudo=exec
+          if [[ "$USER" != forgejo ]]; then
+            sudo='exec /run/wrappers/bin/su
do -u ${cfg.user} -g ${cfg.group} --preserve
-env=GITEA_WORK_DIR --preserve-env=GITEA_CUS
TOM'
+          fi
+          # Note that these variable names 
will change
+          export GITEA_WORK_DIR=${cfg.state
Dir}
+          export GITEA_CUSTOM=${cfg.customD
ir}
+          $sudo ${getExe cfg.package} "$@"
+        '';
+      in [
+        forgejo-cli
+      ];
     };
-    # credit to TLATER
-    # https://discourse.nixos.org/t/how-to-
access-forgejo-cli/45370
-    environment.systemPackages = let
-      cfg = config.services.forgejo;
-      forgejo-cli = pkgs.writeScriptBin "fo
rgejo-cli" ''
-        #!${pkgs.runtimeShell}
-        cd ${cfg.stateDir}
-        sudo=exec
-        if [[ "$USER" != forgejo ]]; then
-          sudo='exec /run/wrappers/bin/sudo
 -u ${cfg.user} -g ${cfg.group} --preserve-e
nv=GITEA_WORK_DIR --preserve-env=GITEA_CUSTO
M'
-        fi
-        # Note that these variable names wi
ll change
-        export GITEA_WORK_DIR=${cfg.stateDi
r}
-        export GITEA_CUSTOM=${cfg.customDir
}
-        $sudo ${getExe cfg.package} "$@"
-      '';
-    in [
-      forgejo-cli
-    ];
   };
 }
 
[ BACK TO LOG ]
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET