This commit is contained in:
truxnell 2024-03-25 23:37:21 +11:00
parent e46eba32a6
commit 1a4d6ecd2a
14 changed files with 209 additions and 101 deletions

View file

@ -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
];
};

View file

@ -14,6 +14,8 @@
../common/optional/firefox.nix
];
config = {
mySystem = {
services.openssh.enable = true;

View file

@ -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 = [ ];
};
}

View file

@ -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
];
}

View file

@ -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";
};
};
}

View file

@ -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;

View file

@ -1,7 +1,8 @@
{
imports = [
./system
./programs
./programs
./services
];
}

View file

@ -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 = [ ];
};
};
}

View file

@ -0,0 +1,7 @@
{
imports = [
./monitoring.nix
./reboot-required-check.nix
./cloudflare-dyndns
];
}

View file

@ -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
];
};
}

View file

@ -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";
};
};
};
}

View file

@ -0,0 +1,20 @@
{ lib
, config
, ...
}:
with lib;
let
cfg = config.mySystem.xx.yy;
in
{
options.mySystem.xx.yy.enable = mkEnableOption "<INSERT DESCRIPTION>";
config = mkIf cfg.enable {
# CONFIG HERE
};
}

View file

@ -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);
};
};
}