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 = [ diff --git a/modules/core/printing.nix b/modules/core/printing.nix index 7622bee..0bf8a60 100644 --- a/modules/core/printing.nix +++ b/modules/core/printing.nix @@ -1,7 +1,7 @@ { pkgs, ... }: { services.avahi = { - enable = true; + enable = false; nssmdns4 = true; openFirewall = true; }; 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) diff --git a/modules/core/sshd.nix b/modules/core/sshd.nix index 6e1a9e8..13fba58 100644 --- a/modules/core/sshd.nix +++ b/modules/core/sshd.nix @@ -2,7 +2,7 @@ { services.openssh = { enable = true; - ports = [ 22 ]; + ports = [ 9123 ]; settings = { PasswordAuthentication = lib.mkDefault false; AllowUsers = null; diff --git a/modules/home/packages.nix b/modules/home/packages.nix index 73b9fa8..0a80335 100644 --- a/modules/home/packages.nix +++ b/modules/home/packages.nix @@ -66,6 +66,7 @@ librewolf # main ungoogled-chromium # for things that don't work with librewolf nsxiv + imv libreoffice xfce.thunar spotify diff --git a/modules/home/waybar/scripts.nix b/modules/home/waybar/scripts.nix index fff7b18..c24b8d3 100644 --- a/modules/home/waybar/scripts.nix +++ b/modules/home/waybar/scripts.nix @@ -155,27 +155,24 @@ "/home/${username}/.local/bin/waybar-music" = { executable = true; text = '' - #!/usr/bin/env bash + #!/usr/bin/env sh - class=$(playerctl metadata --player=ncspot --format '{{lc(status)}}') + META="{{ trunc(artist,17) }} - {{ trunc(title,17) }}" + PLAYERS="spotify ncspot mpv mpd" - if [[ $class == "playing" ]]; then - info=$(playerctl metadata --player=ncspot --format '{{artist}} - {{title}}') - if [[ $\{#info} > 40 ]]; then - info=$(echo $info | cut -c1-40)"..." - fi - text="$info" - elif [[ $class == "paused" ]]; then - info=$(playerctl metadata --player=ncspot --format '{{artist}} - {{title}}') - if [[ $\{#info} > 40 ]]; then - info=$(echo $info | cut -c1-40)"..." - fi - text=" $info" - elif [[ $class == "stopped" ]]; then - text="" - fi + for PLAYER in $PLAYERS; do + # if the player is not playing, continue to the next player, until we find one that is playing + [ "$(playerctl --player=$PLAYER status 2>/dev/null)" != "Playing" ] && continue + text=$(playerctl metadata --player $PLAYER --format "$META") + echo -e "{\"text\":\""$text"\", \"class\":\"Playing\"}" + exit 0 + done - echo -e "{\"text\":\""$text"\", \"class\":\""$class"\"}" + ICON="❚❚ " + PAUSERS="spotify ncspot mpd" + for PAUSER in $PAUSERS; do + [ "$(playerctl --player=$PAUSER status 2>/dev/null)" == "Paused" ] || [ "$(playerctl --player=$PAUSER status 2>/dev/null)" == "Stopped" ] && text="$ICON"$(playerctl metadata --player $PAUSER --format "$META") && echo -e "{\"text\":\""$text"\", \"class\":\""paused"\"}" && exit 0 + done ''; }; "/home/${username}/.local/bin/waybar-devices" = { diff --git a/modules/home/zsh.nix b/modules/home/zsh.nix index b1457dc..82e98d8 100644 --- a/modules/home/zsh.nix +++ b/modules/home/zsh.nix @@ -111,12 +111,12 @@ export export PATH="''${PATH}:''${HOME}/.local/bin/:''${HOME}/.cargo/bin/:''${HOME}/.fzf/bin/" - if [[ $(which sxiv&>/dev/null && echo 1) == "1" ]]; then - alias imv="sxiv" - elif [[ $(which nsxiv&>/dev/null && echo 1) == "1" ]]; then - alias imv="nsxiv" - alias sxiv="nsxiv" - fi + # if [[ $(which sxiv&>/dev/null && echo 1) == "1" ]]; then + # alias imv="sxiv" + # elif [[ $(which nsxiv&>/dev/null && echo 1) == "1" ]]; then + # alias imv="nsxiv" + # alias sxiv="nsxiv" + # fi ''; zsh-abbr = { @@ -173,6 +173,7 @@ # nvim = "nix run /home/liv/Development/nixvim --"; vim = "nvim"; doas = "sudo"; + sxiv = "nsxiv"; # NixOS ns = "nix-shell --run zsh"; diff --git a/modules/services/monitoring.nix b/modules/services/monitoring.nix index a22d5f9..43b5319 100644 --- a/modules/services/monitoring.nix +++ b/modules/services/monitoring.nix @@ -23,9 +23,9 @@ ]; }; }; - networking.firewall = { - allowedTCPPorts = [ - 9001 - ]; - }; + # networking.firewall = { + # allowedTCPPorts = [ + # 9001 + # ]; + # }; } diff --git a/modules/services/mumble.nix b/modules/services/mumble.nix index 14c9487..eaa0836 100644 --- a/modules/services/mumble.nix +++ b/modules/services/mumble.nix @@ -2,6 +2,6 @@ { services.murmur = { enable = true; - openFirewall = true; + openFirewall = false; }; } diff --git a/modules/services/nginx.nix b/modules/services/nginx.nix index 952473a..6e6f98f 100644 --- a/modules/services/nginx.nix +++ b/modules/services/nginx.nix @@ -37,41 +37,35 @@ recommendedProxySettings = true; clientMaxBodySize = lib.mkDefault "10G"; - defaultListen = - let - listen = [ - { - addr = "[::]"; - port = 80; - extraParameters = [ "proxy_protocol" ]; - } - { - addr = "[::]"; - port = 443; - ssl = true; - extraParameters = [ "proxy_protocol" ]; - } - ]; - in - map (x: (x // { addr = "0.0.0.0"; })) listen ++ listen; + #defaultListen = + # let + # listen = [ + # { + # addr = "[::]"; + # port = 80; + # extraParameters = [ "proxy_protocol" ]; + # } + # { + # addr = "[::]"; + # port = 443; + # ssl = true; + # extraParameters = [ "proxy_protocol" ]; + # } + # ]; + # in + # map (x: (x // { addr = "0.0.0.0"; })) listen ++ listen; # Hardened TLS and HSTS preloading appendHttpConfig = '' # Proxying # real_ip_header proxy_protocol; - server { - listen 80 proxy_protocol; - listen 443 ssl proxy_protocol; - # set_real_ip_from 10.7.0.0/24; - } - ssl_certificate /var/lib/acme/quack.social/cert.pem; ssl_certificate_key /var/lib/acme/quack.social/key.pem; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $proxy_protocol_addr; - proxy_set_header X-Forwarded-For $proxy_protocol_addr; + # proxy_set_header Host $host; + # proxy_set_header X-Real-IP $proxy_protocol_addr; + # proxy_set_header X-Forwarded-For $proxy_protocol_addr; # Add HSTS header with preloading to HTTPS requests. # Do not add HSTS header to HTTP requests. @@ -98,19 +92,6 @@ add_header pronouns "any but neopronouns"; add_header locale "[en_US, nl_NL]"; ''; - appendConfig = '' - # https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/ - # set_real_ip_from 213.210.34.27; - - # real_ip_header proxy_protocol; - - # proxy_set_header Host $host; - # proxy_set_header X-Real-IP $proxy_protocol_addr; - # proxy_set_header X-Forwarded-For $proxy_protocol_addr; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header X-Forwarded-Host $host; - # proxy_set_header X-Forwarded-Server $host; - ''; }; networking.firewall = { allowedTCPPorts = [ 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 = { 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; + ''; + }; + }; +} diff --git a/roles/creative.nix b/roles/creative.nix index 9546198..37a9200 100644 --- a/roles/creative.nix +++ b/roles/creative.nix @@ -1,8 +1,16 @@ -{ lib, pkgs, config, username, home-manager, ... }: +{ + lib, + pkgs, + config, + username, + home-manager, + ... +}: with lib; let cfg = config.liv.creative; -in { +in +{ options.liv.creative = { enable = mkEnableOption "Enable creative workflow"; }; @@ -17,6 +25,7 @@ in { obs-studio kdePackages.kdenlive orca-slicer + freecad ]; }; };