nixos-notes

nixos notes
git clone https://logand.com/git/nixos-notes.git/
Log | Files | Refs | README

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