🧶
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

added notes to not forget about these mistakes

+143
+143
docs/notes.md
··· 1 + # sops-nix setup on NixOS (Raspberry Pi 4 from macOS) 2 + 3 + ## Goal 4 + 5 + Migrate a plain `configuration.nix` to Nix Flakes and encrypt secrets using 6 + `sops-nix`, deploying from macOS to a Raspberry Pi 4. 7 + 8 + ## Stack 9 + 10 + - **sops** — encrypts secrets in git 11 + - **age** — encryption backend (derived from existing ED25519 SSH keys via `ssh-to-age`) 12 + - **sops-nix** — NixOS module that decrypts secrets at boot 13 + - **deploy-rs** — deploys from macOS to the Pi over SSH with automatic rollback 14 + 15 + --- 16 + 17 + ## Setup steps 18 + 19 + ### 1. Desktop — derive age identity from your SSH key 20 + 21 + ```bash 22 + mkdir -p $HOME/.config/sops/age/ 23 + read -s SSH_TO_AGE_PASSPHRASE; export SSH_TO_AGE_PASSPHRASE 24 + nix run nixpkgs#ssh-to-age -- -private-key -i $HOME/.ssh/id_ed25519 -o $HOME/.config/sops/age/keys.txt 25 + ``` 26 + 27 + Get your age public key: 28 + 29 + ```bash 30 + nix shell nixpkgs#age --command age-keygen -y $HOME/.config/sops/age/keys.txt 31 + ``` 32 + 33 + ### 2. Raspberry Pi — get the host age public key 34 + 35 + ```bash 36 + cat /etc/ssh/ssh_host_ed25519_key.pub | nix run nixpkgs#ssh-to-age 37 + ``` 38 + 39 + ### 3. Desktop — create `.sops.yaml` 40 + 41 + ```yaml 42 + keys: 43 + - &admin_you age1... # from step 1 44 + - &raspberrypi age1... # from step 2 45 + creation_rules: 46 + - path_regex: secrets/[^/]+\.(yaml|json|env|ini)$ 47 + key_groups: 48 + - age: 49 + - *admin_you 50 + - *raspberrypi 51 + ``` 52 + 53 + ### 4. Desktop — create and edit secrets 54 + 55 + ```bash 56 + mkdir -p secrets 57 + nix run nixpkgs#sops secrets/raspberry.yaml 58 + ``` 59 + 60 + --- 61 + 62 + ## Secrets in `configuration.nix` 63 + 64 + Sops secrets are **files on disk at runtime**, not Nix strings. They cannot be 65 + interpolated with `${}` at build time. Each type of secret needs a different 66 + approach: 67 + 68 + | Secret | How to consume it | 69 + |---|---| 70 + | User password | `hashedPasswordFile = config.sops.secrets.X.path` | 71 + | WiFi credentials | `networking.wireless.secretsFile` + `@VARIABLE@` placeholders | 72 + | SSH public key | Plain text in config — it's public, no need to encrypt | 73 + 74 + ### WiFi 75 + 76 + WiFi credentials need a single file containing both values: 77 + 78 + ```yaml 79 + # secrets/raspberry.yaml 80 + WIFI_CREDENTIALS: | 81 + WIFI_SSID=YourNetwork 82 + WIFI_PASSWORD=YourPassword 83 + ``` 84 + 85 + ```nix 86 + networking.wireless = { 87 + enable = true; 88 + secretsFile = config.sops.secrets.WIFI_CREDENTIALS.path; 89 + networks."@WIFI_SSID@".psk = "@WIFI_PASSWORD@"; 90 + }; 91 + ``` 92 + 93 + ### User password 94 + 95 + The secret must have `neededForUsers = true` so it is available before user 96 + activation runs: 97 + 98 + ```nix 99 + sops.secrets.USER_PASSWORD = { neededForUsers = true; }; 100 + 101 + users.users.alice = { 102 + hashedPasswordFile = config.sops.secrets.USER_PASSWORD.path; 103 + }; 104 + ``` 105 + 106 + --- 107 + 108 + ## Errors encountered and fixes 109 + 110 + ### sops can't decrypt the file on second open 111 + 112 + ``` 113 + Did not find keys in locations 'SOPS_AGE_KEY_FILE', '/Users/.../.ssh/id_rsa' 114 + ``` 115 + 116 + **Cause:** sops looks for `id_rsa` by default and doesn't find `keys.txt`. 117 + 118 + **Fix:** export the variable pointing to the age keys file and add it to your shell config: 119 + 120 + ```bash 121 + export SOPS_AGE_KEY_FILE="$HOME/.config/sops/age/keys.txt" 122 + ``` 123 + 124 + --- 125 + 126 + ### `/run` is forbidden in pure evaluation mode 127 + 128 + ``` 129 + error: access to absolute path '/run' is forbidden in pure evaluation mode 130 + ``` 131 + 132 + **Cause:** `openssh.authorizedKeys.keyFiles` was set to 133 + `config.sops.secrets.SSH_PUBLIC_KEY.path`, which resolves to `/run/secrets/...`. 134 + Nix evaluates this path at build time, but `/run` only exists at runtime. 135 + 136 + **Fix:** SSH public keys are not sensitive. Remove `SSH_PUBLIC_KEY` from sops 137 + and put the key directly in the config: 138 + 139 + ```nix 140 + openssh.authorizedKeys.keys = [ 141 + "ssh-ed25519 AAAA... you@desktop" 142 + ]; 143 + ```