default.nix 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. { inputs, outputs, pkgs, lib, config, ... }:
  2. {
  3. imports = [
  4. inputs.nixos-facter-modules.nixosModules.facter
  5. { config.facter.reportPath = ./facter.json; }
  6. outputs.modules.global.nix-config
  7. inputs.sops-nix.nixosModules.sops
  8. inputs.impermanence.nixosModules.impermanence
  9. inputs.disko.nixosModules.disko
  10. ./disko.nix
  11. # ./services
  12. ];
  13. # System identification
  14. networking.hostName = "odin";
  15. networking.useDHCP = lib.mkDefault true;
  16. sops.defaultSopsFile = ./secrets.yaml;
  17. sops.secrets."thomas/password".neededForUsers = true;
  18. sops.secrets."nullmailer/remotes".owner = config.services.nullmailer.user;
  19. # Boot configuration
  20. boot = {
  21. # Use systemd-boot for UEFI systems
  22. loader = {
  23. systemd-boot.enable = true;
  24. efi.canTouchEfiVariables = true;
  25. grub.devices = [ config.disko.devices.disk.main.device ];
  26. timeout = 3;
  27. };
  28. # Kernel parameters for server workload
  29. kernelParams = [ "rootflags=compress=zstd:1,noatime" ];
  30. kernelModules = [ "nct6775" ];
  31. # Enable KSM for memory efficiency with containers
  32. kernel.sysctl = {
  33. "kernel.sysrq" = 1;
  34. "vm.swappiness" = 10;
  35. "net.core.default_qdisc" = "cake";
  36. };
  37. # Impermanence: reset root on boot
  38. initrd.postDeviceCommands = lib.mkAfter ''
  39. DEVICE=${config.disko.devices.disk.main.device}-part2
  40. mkdir -p /mnt
  41. mount -o subvol=/ $DEVICE /mnt
  42. # Create a directory for old roots if it doesn't exist
  43. mkdir -p /mnt/old-roots
  44. # Move current root to old-roots with timestamp if it exists
  45. if [[ -e /mnt/@root && ! -e /mnt/@root-blank ]]; then
  46. timestamp=$(date --date="@$(stat -c %Y /mnt/@root)" "+%Y-%m-%d_%H:%M:%S")
  47. mv /mnt/@root "/mnt/old-roots/@root-$timestamp"
  48. fi
  49. # Function to recursively delete subvolumes
  50. delete_subvolume_recursively() {
  51. for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
  52. delete_subvolume_recursively "/mnt/$i"
  53. done
  54. btrfs subvolume delete "$1"
  55. }
  56. # Delete old roots older than 30 days
  57. for i in $(find /mnt/old-roots/ -maxdepth 1 -mtime +30); do
  58. delete_subvolume_recursively "$i"
  59. done
  60. # Create fresh root from blank if needed or create blank if it doesn't exist
  61. if [[ -e /mnt/@root-blank ]]; then
  62. btrfs subvolume delete /mnt/@root || true
  63. btrfs subvolume snapshot /mnt/@root-blank /mnt/@root
  64. else
  65. btrfs subvolume create /mnt/@root-blank
  66. btrfs subvolume create /mnt/@root
  67. fi
  68. umount /mnt
  69. '';
  70. };
  71. hardware = {
  72. fancontrol = {
  73. enable = true;
  74. config = ''
  75. INTERVAL=10
  76. DEVPATH=hwmon1=devices/pci0000:00/0000:00:02.2/0000:04:00.0/nvme/nvme0 hwmon2=devices/platform/nct6775.656
  77. DEVNAME=hwmon1=nvme hwmon2=nct6798
  78. FCTEMPS=hwmon2/pwm7=hwmon1/temp1_input hwmon2/pwm2=hwmon1/temp1_input
  79. FCFANS=hwmon2/pwm7=hwmon2/fan7_input hwmon2/pwm2=hwmon2/fan2_input
  80. MINTEMP=hwmon2/pwm7=30 hwmon2/pwm2=30
  81. MAXTEMP=hwmon2/pwm7=60 hwmon2/pwm2=60
  82. MINSTART=hwmon2/pwm7=95 hwmon2/pwm2=150
  83. MINSTOP=hwmon2/pwm7=75 hwmon2/pwm2=0
  84. '';
  85. };
  86. };
  87. # Services configuration
  88. services = {
  89. # Drive power management and fan control
  90. hddfancontrol = {
  91. enable = true;
  92. settings = {
  93. harddrives =
  94. let
  95. devices = config.disko.devices.disk;
  96. in
  97. {
  98. disks = [
  99. devices.storage1.device
  100. devices.storage2.device
  101. devices.storage3.device
  102. ];
  103. pwmPaths = [
  104. "/sys/class/hwmon/hwmon2/pwm1:20:0"
  105. "/sys/class/hwmon/hwmon2/pwm4:80:60"
  106. ];
  107. logVerbosity = "DEBUG";
  108. extraArgs = [
  109. "--min-fan-speed-prct=0"
  110. ];
  111. };
  112. };
  113. };
  114. openssh = {
  115. enable = true;
  116. openFirewall = true;
  117. settings = {
  118. PasswordAuthentication = false;
  119. PermitRootLogin = "no";
  120. X11Forwarding = false;
  121. };
  122. };
  123. # System monitoring
  124. smartd = {
  125. enable = true;
  126. autodetect = true;
  127. notifications.test = true;
  128. notifications.mail.enable = true;
  129. notifications.mail.sender = "[email protected]";
  130. notifications.mail.recipient = "I <[email protected]>";
  131. };
  132. nullmailer = {
  133. enable = true;
  134. setSendmail = true;
  135. remotesFile = config.sops.secrets."nullmailer/remotes".path;
  136. config = {
  137. me = "odin.t5.st";
  138. defaulthost = "odin.t5.st";
  139. defaultdomain = "odin.t5.st";
  140. allmailfrom = "[email protected]";
  141. adminaddr = "[email protected]";
  142. };
  143. };
  144. # Time synchronization
  145. timesyncd.enable = true;
  146. # Btrfs maintenance
  147. btrfs.autoScrub = {
  148. enable = true;
  149. interval = "monthly";
  150. fileSystems = [ "/" ];
  151. };
  152. # Drive spin-down management
  153. # hdparm.devices = [
  154. # {
  155. # device = "/dev/disk/by-id/ata-ST8000VN002-2ZM188_WPV023WG";
  156. # spindownTime = 120; # 10 minutes
  157. # apmLevel = 127;
  158. # }
  159. # {
  160. # device = "/dev/disk/by-id/ata-ST8000VN002-2ZM188_WPV07RMA";
  161. # spindownTime = 120;
  162. # apmLevel = 127;
  163. # }
  164. # {
  165. # device = "/dev/disk/by-id/ata-ST8000VN002-2ZM188_WPV020CG";
  166. # spindownTime = 120;
  167. # apmLevel = 127;
  168. # }
  169. # ];
  170. };
  171. # # Container runtime
  172. # virtualisation = {
  173. # docker = {
  174. # enable = true;
  175. # storageDriver = "btrfs";
  176. # autoPrune = {
  177. # enable = true;
  178. # dates = "weekly";
  179. # flags = [ "--all" "--force" "--volumes" ];
  180. # };
  181. # };
  182. # };
  183. # System packages
  184. environment.systemPackages = with pkgs; [
  185. # System utilities
  186. htop
  187. btop
  188. iotop
  189. lsof
  190. pciutils
  191. usbutils
  192. # Network tools
  193. curl
  194. wget
  195. rsync
  196. # File system tools
  197. btrfs-progs
  198. xfsprogs
  199. smartmontools
  200. hdparm
  201. # # Container tools
  202. # docker-compose
  203. # Storage management
  204. snapraid
  205. mergerfs
  206. # Monitoring
  207. lm_sensors
  208. nvme-cli
  209. ];
  210. # User configuration
  211. users = {
  212. mutableUsers = false; # Declarative user management
  213. users = {
  214. # Main user account
  215. thomas = {
  216. isNormalUser = true;
  217. extraGroups = [ "wheel" "users" ];
  218. hashedPasswordFile = config.sops.secrets."thomas/password".path;
  219. openssh.authorizedKeys.keys = [
  220. "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC5o7LT5wPYWgI8Mvr6RKOv+BcsbQgU7PCw2hheVu17alwF1uFUsAYV5BVQu+uv9uEm/UDsCNhfM6TwI0A1prdmtBz4pKiwXbj7fcdp6DcVOgTsPfawbXEpivtJvlhEatyTsR26MjHKnqpT0BxPvj6Ug6pvRkCYW5d2bWXiY9murmAX6Q5kSyNunkB8PdRTH+S47f7eOdCJY63VBOkkiG8M7XyPwFCDTYiHhbMZcejIdY9mB6kYnMQVRHDznQWiQxrcaE1fD/TY3db9GDcOVoo2aDBOZX7WT2+me67sU8dEK9+nSyhWDzBbEs8knu87ZlKPFwhl4slenRniKhbf22OpicXArtEcjEj0GyDJH5e+ZCIQ4eSQanA7TxnKFlDuaf+Qqx55UT+ya4vJJeik7nkzbRHaE9IoWhhiOaOnaN6kHIxuxB6z7EL3Gk7f78+I/qBaj5df6fgnXM3JBXKa5bRH2wqoSetJAo6EGpEgmU2huB1ktiGlO7BlF5XwSw6cb/KT7NSIXhncgLkCzsDVXxecVQv1FnPISBcp3+ti01ADVf2trgpPDbNTWV40Rgiefie0o2fc6KWAFfum1j5N3WWU+XVVmRjDmKKHiEJBLNKDAe0rQf+tryPW4c5GIN7aFoB+8dYFAuUyLd7Fu3vhZdmcckN5ryHunEc0dKPIiuoVZw=="
  221. ];
  222. };
  223. };
  224. };
  225. # Persistent directories for impermanence
  226. fileSystems."/persist".neededForBoot = true;
  227. environment.persistence."/persist" = {
  228. hideMounts = true;
  229. directories = [
  230. "/etc/nixos"
  231. "/etc/ssh"
  232. "/var/lib/nixos"
  233. "/var/lib/systemd"
  234. "/srv"
  235. ];
  236. files = [
  237. "/etc/machine-id"
  238. ];
  239. users.thomas = {
  240. directories = [
  241. ".ssh"
  242. ".config"
  243. ];
  244. };
  245. };
  246. # System state version
  247. system.stateVersion = "25.05";
  248. }