README (8963B)
1 # NixOS Notes 2 3 ## WiFi from Command Line 4 5 $ ip a 6 $ sudo bash -c 'wpa_supplicant -B -i iface -c <(wpa_passphrase ssid key)' 7 8 Without passphrase is more complex: create file /tmp/cbase.wifi with 9 the following contents: 10 11 network={ 12 ssid="c-base-public" 13 key_mgmt=NONE 14 } 15 16 $ sudo wpa_supplicant -i wlp3s0 -c /tmp/cbase.wifi 17 18 ## Installation 19 20 Network connection is needed for installation. 21 Use cable ethernet or wifi. 22 23 Prepare installation disk 24 25 https://nixos.org 26 27 $ cd ~/Downloads 28 $ wget https://channels.nixos.org/nixos-22.05/latest-nixos-minimal-x86_64-linux.iso 29 $ wget https://channels.nixos.org/nixos-22.05/latest-nixos-minimal-x86_64-linux.iso.sha256 30 $ cat latest-nixos-minimal-x86_64-linux.iso.sha256 31 $ mv latest-nixos-minimal-x86_64-linux.iso nixos-minimal-22.05.3050.d86a4619b7e-x86_64-linux.iso 32 $ sha256sum -c latest-nixos-minimal-x86_64-linux.iso.sha256 33 34 insert usb stick 35 36 $ dmesg | tail 37 $ lsblk 38 $ sudo ddrescue --force nixos-minimal-22.05.3050.d86a4619b7e-x86_64-linux.iso /dev/sdX 39 #$ sudo dd if=nixos-minimal-22.05.3050.d86a4619b7e-x86_64-linux.iso of=/dev/sdX 40 $ lsblk 41 42 boot from the usb stick above 43 44 $ sudo su - 45 # setfont ter-i32n 46 47 ensure internet connection works: 48 49 # ping 1.1.1.1 50 51 (If not, configure wifi, see above.) 52 53 Partition Disk 54 55 dos label: 1 partition enough 56 gpt label: needs grub partition + root + boot 57 58 # lsblk 59 # parted /dev/sdX -- p 60 # parted /dev/sdX -- mklabel gpt 61 # parted /dev/sdX -- mkpart primary 1024MiB 100% 62 # parted /dev/sdX -- mkpart ESP fat32 1MiB 1024MiB 63 # parted /dev/sdX -- set 2 esp on 64 # parted /dev/sdX -- set 2 boot on 65 # parted /dev/sdX -- align-check optimal 1 66 # lsblk 67 68 Format Disks 69 70 # mkfs.vfat -F32 /dev/sdX2 71 # cryptsetup -v luksFormat /dev/sdX1 72 # cryptsetup luksOpen /dev/sdX1 luksroot 73 # lsblk 74 75 # mkfs.ext4 -L root /dev/mapper/luksroot 76 or 77 # nix-shell -p nilfs-utils --run 'mkfs.nilfs2 -L root /dev/mapper/luksroot' 78 79 Mount Disks 80 81 # mount /dev/mapper/luksroot /mnt 82 # mkdir /mnt/boot 83 # mount /dev/sdX2 /mnt/boot 84 85 Install NixOS 86 87 # nixos-generate-config --root /mnt 88 89 edit /mnt/etc/nixos/configuration.nix 90 91 # nix-shell -p emacs-nox --run 'emacs /mnt/etc/nixos/configuration.nix' 92 93 boot.loader.systemd-boot.enable = true; 94 boot.loader.efi.canTouchEfiVariables = true; 95 boot.supportedFilesystems = ["nilfs2"]; 96 boot.initrd.kernelModules = ["nilfs2"]; 97 98 networking.hostName = "foo"; 99 networking.wireless = { 100 enable = true; 101 networks = { 102 foo = {psk = "bar";}; 103 c-base-public = {}; 104 }; 105 }; 106 107 services.openssh = { 108 enable = true; 109 permitRootLogin = "yes"; 110 passwordAuthentication = true; 111 forwardX11 = false; 112 extraConfig = '' 113 useDNS = no 114 ''; 115 }; 116 users.mutableUsers = false; 117 # nix-shell -p mkpasswd --run 'mkpasswd -m SHA-512 -s' 118 users.users.root.initialHashedPassword = "hashed-password-from-above"; 119 120 and start installation: 121 122 # nixos-install --no-root-passwd 123 # reboot 124 125 ## Backups 126 127 $ sudo cryptsetup -v luksFormat /dev/sdX 128 $ sudo cryptsetup luksOpen /dev/sdX backup 129 $ sudo cryptsetup luksDump /dev/sdX 130 $ sudo cryptsetup -v status backup 131 $ sudo dd if=/dev/zero of=/dev/mapper/backup status=progress bs=128M 132 $ sudo mkfs.ext3 /dev/mapper/backup 133 $ sudo mount /dev/mapper/backup /mnt 134 $ sudo umount /dev/mapper/backup 135 $ sudo cryptsetup luksClose backup 136 137 $ sudo cryptsetup luksAddKey /dev/sdX 138 $ sudo cryptsetup luksRemoveKey /dev/sdX 139 140 ## Deployment 141 142 There are several deployment tools for nixos each with pros and cons. 143 144 - nixops: tried it, didn't like it. Too stateful and fragile. 145 146 - hail: did not try. Looks abandoned. Pulls updates from hydra. 147 148 - morph: did not try. Looks complex. 149 150 - krops: did not try. Actively used. Builds remotely, which I don't 151 want. A production server should serve specific purpose and things 152 which don't serve that purpose should not be there, i.e. I don't 153 want to build there anything and I don't want the build artefacts to 154 be stored there. 155 156 - nixos-rebuild: nixos native command. Supports deploying to other 157 machines but doesn't do substitutes, which is a major flaw on 158 asymetric connections with bad upload speed. 159 160 nixos-rebuild is actually closest to what I want. 161 162 Here is an example of a deployment scripts for several machines, each 163 with different nixpkgs. Deployment scripts are first built for all 164 machines (can be built and cached by hydra, for example). Running a 165 deployment script handles local and remote deployments accordingly. 166 Remote deployments immitate "nixos-rebuild switch" but allow 167 substitutes by copying the closure first. 168 169 Have subdir with configuration.nix for each machine. default.nix can 170 look something like this: 171 172 # nix-build && ./result/bin/deploy-all 173 # nix-build && ./result/bin/deploy-hostname1 174 # nix-build && ./result/bin/deploy-hostname2 175 let 176 pkgs = import <nixpkgs> {}; 177 nixpkgs1809 = fetchTarball { 178 url = https://nixos.org/channels/nixos-18.09/nixexprs.tar.xz; 179 }; 180 nixpkgs1903 = fetchTarball { 181 url = https://nixos.org/channels/nixos-19.03/nixexprs.tar.xz; 182 }; 183 local = name: nixpkgs: 184 pkgs.writeScript "deploy-local-${name}" '' 185 sudo nixos-rebuild switch \ 186 -I nixos-config=./${name}/configuration.nix \ 187 -I nixpkgs=${nixpkgs} 188 ''; 189 buildSystem = name: nixpkgs: 190 let 191 # https://stackoverflow.com/questions/47655567/how-to-build-a-nixops-deployment-on-hydra 192 pkgs2 = import nixpkgs {}; 193 nixosSystem = import (pkgs2.path + "/nixos/lib/eval-config.nix") { 194 inherit (pkgs2) system; 195 modules = [(./. + "/${name}/configuration.nix")]; 196 }; 197 in nixosSystem.config.system.build.toplevel; 198 remote = name: nixpkgs: 199 let 200 sshName = "${name}.tincnet"; 201 system = buildSystem name nixpkgs; 202 pkgs2 = import nixpkgs {}; 203 switch = pkgs.writeScript "switch-${name}" '' 204 #!${pkgs2.bash}/bin/bash 205 set -euo pipefail 206 cd /tmp 207 ls -al /nix/var/nix/profiles 208 echo register ${system} 209 sudo nix-env -p /nix/var/nix/profiles/system --set ${system} 210 echo switch 211 sudo nohup ${system}/bin/switch-to-configuration switch 212 ls -al /nix/var/nix/profiles 213 ''; 214 in 215 pkgs.writeScript "deploy-remote-${name}" '' 216 #!${pkgs.bash}/bin/bash 217 set -euo pipefail 218 echo starting ${name} to ${sshName} 219 #nix-copy-closure --sign --use-substitutes --to ${sshName} ${switch} 220 nix-copy-closure --gzip --use-substitutes --to ${sshName} ${switch} 221 #nix copy --to ssh://${sshName} ${switch} 222 ssh -t ${sshName} ${switch} 223 echo ok ${name} to ${sshName} 224 ''; 225 deploy1 = name: nixpkgs: 226 pkgs.writeScriptBin "deploy-${name}" '' 227 #!${pkgs.bash}/bin/bash 228 set -euo pipefail 229 if test ${name} == $(hostname -s); then 230 exec ${local name nixpkgs} 231 else 232 exec ${remote name nixpkgs} 233 fi 234 ''; 235 all = [ 236 (deploy1 "hostname1" nixpkgs1809) 237 (deploy1 "hostname2" nixpkgs1903) 238 ]; 239 in 240 pkgs.buildEnv { 241 name = "deploy"; 242 paths = all ++ [ 243 (pkgs.writeScriptBin "deploy-all" ('' 244 #!${pkgs.bash}/bin/bash 245 set -euo pipefail 246 '' 247 + (pkgs.stdenv.lib.concatMapStrings (x: "${x}\n") all))) 248 ]; 249 } 250 251 If the closure is not signed, your user needs to be trusted by nix in 252 the target machine configuration.nix: 253 254 nix.trustedUsers = ["root" "myuser"]; 255 256 ## Secrets 257 258 Nix does not address management of secrets. 259 260 Some NixOS deployment tools try to handle it by creating the secret 261 keys somewhere and then pushing them to the target machines. I am not 262 convinced that this is the right approach. Secrets should not be 263 pushed around unnecessarily. 264 265 What I do, for example, for tinc: 266 267 - define the tinc service with empty fields for unknown public keys 268 269 - deploy the the tinc service, let it generate the keys on the target 270 machine 271 272 - read the public key from the target machine and update the tinc 273 service with the newly acquired public key 274 275 - deploy the tinc service for the second time, this time with the 276 public key already filled in 277 278 ## Recover Lost Password 279 280 TODO systemd-boot? 281 282 GRUB: 283 284 - press e to edit kernel setting 285 286 - add init=/bin/sh to the end 287 288 - fsck root file system 289 290 - mount -o remount,rw / 291 292 - passwd root 293 294 - mount -o remount,ro / 295 296 - reboot -d -f (exec /sbin/init should work) 297 298 LILO: 299 300 - Linux init=/bin/sh at the end of LILO boot prompt (hold shift while 301 booting) 302 303 - other steps are the same 304 305 YABOOT: 306 307 - Linux init=/bin/sh at yaboot prompt