From 6dbc617a7d36ab949511520be487e216e09f44d5 Mon Sep 17 00:00:00 2001 From: traxys Date: Wed, 20 Dec 2023 00:28:10 +0100 Subject: [PATCH] Initial template --- .gitignore | 1 + README.md | 37 +++++++++++++++++++++ config.nix | 25 ++++++++++++++ flake.nix | 67 ++++++++++++++++++++++++++++++++++++++ hardware-configuration.nix | 33 +++++++++++++++++++ secrets/secrets.nix | 8 +++++ update.sh | 5 +++ 7 files changed, 176 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 config.nix create mode 100644 flake.nix create mode 100644 hardware-configuration.nix create mode 100644 secrets/secrets.nix create mode 100644 update.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c4a847d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/result diff --git a/README.md b/README.md new file mode 100644 index 0000000..2cc9f56 --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +# NixOS template for RPi 4 + +This template allows to install & manage a NixOS distribution on an RPi4. + +## Host Preparation + +If the host is not an aarch64-linux machine, it must have nix binfmt configured: `boot.binfmt.emulatedSystems = ["aarch64-linux"];`. + +## Initial installation sdcard + +There are several things to edit in the `flake.nix` for the installation: +- `""` & `` in [flake.nix](flake.nix) +- `# My SSH Key` in [flake.nix](flake.nix) + +You can then generate a sd image using `nix build .#rpi4-install`. +Note that when using binfmt this can take a long time. + +The result will be located in `result/sd-image/nixos-sd-image-23.05.20231216.b2566f4-aarch64-linux.img.zst` +It can be written with `sudo zstdcat '.zst' -o /dev/....`. + +Tip: to see more details on the build its possible to run `nom build ...` instead of `nix build ...`. + +Note that on the first boot there most likely won't be wifi. To enable wifi a `systemctl restart wpa_supplicant` might be needed. + +## Deployment of the full configuration + +After logging in the rpi4 you need to fetch the system ssh key (located at `/etc/ssh/ssh_host_ed25519_key.pub`) and write it in [secrets.nix](secrets/secrets.nix). + +You can then run `nix run .#agenix -- -e wifi.age` in the `secrets` directory to write the wifi key. +The file must be formatted like this: +``` +WIFI_KEY="" +``` + +Then in `config.nix` `` must be substituted with the correct network name, and the SSH key should be filled in. + +In `update.sh` the IP must be filled in `HOST`, and then the configuration can be deployed using `update.sh` diff --git a/config.nix b/config.nix new file mode 100644 index 0000000..3dbccae --- /dev/null +++ b/config.nix @@ -0,0 +1,25 @@ +{config, ...}: { + imports = [ + ./hardware-configuration.nix + ]; + + boot.loader.grub.enable = false; + boot.loader.generic-extlinux-compatible.enable = true; + + # File contains "WIFI_PSK=" + age.secrets.wifi.file = ./secrets/wifi.age; + + networking.wireless = { + enable = true; + networks."".psk = "@WIFI_PSK@"; + environmentFile = config.age.secrets.wifi.path; + }; + + networking.hostName = "rpi4-nixos"; + services.openssh.enable = true; + users.users.root.openssh.authorizedKeys.keys = [ + # My SSH key + ]; + + system.stateVersion = "23.11"; +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..9e82289 --- /dev/null +++ b/flake.nix @@ -0,0 +1,67 @@ +{ + description = "A very basic flake"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05"; + inputs.nixos-hw.url = "github:NixOS/nixos-hardware"; + inputs.agenix.url = "github:ryantm/agenix"; + inputs.flake-utils.url = "github:numtide/flake-utils"; + + outputs = { + self, + nixpkgs, + nixos-hw, + flake-utils, + agenix, + }: let + buildEnv = { + nixpkgs.hostPlatform = "aarch64-linux"; + + nixpkgs.overlays = [ + (final: super: { + makeModulesClosure = x: + super.makeModulesClosure (x // {allowMissing = true;}); + }) + ]; + }; + in + { + nixosConfigurations.rpi4-install = nixpkgs.lib.nixosSystem { + modules = [ + "${nixpkgs}/nixos/modules/installer/sd-card/sd-image-aarch64-installer.nix" + nixos-hw.nixosModules.raspberry-pi-4 + buildEnv + { + networking.hostName = "rpi4-nixos"; + + services.openssh.enable = true; + users.users.root.openssh.authorizedKeys.keys = [ + # My SSH Key + ]; + + networking.wireless = { + enable = true; + # Don't commit the password! + networks."".psk = ""; + }; + + system.stateVersion = "23.11"; + } + ]; + }; + nixosConfigurations.rpi4 = nixpkgs.lib.nixosSystem { + modules = [ + nixos-hw.nixosModules.raspberry-pi-4 + agenix.nixosModules.default + buildEnv + ./config.nix + ]; + }; + images.rpi4-install = self.nixosConfigurations.rpi4-install.config.system.build.sdImage; + } + // (flake-utils.lib.eachDefaultSystem (system: { + devShell = nixpkgs.legacyPackages."${system}".mkShell { + nativeBuildInputs = [agenix.packages."${system}".agenix]; + }; + packages.agenix = agenix.packages.${system}.agenix; + })); +} diff --git a/hardware-configuration.nix b/hardware-configuration.nix new file mode 100644 index 0000000..77cefe1 --- /dev/null +++ b/hardware-configuration.nix @@ -0,0 +1,33 @@ +# 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 + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "usbhid" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888"; + fsType = "ext4"; + }; + + 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.end0.useDHCP = lib.mkDefault true; + # networking.interfaces.wlan0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; + powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand"; +} diff --git a/secrets/secrets.nix b/secrets/secrets.nix new file mode 100644 index 0000000..42490b6 --- /dev/null +++ b/secrets/secrets.nix @@ -0,0 +1,8 @@ +let + rpi4-key = ""; + myKey = ""; + + keys = [rpi4-key myKey]; +in { + "wifi.age".publicKeys = keys; +} diff --git a/update.sh b/update.sh new file mode 100644 index 0000000..51b2a16 --- /dev/null +++ b/update.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +HOST= + +nixos-rebuild switch --fast --flake .#rpi4 --target-host root@$HOST