From 78cb82a06168bc2938ee8a83776062a3c638280c Mon Sep 17 00:00:00 2001 From: Ahwx Date: Tue, 3 Jun 2025 10:33:07 +0200 Subject: [PATCH 1/4] fix: make sudo sad --- modules/core/security.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/security.nix b/modules/core/security.nix index 74af49c..00d59d3 100644 --- a/modules/core/security.nix +++ b/modules/core/security.nix @@ -36,7 +36,7 @@ --replace "incorrect password attempts" "nuu silly, try again ~ >.< ~" \ --replace "incorrect password attempt" "nuu silly, try again ~ >.< ~" \ --replace "authentication failure" "oepsie woepsie alles is stukkie wukkie :3" \ - --replace "a password is required" "no password for me? 🥺\n" + --replace "a password is required" "no password? 😭\n" ''; configureFlags = (builtins.filter (x: !(lib.strings.hasPrefix x "--with-passprompt=")) old.configureFlags) From f113d19c33e64a4a3aef355935041d82587a11c3 Mon Sep 17 00:00:00 2001 From: Ahwx Date: Tue, 3 Jun 2025 10:33:18 +0200 Subject: [PATCH 2/4] fix: make unifi work again --- modules/services/unifi.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/unifi.nix b/modules/services/unifi.nix index c206c3d..fa0c49d 100644 --- a/modules/services/unifi.nix +++ b/modules/services/unifi.nix @@ -3,7 +3,7 @@ { services.unifi = { enable = true; - unifiPackage = pkgs.unifi8; + unifiPackage = pkgs.unifi; mongodbPackage = pkgs.mongodb-7_0; }; # services.nginx = { From da80328deba43dd8bba380115b6cbce00c60ece2 Mon Sep 17 00:00:00 2001 From: Ahwx Date: Tue, 3 Jun 2025 10:33:55 +0200 Subject: [PATCH 3/4] feat: define dhcp settings and subnets etc --- hosts/lily/default.nix | 185 ++++++++++++++++++++++++++++++----------- hosts/lily/dns.nix | 2 +- 2 files changed, 138 insertions(+), 49 deletions(-) diff --git a/hosts/lily/default.nix b/hosts/lily/default.nix index fba412b..b6d57ce 100644 --- a/hosts/lily/default.nix +++ b/hosts/lily/default.nix @@ -11,6 +11,24 @@ let # internalIPs = lib.mapAttrsToList ( # _: val: lib.strings.removeSuffix ".1" val.cidr + ".0/24" # ) networks; + commonDhcpOptions = [ + { + name = "domain-name-servers"; + data = "9.9.9.9"; + } + { + name = "time-servers"; + data = "172.16.1.1"; + } + { + name = "domain-name"; + data = "beeping.local"; + } + { + name = "domain-search"; + data = "beeping.local"; + } + ]; in { imports = [ @@ -51,7 +69,26 @@ in }; }; + # label network interfaces + services.udev.extraRules = '' + SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:90:47:67:6e", ATTR{type}=="1", NAME="wan0" + SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:90:47:67:6f", ATTR{type}=="1", NAME="lan0" + SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:90:63:0f:80", ATTR{type}=="1", NAME="lan1" + SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:90:63:0f:81", ATTR{type}=="1", NAME="lan2" + ''; + networking = { + nameservers = [ + "9.9.9.9" + "149.112.112.112" + ]; + interfaces = { + wan0.useDHCP = true; + lan0.useDHCP = false; + lan1.useDHCP = false; + lan2.useDHCP = false; + }; + firewall = { enable = false; allowPing = true; @@ -101,56 +138,108 @@ in }; services = { - udev.extraRules = '' - SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:90:47:67:6e", ATTR{type}=="1", NAME="wan0" - SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:90:47:67:6f", ATTR{type}=="1", NAME="lan0" - SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:90:63:0f:80", ATTR{type}=="1", NAME="lan1" - SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:90:63:0f:81", ATTR{type}=="1", NAME="lan2" - ''; - dhcpd4 = { + kea.dhcp4 = { enable = true; - interfaces = [ - "lan" - "servers" - "management" - "iot" - "guest" - ]; - extraConfig = '' - option domain-name-servers 9.9.9.9, 149.112.112.112; - option subnet-mask 255.255.255.0; + settings = { + lease-database = { + name = "/var/lib/kea/dhcp4.leases"; + persist = true; + type = "memfile"; + }; + interfaces-config = { + interfaces = [ + "lan" + "servers" + "management" + "iot" + "guest" + ]; + }; + option-data = [ + { + name = "domain-name-servers"; + data = ""; + always-send = true; + } + { + name = "routers"; + data = ""; + } + { + name = "domain-name"; + data = "beeping.local"; + } + ]; - subnet 172.16.1.0 netmask 255.255.255.0 { - option broadcast-address 172.16.1.255; - option routers 172.16.1.1; - interface lan; - range 172.16.1.50 172.16.1.254; - } - subnet 172.16.10.0 netmask 255.255.255.0 { - option broadcast-address 172.16.10.255; - option routers 172.16.10.1; - interface servers; - range 172.16.10.50 172.16.10.254; - } - subnet 172.16.21.0 netmask 255.255.255.0 { - option broadcast-address 172.16.21.255; - option routers 172.16.21.1; - interface management; - range 172.16.21.50 172.16.21.254; - } - subnet 172.16.100.0 netmask 255.255.255.0 { - option broadcast-address 172.16.100.255; - option routers 172.16.100.1; - interface iot; - range 172.16.100.50 172.16.100.254; - } - subnet 172.16.110.0 netmask 255.255.255.0 { - option broadcast-address 172.16.110.255; - option routers 172.16.110.1; - interface guest; - range 172.16.110.50 172.16.110.254; - } - ''; + rebind-timer = 2000; + renew-timer = 1000; + valid-lifetime = 43200; + + # option domain-name-servers 9.9.9.9, 149.112.112.112; + # TODO: these should be dynamically generated based on ${config.networking.vlans} + subnet4 = [ + ({ + id = 1; + interface = "lan"; + subnet = "172.16.1.0/24"; + pools = [ { pool = "172.16.1.50 - 172.16.1.254"; } ]; + option-data = [ + { + name = "routers"; + data = "172.16.1.1"; + } + ] ++ commonDhcpOptions; + }) + ({ + id = 10; + interface = "servers"; + subnet = "172.16.10.0/24"; + pools = [ { pool = "172.16.10.50 - 172.16.10.254"; } ]; + option-data = [ + { + name = "routers"; + data = "172.16.10.1"; + } + ] ++ commonDhcpOptions; + }) + ({ + id = 21; + interface = "management"; + subnet = "172.16.21.0/24"; + pools = [ { pool = "172.16.21.50 - 172.16.21.254"; } ]; + option-data = [ + { + name = "routers"; + data = "172.16.21.1"; + } + ] ++ commonDhcpOptions; + }) + ({ + id = 100; + interface = "iot"; + subnet = "172.16.100.0/24"; + pools = [ { pool = "172.16.100.50 - 172.16.100.254"; } ]; + option-data = [ + { + name = "routers"; + data = "172.16.100.1"; + } + ] ++ commonDhcpOptions; + }) + ({ + id = 110; + interface = "guest"; + subnet = "172.16.110.0/24"; + pools = [ { pool = "172.16.110.50 - 172.16.110.254"; } ]; + option-data = [ + { + name = "routers"; + data = "172.16.110.1"; + } + ] ++ commonDhcpOptions; + }) + ]; + }; }; avahi = { enable = true; diff --git a/hosts/lily/dns.nix b/hosts/lily/dns.nix index b754a51..e92df27 100644 --- a/hosts/lily/dns.nix +++ b/hosts/lily/dns.nix @@ -2,7 +2,7 @@ { services = { dnsmasq = { - enable = true; + enable = false; # try some other options first settings = { cache-size = 10000; # Specifies the size of the DNS query cache. It will store up to n cached DNS queries to improve response times for frequently accessed domains. server = [ From 92ded40fd7d2f9e9fe1286d1a625bd4500642c5d Mon Sep 17 00:00:00 2001 From: Ahwx Date: Tue, 3 Jun 2025 10:34:03 +0200 Subject: [PATCH 4/4] feat: define vnstat issues --- modules/services/vnstat.nix | 122 ++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 modules/services/vnstat.nix diff --git a/modules/services/vnstat.nix b/modules/services/vnstat.nix new file mode 100644 index 0000000..c8c66b0 --- /dev/null +++ b/modules/services/vnstat.nix @@ -0,0 +1,122 @@ +{ + lib, + config, + pkgs, + ... +}: + +let + vnstatUser = "vnstatd"; + vnstatImageDir = "/var/www/vnstat"; + vnstatDashboardFile = pkgs.writeText "dashboard.html" '' + + + + vnStat dashboard + + + + + + +
+ + + +
+ + + ''; + + serverName = "vnstat.abnv.me"; + serviceConfig = config.services."${serverName}"; + options = { + enable = lib.mkEnableOption "${serverName} service"; + }; +in +{ + options.services.${serverName} = options; + config = lib.mkIf serviceConfig.enable { + services.vnstat.enable = true; + + systemd = { + tmpfiles.rules = [ + "d ${vnstatImageDir} 1775 ${vnstatUser} ${vnstatUser}" + "L+ ${vnstatImageDir}/index.html - - - - ${vnstatDashboardFile}" + "Z ${vnstatImageDir} 755 ${vnstatUser} ${vnstatUser}" + ]; + + services."vnstati-web" = { + enable = true; + description = "service that generates images for vnstat monitoring"; + startAt = "*:0/5:00"; + restartIfChanged = true; + after = [ "vnstat.service" ]; + path = [ pkgs.vnstat ]; + serviceConfig = { + User = vnstatUser; + Group = vnstatUser; + WorkingDirectory = vnstatImageDir; + Type = "oneshot"; + AmbientCapabilities = [ ]; + CapabilityBoundingSet = [ ]; + KeyringMode = "private"; + LockPersonality = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "full"; + RemoveIPC = true; + RestrictAddressFamilies = [ ]; + RestrictNamespaces = true; + RestrictRealtime = true; + }; + script = '' + vnstati --style 1 -L -s -o vnstat-s.png + vnstati --style 1 -L --fivegraph 576 218 -o vnstat-5g.png + vnstati --style 1 -L -hg -o vnstat-hg.png + vnstati --style 1 -L -h 24 -o vnstat-h.png + vnstati --style 1 -L -d 30 -o vnstat-d.png + vnstati --style 1 -L -t 10 -o vnstat-t.png + vnstati --style 1 -L -m 12 -o vnstat-m.png + vnstati --style 1 -L -y 5 -o vnstat-y.png + ''; + }; + + timers."vnstat-image-gen".timerConfig = { + User = vnstatUser; + Group = vnstatUser; + }; + }; + + services.nginx.virtualHosts.${serverName} = { + root = vnstatImageDir; + extraConfig = '' + add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + if_modified_since off; + expires off; + etag off; + ''; + }; + }; +}