diff --git a/README.md b/README.md index 09ef644..63ee401 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ This is my personal nix config. - `nom/` - My laptop and main development machine - `ward/` - ODROID H3, energy efficient SBC. Used as a firewall betwenn my ISP and internal home network. Hosts some lightweight services using full KVM virtual machines. - `envoy/` - Hetzner Cloud server. Primarily used as my mailserver and VPN provider. - - `zackbiene/` - ODROID N2+. Hosts IoT and Home Automation stuff and fully isolates that from my internal network. - - not yet ready for publicized: my main development machine, powerful home server, some services ... (still in transition from gentoo :/) + - `zackbiene/` - ODROID N2+. Hosts IoT and Home Automation stuff and fully isolates that stuff from my internal network. + - not yet ready for publicized: my main development machine, the powerful home server, some services ... (still in transition from gentoo :/) - `modules/` additional NixOS modules that are not yet upstreamed. - `nix/` library functions and plumbing - `apps/` Additional runnable actions for this flake @@ -52,19 +52,24 @@ This is my personal nix config. #### Add new machine -... +... incomplete. - add hosts/ - fill meta.nix - fill net.nix -- todo: hostid (move to nodeSecrets) +- fill fs.nix (you need to know the device by-id paths in advance for formatting to work!) - generate-initrd-keys - generate-wireguard-keys #### Initial deploy -- Create a iso disk image for the system using `nix build --print-out-paths --no-link .#installer-image-` -- dd the resulting image to a stick and boot from it +- Create a iso disk image for the system by using `nix build --print-out-paths --no-link .#installer-image-` +- dd the resulting image to a stick and boot from it on the target +- (Optional) ssh into the target (keys are already set up) +- Run `install-system` and reboot +- Retrieve the new host identity by using `ssh-keyscan | grep -o 'ed25519.*' > host//secrets/host.pub` +- Rekey the secrets for the new identity `nix run .#rekey` +- Deploy again remotely via colmena #### Show QR for external wireguard client diff --git a/hosts/common/initrd-ssh.nix b/hosts/common/initrd-ssh.nix index ea8c396..3e9d62c 100644 --- a/hosts/common/initrd-ssh.nix +++ b/hosts/common/initrd-ssh.nix @@ -11,4 +11,19 @@ port = 4; hostKeys = [config.rekey.secrets.initrd_host_ed25519_key.path]; }; + + # Make sure that there is always a valid initrd hostkey available that can be installed into + # the initrd. When bootstrapping a system (or re-installing), agenix cannot succeed in decrypting + # whatever is given, since the correct hostkey doesn't even exist yet. We still require + # a valid hostkey to be available so that the initrd can be generated successfully. + # The correct initrd host-key will be installed with the next update after the host is booted + # for the first time, and the secrets were rekeyed for the the new host identity. + system.activationScripts.agenixEnsureInitrdHostkey = { + text = '' + [[ -e ${rekey.secrets.initrd_host_ed25519_key.path} ]] \ + || ssh-keygen -t ed25519 -N "" -f ${rekey.secrets.initrd_host_ed25519_key.path} + ''; + deps = ["agenixInstall"]; + }; + system.activationScripts.agenixChown.deps = ["agenixEnsureInitrdHostkey"]; } diff --git a/hosts/ward/fs.nix b/hosts/ward/fs.nix index 0a8fb59..ebfd95c 100644 --- a/hosts/ward/fs.nix +++ b/hosts/ward/fs.nix @@ -7,7 +7,7 @@ disk = { m2-ssd = { type = "disk"; - device = "/dev/disk/by-id/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + device = "/dev/disk/by-id/nvme-Samsung_SSD_980_1TB_S649NL0TC36758M"; content = { type = "table"; format = "gpt"; @@ -17,6 +17,7 @@ start = "2048"; end = "1GiB"; fs-type = "fat32"; + bootable = true; content = { type = "filesystem"; format = "vfat"; @@ -27,6 +28,7 @@ name = "swap"; start = "1GiB"; end = "17GiB"; + fs-type = "linux-swap"; content = { type = "swap"; randomEncryption = true; diff --git a/nix/generate-installer.nix b/nix/generate-installer.nix index 62b8e51..18a66bb 100644 --- a/nix/generate-installer.nix +++ b/nix/generate-installer.nix @@ -8,18 +8,30 @@ pkgs, lib, ... - }: { + }: let + disko = pkgs.writeShellScriptBin "disko" "${nodeAttrs.config.system.build.disko}"; + disko-mount = pkgs.writeShellScriptBin "disko-mount" "${nodeAttrs.config.system.build.mountScript}"; + disko-format = pkgs.writeShellScriptBin "disko-format" "${nodeAttrs.config.system.build.formatScript}"; + + install-system = pkgs.writeShellScriptBin "install-system" '' + set -euo pipefail + + echo "Formatting disks..." + ${disko}/bin/disko + + echo "Installing system..." + nixos-install --no-root-password --system ${nodeAttrs.config.system.build.toplevel} + + echo "Done!" + ''; + in { + isoImage.isoName = lib.mkForce "nixos-image-${nodeName}.iso"; system.stateVersion = "23.05"; nix.extraOptions = '' experimental-features = nix-command flakes recursive-nix ''; - isoImage.isoName = lib.mkForce "nixos-image-${nodeName}.iso"; - - services.openssh = { - enable = true; - settings.PermitRootLogin = "yes"; - }; + console.keyMap = "de-latin1-nodeadkeys"; users.users.root = { password = "nixos"; @@ -37,14 +49,21 @@ fzf wget curl - # TODO nodeAttrs.config.boot.system. + + disko + disko-mount + disko-format + install-system ]; }; }; in { packages.${system}."installer-image-${nodeName}" = nixos-generators.nixosGenerate { pkgs = self.pkgs.${system}; - modules = [configuration]; + modules = [ + configuration + ../hosts/common/core/ssh.nix + ]; format = { x86_64-linux = "install-iso"; diff --git a/nix/lib.nix b/nix/lib.nix index 88c9945..d7db3f8 100644 --- a/nix/lib.nix +++ b/nix/lib.nix @@ -54,7 +54,6 @@ in rec { recursiveUpdate { ${name} = { type = "zpool"; - mode = "mirror"; rootFsOptions = { compression = "zstd"; acltype = "posix"; @@ -74,19 +73,25 @@ in rec { "local/root" = { type = "zfs_fs"; postCreateHook = "zfs snapshot ${name}/local/root@blank"; - options.canmount = "on"; - mountpoint = "/"; + options = { + canmount = "on"; + mountpoint = "/"; + }; }; "local/nix" = { type = "zfs_fs"; - options.canmount = "on"; - mountpoint = "/nix"; + options = { + canmount = "on"; + mountpoint = "/nix"; + }; }; "safe".type = "zfs_fs"; "safe/persist" = { type = "zfs_fs"; - options.canmount = "on"; - mountpoint = "/persist"; + options = { + canmount = "on"; + mountpoint = "/persist"; + }; }; }; };