Compare commits
10 commits
01b19c9fa0
...
748ccc6fc8
| Author | SHA1 | Date | |
|---|---|---|---|
| 748ccc6fc8 | |||
| 6e9de4c189 | |||
| c51c7183c1 | |||
| deedd00762 | |||
| 223f716b85 | |||
| 8a9c513fde | |||
| 7ea9246d74 | |||
| 4790078ff9 | |||
| c3adfa7e25 | |||
| 8f44273faf |
5 changed files with 155 additions and 2 deletions
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,6 @@
|
||||||
./crowdsec.nix
|
./crowdsec.nix
|
||||||
./backup.nix
|
./backup.nix
|
||||||
./adguard.nix
|
./adguard.nix
|
||||||
|
./forgejo.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
87
modules/forgejo.nix
Normal file
87
modules/forgejo.nix
Normal 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
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue