From 84518224e2ec1df0b1a1dbcff4bd68fdde61d81c Mon Sep 17 00:00:00 2001 From: surtur Date: Sat, 2 Dec 2023 19:15:45 +0100 Subject: [PATCH] nix: add monoceros system configuration --- nix/.sops.yaml | 7 + nix/flake.nix | 10 ++ nix/hosts/monoceros/configuration.nix | 161 ++++++++++++++++++ nix/hosts/monoceros/disko-config.nix | 119 +++++++++++++ .../monoceros/hardware-configuration.nix | 26 +++ nix/hosts/monoceros/secrets.yaml | 41 +++++ 6 files changed, 364 insertions(+) create mode 100644 nix/hosts/monoceros/configuration.nix create mode 100644 nix/hosts/monoceros/disko-config.nix create mode 100644 nix/hosts/monoceros/hardware-configuration.nix create mode 100644 nix/hosts/monoceros/secrets.yaml diff --git a/nix/.sops.yaml b/nix/.sops.yaml index 0f50faf..6553f0c 100644 --- a/nix/.sops.yaml +++ b/nix/.sops.yaml @@ -3,6 +3,7 @@ keys: - &it age1nt7a9nsgwsf7c9x8yx3qu8w24svz02hpfuwtmk8dazw6j6lh33hsgv8erk - &loki age136558pknq6glx2xftavt7mm3p4jcpu54kej2kxryeu78m5r59e0qvawl5l - &nixpi age17qvnfr98kxn0yuw6zjsmrl5nqlganzakn77pchnf5cr3an4gdp5s8dn26v + - &monoceros age1yzlnedt49kd429jssj73v3yz5z7deyg82dq0gq86lp6dft4edg7qrcjs5v - &backup age15959gprm59azjflvpj97yt0lj6dj4d2yv0nd6u9jp32lzwp3de7qzhf85y - &surtur age1drh8uq93mhzhj3rz9s2gcnht04wc5hukzutlu4l5qc55hxaznd5s9xs2f6 creation_rules: @@ -16,6 +17,11 @@ creation_rules: - age: - *backup - *nixpi + - path_regex: hosts/monoceros/*.* + key_groups: + - age: + - *backup + - *monoceros - path_regex: secrets/*.* key_groups: - age: @@ -23,4 +29,5 @@ creation_rules: - *surtur - *loki - *nixpi + - *monoceros ... diff --git a/nix/flake.nix b/nix/flake.nix index ff92504..5ee9a45 100644 --- a/nix/flake.nix +++ b/nix/flake.nix @@ -58,6 +58,16 @@ ]; }; + nixosConfigurations.monoceros = nixpkgs.lib.nixosSystem { + # inherit pkgs system; + modules = [ + disko.nixosModules.disko + sops-nix.nixosModules.sops + + ./hosts/monoceros/configuration.nix + ]; + }; + nixosConfigurations.nixpi = nixpkgs.lib.nixosSystem { system = "aarch64-linux"; # pkgs = nixpkgs.legacyPackages.${system}; diff --git a/nix/hosts/monoceros/configuration.nix b/nix/hosts/monoceros/configuration.nix new file mode 100644 index 0000000..5cd0f1a --- /dev/null +++ b/nix/hosts/monoceros/configuration.nix @@ -0,0 +1,161 @@ +{ + config, + lib, + pkgs, + ... +}: { + imports = [ + # Include the results of the hardware scan. + ./hardware-configuration.nix + ./disko-config.nix + + # ./modules/caddy.nix + ../../modules/base.nix + ../../modules/dnscrypt.nix + ]; + + sops = { + defaultSopsFile = ./secrets.yaml; + age = { + # keyFile = "/root/.age/monoceros"; + sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"]; + generateKey = false; + }; + + secrets.rootPassphrase.owner = "root"; + }; + + # nixpkgs.currentSystem = "x86_64-linux"; + nix.settings.trusted-users = ["@wheel" "root"]; + + # forbid hibernation due to zfs-on-root. + boot.kernelParams = ["nohibernate"]; + + # Use the systemd-boot EFI boot loader. + boot.loader.systemd-boot.enable = true; + boot.loader.systemd-boot.configurationLimit = 42; + boot.loader.systemd-boot.editor = false; + boot.loader.systemd-boot.netbootxyz.enable = false; + boot.loader.efi.canTouchEfiVariables = true; + + boot.supportedFilesystems = ["zfs"]; + boot.zfs.forceImportRoot = true; + + boot.initrd.secrets = { + # "/root/initrd-ssh-key" = "/root/initrd-ssh-key"; + "/root/initrd-ssh-host-ed25519_key" = "/root/initrd-ssh-host-ed25519_key"; + }; + boot.initrd.kernelModules = ["zfs" "e1000e"]; + boot.initrd.network = { + # This will use udhcp to get an ip address. + # Make sure you have added the kernel module for your network driver to `boot.initrd.availableKernelModules`, + # so your initrd can load it! + # Static ip addresses might be configured using the ip argument in kernel command line: + # https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt + enable = true; + ssh = { + enable = true; + # To prevent ssh clients from freaking out because a different host key is used, + # a different port for ssh is useful (assuming the same host has also a regular sshd running) + postCommands = '' + echo "zfs load-key zroot/nixos && killall zfs" >> /root/.profile + ''; + + port = 2222; + # hostKeys paths must be unquoted strings, otherwise you'll run into issues with boot.initrd.secrets + # the keys are copied to initrd from the path specified; multiple keys can be set + # you can generate any number of host keys using + # `ssh-keygen -t ed25519 -N "" -f /path/to/ssh_host_ed25519_key` + hostKeys = [/root/initrd-ssh_host_ed25519_key]; + ignoreEmptyHostKeys = true; + authorizedKeys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIODmLwtQj6ylgdTPo1/H5jW7jsLzwaCTGdIsTQAdc896"]; + }; + }; + # boot.initrd.systemd.contents + + boot.binfmt = { + emulatedSystems = [ + "wasm32-wasi" + "aarch64-linux" + ]; + }; + + networking = { + # hostId = pkgs.lib.mkForce "00000000"; + hostId = "deadb33f"; + hostName = "monoceros"; + + usePredictableInterfaceNames = false; + interfaces.eth0 = { + ipv6.addresses = [ { + address = "2a02:c206:2153:0314:0000:0000:0000:0001"; + prefixLength = 64; + }]; + ipv4.addresses = [ { + address = "158.220.120.164"; + prefixLength = 20; + } ]; + }; + + nftables.enable = true; + + networkmanager.enable = false; + + firewall = { + allowPing = true; + }; + + # Configure network proxy if necessary + # networking.proxy.default = "http://user:password@proxy:port/"; + # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; + }; + + users.users.root = { + shell = pkgs.zsh; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBtG6NCgdLHX4ztpfvYNRaslKWZcl6KdTc1DehVH4kAL" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJaXmXbNegxiXLldy/sMYX8kCsghY1SGqn2FZ5Jk7QJw" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBZbkw9vjCfbMPEH7ZAFq20XE9oIJ4w/HRIMu2ivNcej caelum's nixbldr key" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGKzPC0ZK4zrOEBUdu1KNThEleVb1T5Pl3+n3KB3o0b8 surtur's nixbldr key" + ]; + hashedPasswordFile = config.sops.secrets.rootPassphrase.path; + subUidRanges = [ + { + count = 65536; + startUid = 65536 * 28; # 1835008, docker + } + ]; + }; + + services = { + avahi.enable = lib.mkForce false; + + atd.enable = true; + + power-profiles-daemon.enable = false; + #tlp.enable = + # lib.mkDefault ((lib.versionOlder (lib.versions.majorMinor lib.version) "23.11") + # || !config.services.power-profiles-daemon.enable); + auto-cpufreq.enable = false; + + # TS is enabled in the imported module, this is additional config. + tailscale = { + useRoutingFeatures = "both"; + # accept-routes = true; + }; + + zfs = { + autoScrub = { + enable = true; + interval = "weekly"; + }; + trim.enable = true; + }; + }; + + # Copy the NixOS configuration file and link it from the resulting system + # (/run/current-system/configuration.nix). This is useful in case you + # accidentally delete configuration.nix. + # Does not work with flakes - yet™. + system.copySystemConfiguration = false; +} diff --git a/nix/hosts/monoceros/disko-config.nix b/nix/hosts/monoceros/disko-config.nix new file mode 100644 index 0000000..aed3503 --- /dev/null +++ b/nix/hosts/monoceros/disko-config.nix @@ -0,0 +1,119 @@ +{ + config, + disks ? ["/dev/sda"], + lib, + ... +}: let + zfs-DATA = config.age.secrets.zfs-DATA; + p = config.sops.placeholder; +in { + sops.secrets = { + "zfs/ROOT" = p."zfs/ROOT".path; + }; + systemd.services.zfs-mount.requires = ["sops-nix.service"]; + + disko.devices = { + disk = { + x = { + type = "disk"; + device = "/dev/sda"; + content = { + type = "gpt"; + partitions = { + ESP = { + type = "EF00"; + size = "700M"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + zfs = { + size = "100%"; + content = { + type = "zfs"; + pool = "zroot"; + }; + }; + }; + }; + }; + }; + zpool = { + zroot = { + type = "zpool"; + mode = ""; # == single disk + options = { + ashift = "12"; + autotrim = "on"; + }; + rootFsOptions = { + checksum = "sha512"; + compression = "zstd"; + "com.sun:auto-snapshot" = "false"; + }; + mountpoint = null; + postCreateHook = "zfs snapshot zroot@blank"; + + datasets = { + "ROOT" = { + type = "zfs_fs"; + mountpoint = null; + options."com.sun:auto-snapshot" = "false"; + }; + "ROOT/nixos" = { + type = "zfs_fs"; + mountpoint = "/"; + options = { + encryption = "aes-256-gcm"; + keyformat = "passphrase"; + keylocation = "file:///root/.zfs-ROOT.key"; + "com.sun:auto-snapshot" = "true"; + }; + postCreateHook = '' + zfs set keylocation="prompt" "zroot/$name"; + ''; + }; + nix = { + type = "zfs_fs"; + mountpoint = "/nix"; + options = { + encryption = "aes-256-gcm"; + keyformat = "passphrase"; + keylocation = "file:///root/.zfs-nix.key"; + "com.sun:auto-snapshot" = "true"; + }; + }; + DATA = { + type = "zfs_fs"; + mountpoint = "none"; + options = { + encryption = "aes-256-gcm"; + keyformat = "passphrase"; + keylocation = "file:///root/.zfs-DATA.key"; + "com.sun:auto-snapshot" = "true"; + }; + # postCreateHook = '' + # zfs set keylocation="file://${zfs-DATA}.path" "zroot/$name"; + # ''; + }; + "DATA/var-lib" = { + type = "zfs_fs"; + options = { + mountpoint = "/var/lib"; + "com.sun:auto-snapshot" = "true"; + }; + }; + "DATA-no-backup" = { + type = "zfs_fs"; + options = { + mountpoint = "none"; + "com.sun:auto-snapshot" = "false"; + }; + }; + }; + }; + }; + }; +} diff --git a/nix/hosts/monoceros/hardware-configuration.nix b/nix/hosts/monoceros/hardware-configuration.nix new file mode 100644 index 0000000..e2059d9 --- /dev/null +++ b/nix/hosts/monoceros/hardware-configuration.nix @@ -0,0 +1,26 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + swapDevices = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.ens18.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/nix/hosts/monoceros/secrets.yaml b/nix/hosts/monoceros/secrets.yaml new file mode 100644 index 0000000..bd46a48 --- /dev/null +++ b/nix/hosts/monoceros/secrets.yaml @@ -0,0 +1,41 @@ +rootPassphrase: ENC[AES256_GCM,data:pzXye/PhF1dZiK3orbKpAUrMan4teT2hTfXEALHVU3IlgxvGT0sc005ng1qHAoU17fVLHvPYg2eR6z+vsRFe7W38fCHhsaUpKA==,iv:JVg6HF1TLWLS9AugT7RrZ+FuJszSU4UcgIDaFuuXs6M=,tag:9VU71hnl4XLxg6hq76PfVQ==,type:str] +zfs: + ROOT: ENC[AES256_GCM,data:UmsQ6b0C1/kPRF4vwiQKNEMiK4L9VKdDxwMdHFvZdtgWzmXbhcDBl/MNvV0vrFFb3YhORvYshC6Iz85V45fICLCDCXxaaCw022bXuUHzBwraVYYJFUVKYij6xrDgrM+VBxWnVMoHXm7qDj8+65B976XWf4BW0kJCgN5VfFn5zDc=,iv:/UxeLuW1+YtHFpxMqE+jrOvDH2XDmq5BSvQeCxncdFo=,tag:X9gDl+y7Bqxwh3OTbmwMAA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1nt7a9nsgwsf7c9x8yx3qu8w24svz02hpfuwtmk8dazw6j6lh33hsgv8erk + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFWVpQT3JjYUNSUndBRk5R + cG5razRNbUZtSFBwMVdIWlpyQTQyMHR3Ynd3Ck1kV0h1UGhoZ3Y2NEJiOXhEcndN + YUpxUWFiT0ptY0ZiMjVlcWczWFVOQmMKLS0tIDFRTmJma2VpbnRJVHlBd2lHSE45 + dloyaFlOK1Q3L0E5dkYvUGk5NHJIOXMK20I/tTJRUM1IdJ+2TiLaNCcV+iMw9wDz + v2hLcZy44Ri5x1uBpOihzL1sEPZHXSpHiPTjzb9B8JgErjfsSJy+1A== + -----END AGE ENCRYPTED FILE----- + - recipient: age15959gprm59azjflvpj97yt0lj6dj4d2yv0nd6u9jp32lzwp3de7qzhf85y + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjY2M5S0hEa2VabTRFOWNY + NHRJcnhGZ1NPVzJDRDhXSjdrSFpIakloSjIwCjkwbFp2dDh6cVhBaC9JMlhJK2ZV + Umo0SGlIeGFCdzVGcFpzSFY2OFZ0TncKLS0tIGVxRVMzMGtmcXNOUW5obVp5b2Zq + MldZTldrSkZQZzdldldCSG5NNmRtNGMKg0YFxVHodglwKBx6vANb4HijuRcHR2q/ + L9rsPr5yPoeDQM1xm1QijxRfjgDuE3Unq7cFovhBhj9JtjR2HiknWw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1yzlnedt49kd429jssj73v3yz5z7deyg82dq0gq86lp6dft4edg7qrcjs5v + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNRlBSeDVJMjBhTlRZTjlQ + Q09DR1IvNmlINHFsaEhJeFl2cXhlZ2tvVTBjCk9Ca3hLUDdid2pxYUlOeDNyUW84 + RWdXL0srOXFNT2tmZUpqWTc4aGdBL2MKLS0tIDlGektrWE91OFkzdS9qeHk0Tnhn + dmVoZmRnbUkwZHlaR2p6K2t3Yndlb28KPazQ4zxu/C0wQktU+NMcuIcLZyqMv5VS + 3iKDq773lgc6wcHmse1wO1eOuc1AO/+b9+hKWvioZSbatRvt0GFa8w== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2023-11-24T16:11:56Z" + mac: ENC[AES256_GCM,data:aGOSaE47Irfz1NY2d6n28PgrUl5xwUhPCnbq3OKwGC6pgtDbnnthha2tswSB8MwUmy0LwmLzsMYE4jwzKq5r8hXOMJJgRvLnm+t0bjoZdG/sGewSpio3EdG1nVBmJPmbzRbJJRw5eiDYB6zp56QKg/+9nwbpEPqab0LScFu7T+Q=,iv:TsV6r9aJAdeEgtmOU10awtfJeWG+TB5let3wEpXe1R4=,tag:nZX+6Y/knsX9GBRIVGUKAw==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.7.3