Compare commits

..

10 commits

5 changed files with 155 additions and 2 deletions

View file

@ -120,6 +120,13 @@
signupAllowed = false; signupAllowed = false;
}; };
# === Forgejo (Self-hosted Git) ===
myModules.forgejo = {
enable = true;
domain = "git.ashisgreat.xyz";
disableRegistration = true; # Admin only
};
# === CrowdSec === # === CrowdSec ===
myModules.crowdsec.enable = true; myModules.crowdsec.enable = true;

View file

@ -47,16 +47,49 @@ in
default = [ "194.242.2.2" "2a07:e340::2" ]; default = [ "194.242.2.2" "2a07:e340::2" ];
description = "Bootstrap DNS servers for resolving DoH upstream"; description = "Bootstrap DNS servers for resolving DoH upstream";
}; };
filters = lib.mkOption {
type = lib.types.listOf (lib.types.submodule {
options = {
name = lib.mkOption {
type = lib.types.str;
description = "Friendly name for the filter list";
};
url = lib.mkOption {
type = lib.types.str;
description = "URL of the filter list (txt format)";
};
enabled = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Whether the filter is enabled";
};
};
});
default = [
{ name = "AdGuard DNS filter"; url = "https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt"; }
{ name = "AdAway Default Blocklist"; url = "https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt"; }
{ name = "HaGeZi Multi Light"; url = "https://hagezi.github.io/dns-blocklists/wildcard/light.txt"; }
{ name = "OISD Basic"; url = "https://small.oisd.nl/"; }
{ name = "Peter Lowe's List"; url = "https://pgl.yoyo.org/adservers/serverlist.php?hostformat=adguard&showintro=0&mimetype=plaintext"; }
];
description = "DNS blocklists to maintain in AdGuard Home";
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# Generate a temporary JSON file containing the filters for yq to inject
systemd.tmpfiles.rules = [
"f /run/adguardhome_filters.json 0644 root root - ${builtins.toJSON { filters = map (f: { inherit (f) name url enabled; }) cfg.filters; }}"
];
services.adguardhome = { services.adguardhome = {
enable = true; enable = true;
host = "127.0.0.1"; host = "127.0.0.1";
port = cfg.port; port = cfg.port;
settings = { settings = {
dns = { dns = {
bind_hosts = [ "127.0.0.1" ]; bind_hosts = [ "0.0.0.0" ];
port = 5353; port = 5353;
upstream_dns = [ cfg.upstreamDoh ]; upstream_dns = [ cfg.upstreamDoh ];
bootstrap_dns = cfg.bootstrapDns; bootstrap_dns = cfg.bootstrapDns;
@ -104,11 +137,22 @@ in
}; };
}; };
# Give AdGuardHome access to ACME certificates # Inject filters into AdGuardHome.yaml before starting
systemd.services.adguardhome = { systemd.services.adguardhome = {
requires = [ "acme-${cfg.domain}.service" ]; requires = [ "acme-${cfg.domain}.service" ];
after = [ "acme-${cfg.domain}.service" ]; after = [ "acme-${cfg.domain}.service" ];
serviceConfig.SupplementaryGroups = [ "acme" "nginx" ]; serviceConfig.SupplementaryGroups = [ "acme" "nginx" ];
serviceConfig.ReadOnlyPaths = [ "/var/lib/acme/${cfg.domain}" ];
serviceConfig.SystemCallFilter = lib.mkForce []; # Allow yq-go to run its syscalls
preStart = lib.mkAfter ''
if [ -f /var/lib/private/AdGuardHome/AdGuardHome.yaml ]; then
${pkgs.yq-go}/bin/yq -i '
.filters = load("/run/adguardhome_filters.json").filters |
.tls.certificate_path = "/var/lib/acme/${cfg.domain}/fullchain.pem" |
.tls.private_key_path = "/var/lib/acme/${cfg.domain}/key.pem"
' /var/lib/private/AdGuardHome/AdGuardHome.yaml
fi
'';
}; };
# Open firewall for DoT # Open firewall for DoT

View file

@ -91,6 +91,17 @@ in
# Remediation profiles # Remediation profiles
localConfig.profiles = [ localConfig.profiles = [
{
name = "block_non_de";
filters = [ "Alert.Remediation == true && Alert.GetScope() == 'Ip' && Alert.Source.Cn != 'DE' && Alert.Source.Cn != ''" ];
decisions = [
{
type = "ban";
duration = "24h";
}
];
on_success = "break";
}
{ {
name = "default_ip_remediation"; name = "default_ip_remediation";
filters = [ "Alert.Remediation == true && Alert.GetScope() == 'Ip'" ]; filters = [ "Alert.Remediation == true && Alert.GetScope() == 'Ip'" ];
@ -106,6 +117,9 @@ in
# Hub collections for common attack patterns # Hub collections for common attack patterns
hub = { hub = {
parsers = [
"crowdsecurity/geoip-enrich"
];
collections = [ collections = [
"crowdsecurity/linux" "crowdsecurity/linux"
"crowdsecurity/nginx" "crowdsecurity/nginx"

View file

@ -10,5 +10,6 @@
./crowdsec.nix ./crowdsec.nix
./backup.nix ./backup.nix
./adguard.nix ./adguard.nix
./forgejo.nix
]; ];
} }

87
modules/forgejo.nix Normal file
View file

@ -0,0 +1,87 @@
# Forgejo Module
# Provides: Self-hosted Git service (Fork of Gitea)
#
# Usage:
# myModules.forgejo = {
# enable = true;
# domain = "git.example.com";
# };
{
config,
lib,
pkgs,
...
}:
let
cfg = config.myModules.forgejo;
in
{
options.myModules.forgejo = {
enable = lib.mkEnableOption "Forgejo Git service";
port = lib.mkOption {
type = lib.types.port;
default = 3002;
description = "Internal port to run Forgejo on";
};
domain = lib.mkOption {
type = lib.types.str;
example = "git.example.com";
description = "Public domain name for Forgejo";
};
disableRegistration = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Disable public user registration";
};
};
config = lib.mkIf cfg.enable {
services.forgejo = {
enable = true;
database.type = "postgres";
settings = {
server = {
DOMAIN = cfg.domain;
ROOT_URL = "https://${cfg.domain}/";
HTTP_ADDR = "127.0.0.1";
HTTP_PORT = cfg.port;
SSH_PORT = 2222;
START_SSH_SERVER = true;
SSH_LISTEN_ADDR = "0.0.0.0";
};
service = {
DISABLE_REGISTRATION = cfg.disableRegistration;
};
session = {
COOKIE_SECURE = true;
};
security = {
PASSWORD_COMPLEXITY = "lower,upper,digit,spec";
MIN_PASSWORD_LENGTH = 12;
};
};
};
# Nginx Reverse Proxy
myModules.nginx.domains."${cfg.domain}" = {
port = cfg.port;
extraConfig = ''
client_max_body_size 512M;
'';
};
# Open SSH port for Git
networking.firewall.allowedTCPPorts = [ 2222 ];
# Backups (Add Forgejo data to restic if backup module is enabled)
myModules.backup.paths = [
config.services.forgejo.stateDir
];
};
}