From 1a4d6ecd2ac2bfcddacd6c04a5c12fb08808a912 Mon Sep 17 00:00:00 2001 From: truxnell <19149206+truxnell@users.noreply.github.com> Date: Mon, 25 Mar 2024 23:37:21 +1100 Subject: [PATCH] hax --- flake.nix | 14 ++++- nixos/hosts/citadel/default.nix | 2 + .../common/optional/cloudflare-dyndns.nix | 28 ---------- nixos/hosts/common/optional/monitoring.nix | 30 ----------- .../hosts/common/optional/reboot-required.nix | 36 ------------- nixos/hosts/dns01/default.nix | 7 +-- nixos/modules/nixos/default.nix | 3 +- .../cloudflare-dyndns.sops.yaml | 0 .../services/cloudflare-dyndns/default.nix | 39 ++++++++++++++ nixos/modules/nixos/services/default.nix | 7 +++ nixos/modules/nixos/services/monitoring.nix | 46 ++++++++++++++++ .../nixos/services/reboot-required-check.nix | 54 +++++++++++++++++++ nixos/modules/nixos/template.nix | 20 +++++++ nixos/profiles/role-server.nix | 24 +++++++++ 14 files changed, 209 insertions(+), 101 deletions(-) delete mode 100644 nixos/hosts/common/optional/cloudflare-dyndns.nix delete mode 100644 nixos/hosts/common/optional/monitoring.nix delete mode 100644 nixos/hosts/common/optional/reboot-required.nix rename nixos/{hosts/common/optional => modules/nixos/services/cloudflare-dyndns}/cloudflare-dyndns.sops.yaml (100%) create mode 100644 nixos/modules/nixos/services/cloudflare-dyndns/default.nix create mode 100644 nixos/modules/nixos/services/default.nix create mode 100644 nixos/modules/nixos/services/monitoring.nix create mode 100644 nixos/modules/nixos/services/reboot-required-check.nix create mode 100644 nixos/modules/nixos/template.nix create mode 100644 nixos/profiles/role-server.nix diff --git a/flake.nix b/flake.nix index 94c69f3..2c0e3e2 100644 --- a/flake.nix +++ b/flake.nix @@ -87,6 +87,7 @@ { "rickenbacker" = mkNixosConfig { + # NixOS laptop (dualboot windows, dunno why i kept it) hostname = "rickenbacker"; system = "x86_64-linux"; hardwareModules = [ @@ -100,6 +101,8 @@ }; "citadel" = mkNixosConfig { + # Gaming PC (dualboot windows) + hostname = "citadel"; system = "x86_64-linux"; hardwareModules = [ @@ -112,8 +115,17 @@ }; "dns01" = mkNixosConfig { + # Rpi for DNS and misc services + hostname = "dns01"; - system = "x86_64-linux"; + system = "aarch64-linux"; + hardwareModules = [ + ./nixos/profiles/hw-rpi4.nix + inputs.nixos-hardware.nixosModules.raspberry-pi-4 + ]; + profileModules = [ + ./nixos/profiles/role-server.nix + ]; }; diff --git a/nixos/hosts/citadel/default.nix b/nixos/hosts/citadel/default.nix index 8b7687a..dedbcfb 100644 --- a/nixos/hosts/citadel/default.nix +++ b/nixos/hosts/citadel/default.nix @@ -14,6 +14,8 @@ ../common/optional/firefox.nix ]; + + config = { mySystem = { services.openssh.enable = true; diff --git a/nixos/hosts/common/optional/cloudflare-dyndns.nix b/nixos/hosts/common/optional/cloudflare-dyndns.nix deleted file mode 100644 index f93b2ff..0000000 --- a/nixos/hosts/common/optional/cloudflare-dyndns.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ config -, lib -, ... -}: { - # Current nixpkgs cf-ddns only supports using a env file for the apitoken - # but not for domains, which makes them hard to find. - # To circumvent this, I put both in the 'apiTokenFile' var - # so my secret is: - - # apiTokenFile: |- - # CLOUDFLARE_API_TOKEN=derp - # CLOUDFLARE_DOMAINS=derp.herp.xyz derp1.herp.xyz - - # init secret - config.sops.secrets."system/networking/cloudflare-dyndns/apiTokenFile".sopsFile = ./cloudflare-dyndns.sops.yaml; - - # Restart when secret changes - config.sops.secrets."system/networking/cloudflare-dyndns/apiTokenFile".restartUnits = [ "cloudflare-dyndns" ]; - - # Cloudflare dynamic dns to keep my DNS records pointed at home - config.services.cloudflare-dyndns = { - enable = true; - ipv6 = false; - proxied = true; - apiTokenFile = config.sops.secrets."system/networking/cloudflare-dyndns/apiTokenFile".path; - domains = [ ]; - }; -} diff --git a/nixos/hosts/common/optional/monitoring.nix b/nixos/hosts/common/optional/monitoring.nix deleted file mode 100644 index 4dd7631..0000000 --- a/nixos/hosts/common/optional/monitoring.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ config -, pkgs -, lib -, ... -}: { - services.prometheus.exporters = { - node = { - enable = true; - enabledCollectors = [ - "diskstats" - "filesystem" - "loadavg" - "meminfo" - "netdev" - "stat" - "time" - "uname" - "systemd" - ]; - }; - smartctl = { - enable = true; - }; - }; - - networking.firewall.allowedTCPPorts = [ - config.services.prometheus.exporters.node.port - config.services.prometheus.exporters.smartctl.port - ]; -} diff --git a/nixos/hosts/common/optional/reboot-required.nix b/nixos/hosts/common/optional/reboot-required.nix deleted file mode 100644 index 607c86c..0000000 --- a/nixos/hosts/common/optional/reboot-required.nix +++ /dev/null @@ -1,36 +0,0 @@ -{ config -, pkgs -, ... -}: { - systemd.timers."reboot-required-check" = { - wantedBy = [ "timers.target" ]; - timerConfig = { - # start at boot - OnBootSec = "0m"; - # check every hour - OnUnitActiveSec = "1h"; - Unit = "reboot-required-check.service"; - }; - }; - - systemd.services."reboot-required-check" = { - script = '' - #!/usr/bin/env bash - - # compare current system with booted sysetm to determine if a reboot is required - if [[ "$(readlink /run/booted-system/{initrd,kernel,kernel-modules})" == "$(readlink /run/current-system/{initrd,kernel,kernel-modules})" ]]; then - # check if the '/var/run/reboot-required' file exists and if it does, remove it - if [[ -f /var/run/reboot-required ]]; then - rm /var/run/reboot-required || { echo "Failed to remove /var/run/reboot-required"; exit 1; } - fi - else - echo "reboot required" - touch /var/run/reboot-required || { echo "Failed to create /var/run/reboot-required"; exit 1; } - fi - ''; - serviceConfig = { - Type = "oneshot"; - User = "root"; - }; - }; -} diff --git a/nixos/hosts/dns01/default.nix b/nixos/hosts/dns01/default.nix index 9298d3e..e7cda43 100644 --- a/nixos/hosts/dns01/default.nix +++ b/nixos/hosts/dns01/default.nix @@ -3,18 +3,15 @@ # https://search.nixos.org/options and in the NixOS manual (`nixos-help`). { config , lib -, pkgs +, pkgs , ... }: { imports = [ - ../common/optional/monitoring.nix - ../common/optional/reboot-required.nix ../common/optional/dnscrypt-proxy2.nix - ../common/optional/cloudflare-dyndns.nix ../common/optional/maddy.nix ]; - + mySystem.services.cfddns.enable = true; networking.hostName = "dns01"; # Define your hostname. networking.useDHCP = lib.mkDefault true; diff --git a/nixos/modules/nixos/default.nix b/nixos/modules/nixos/default.nix index 916039f..e1f6e80 100644 --- a/nixos/modules/nixos/default.nix +++ b/nixos/modules/nixos/default.nix @@ -1,7 +1,8 @@ { imports = [ ./system - ./programs + ./programs + ./services ]; } diff --git a/nixos/hosts/common/optional/cloudflare-dyndns.sops.yaml b/nixos/modules/nixos/services/cloudflare-dyndns/cloudflare-dyndns.sops.yaml similarity index 100% rename from nixos/hosts/common/optional/cloudflare-dyndns.sops.yaml rename to nixos/modules/nixos/services/cloudflare-dyndns/cloudflare-dyndns.sops.yaml diff --git a/nixos/modules/nixos/services/cloudflare-dyndns/default.nix b/nixos/modules/nixos/services/cloudflare-dyndns/default.nix new file mode 100644 index 0000000..40fe5ea --- /dev/null +++ b/nixos/modules/nixos/services/cloudflare-dyndns/default.nix @@ -0,0 +1,39 @@ +{ lib +, config +, ... +}: + +with lib; +let + cfg = config.mySystem.services.cfDdns; +in +{ + options.mySystem.services.cfDdns.enable = mkEnableOption "Cloudflare ddns"; + + config = mkIf cfg.enable { + # Current nixpkgs cf-ddns only supports using a env file for the apitoken + # but not for domains, which makes them hard to find. + # To circumvent this, I put both in the 'apiTokenFile' var + # so my secret is: + + # apiTokenFile: |- + # CLOUDFLARE_API_TOKEN=derp + # CLOUDFLARE_DOMAINS=derp.herp.xyz derp1.herp.xyz + + # TODO add notifications on IP change + # init secret + config.sops.secrets."system/networking/cloudflare-dyndns/apiTokenFile".sopsFile = ./cloudflare-dyndns.sops.yaml; + + # Restart when secret changes + config.sops.secrets."system/networking/cloudflare-dyndns/apiTokenFile".restartUnits = [ "cloudflare-dyndns" ]; + + # Cloudflare dynamic dns to keep my DNS records pointed at home + config.services.cloudflare-dyndns = { + enable = true; + ipv6 = false; + proxied = true; + apiTokenFile = config.sops.secrets."system/networking/cloudflare-dyndns/apiTokenFile".path; + domains = [ ]; + }; + }; +} diff --git a/nixos/modules/nixos/services/default.nix b/nixos/modules/nixos/services/default.nix new file mode 100644 index 0000000..f9ea679 --- /dev/null +++ b/nixos/modules/nixos/services/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./monitoring.nix + ./reboot-required-check.nix + ./cloudflare-dyndns + ]; +} diff --git a/nixos/modules/nixos/services/monitoring.nix b/nixos/modules/nixos/services/monitoring.nix new file mode 100644 index 0000000..df2086b --- /dev/null +++ b/nixos/modules/nixos/services/monitoring.nix @@ -0,0 +1,46 @@ +{ lib +, config +, self +, ... +}: +with lib; +let + cfg = config.mySystem.services.promMonitoring; +in +{ + options.mySystem.services.promMonitoring.enable = mkEnableOption "Prometheus Monitoring"; + + config = mkIf cfg.enable { + + services.prometheus.exporters = { + node = { + enable = true; + enabledCollectors = [ + "diskstats" + "filesystem" + "loadavg" + "meminfo" + "netdev" + "stat" + "time" + "uname" + "systemd" + ]; + }; + smartctl = { + enable = true; + }; + + + }; + + # ensure ports are open + networking.firewall.allowedTCPPorts = mkIf cfg.enable [ + config.services.prometheus.exporters.node.port + config.services.prometheus.exporters.smartctl.port + ]; + + }; + + +} diff --git a/nixos/modules/nixos/services/reboot-required-check.nix b/nixos/modules/nixos/services/reboot-required-check.nix new file mode 100644 index 0000000..7ceacfe --- /dev/null +++ b/nixos/modules/nixos/services/reboot-required-check.nix @@ -0,0 +1,54 @@ +{ lib +, config +, self +, ... +}: +with lib; +let + cfg = config.mySystem.services.rebootRequiredCheck; +in +{ + options.mySystem.services.rebootRequiredCheck.enable = mkEnableOption "Reboot required check"; + + config = mkIf cfg.enable { + + # Enable timer + systemd.timers."reboot-required-check" = { + wantedBy = [ "timers.target" ]; + timerConfig = { + # start at boot + OnBootSec = "0m"; + # check every hour + OnUnitActiveSec = "1h"; + Unit = "reboot-required-check.service"; + }; + }; + + # Below script will check if initrd, kernel, kernel-modules that were booted match the current system + # i.e. if a nixos-rebuild switch has upgraded anything + systemd.services."reboot-required-check" = { + script = '' + #!/usr/bin/env bash + + # compare current system with booted sysetm to determine if a reboot is required + if [[ "$(readlink /run/booted-system/{initrd,kernel,kernel-modules})" == "$(readlink /run/current-system/{initrd,kernel,kernel-modules})" ]]; then + # check if the '/var/run/reboot-required' file exists and if it does, remove it + if [[ -f /var/run/reboot-required ]]; then + rm /var/run/reboot-required || { echo "Failed to remove /var/run/reboot-required"; exit 1; } + fi + else + echo "reboot required" + touch /var/run/reboot-required || { echo "Failed to create /var/run/reboot-required"; exit 1; } + fi + ''; + serviceConfig = { + Type = "oneshot"; + User = "root"; + }; + }; + + + }; + + +} diff --git a/nixos/modules/nixos/template.nix b/nixos/modules/nixos/template.nix new file mode 100644 index 0000000..d901e8a --- /dev/null +++ b/nixos/modules/nixos/template.nix @@ -0,0 +1,20 @@ +{ lib +, config +, ... +}: + +with lib; +let + cfg = config.mySystem.xx.yy; +in +{ + options.mySystem.xx.yy.enable = mkEnableOption ""; + + config = mkIf cfg.enable { + + # CONFIG HERE + + }; + + +} diff --git a/nixos/profiles/role-server.nix b/nixos/profiles/role-server.nix new file mode 100644 index 0000000..22d6361 --- /dev/null +++ b/nixos/profiles/role-server.nix @@ -0,0 +1,24 @@ +{ config, lib, pkgs, imports, boot, ... }: +# Role for headless servers +# covers raspi's, sbc, NUC etc, anything +# that is headless and minimal for running services + +with lib; +{ + config = { + + # Enable monitoring for remote scraiping + mySystem.services.promMonitoring.enable = true; + mySystem.services.rebootRequiredCheck.enable = true; + + nix.settings = { + # TODO factor out into mySystem + # Avoid disk full issues + max-free = lib.mkDefault (1000 * 1000 * 1000); + min-free = lib.mkDefault (128 * 1000 * 1000); + }; + }; + + + +}