nixos-notes

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

README (6673B)


      1 # NixOS Notes
      2 
      3 ## Installation
      4 
      5 Partition Disk
      6 
      7     # lsblk
      8     # parted /dev/sdX -- p
      9     # parted /dev/sdX -- mklabel gpt
     10     # parted /dev/sdX -- mkpart primary 1024MiB 100%
     11     # parted /dev/sdX -- mkpart ESP fat32 256MiB 1024MiB
     12     # parted /dev/sdX -- mkpart GRUB 1MiB 256MiB
     13     # parted /dev/sdX -- set 2 esp on
     14     # parted /dev/sdX -- set 2 boot on
     15     # parted /dev/sdX -- set 3 bios_grub on
     16     # parted /dev/sdX -- align-check optimal 1
     17 
     18 Format Disks
     19 
     20     # mkfs.vfat -F32 /dev/sdX2
     21     # cryptsetup -v luksFormat /dev/sdX1
     22     # cryptsetup luksOpen /dev/sdX1 luksroot
     23     # mkfs.nilfs2 -L root /dev/mapper/luksroot
     24 
     25 Mount Disks
     26 
     27     # mount /dev/mapper/luksroot /mnt
     28     # mkdir /mnt/boot
     29     # mount /dev/sdX2 /mnt/boot
     30 
     31 Install NixOS
     32 
     33     # nixos-generate-config --root /mnt
     34     # ...edit /mnt/etc/nixos/configuration.nix
     35     # nixos-install
     36     # ...set root password
     37     # reboot
     38 
     39 ## WiFi from Command Line
     40 
     41     $ sudo wpa_supplicant -B -i iface -c <(wpa_passphrase ssid key)
     42 
     43 Without passphrase is more complex: create file /tmp/cbase.wifi with
     44 the following contents:
     45 
     46     network={
     47     ssid="c-base-public"
     48     key_mgmt=NONE
     49     }
     50 
     51     $ sudo wpa_supplicant -i wlp3s0 -c /tmp/cbase.wifi
     52 
     53 ## Backups
     54 
     55     $ sudo cryptsetup -v luksFormat /dev/sdX
     56     $ sudo cryptsetup luksOpen /dev/sdX backup
     57     $ sudo cryptsetup luksDump /dev/sdX
     58     $ sudo cryptsetup -v status backup
     59     $ sudo dd if=/dev/zero of=/dev/mapper/backup status=progress bs=128M
     60     $ sudo mkfs.ext3 /dev/mapper/backup
     61     $ sudo mount /dev/mapper/backup /mnt
     62     $ sudo umount /dev/mapper/backup
     63     $ sudo cryptsetup luksClose backup
     64 
     65     $ sudo cryptsetup luksAddKey /dev/sdX
     66     $ sudo cryptsetup luksRemoveKey /dev/sdX
     67 
     68 ## Deployment
     69 
     70 There are several deployment tools for nixos each with pros and cons.
     71 
     72 - nixops: tried it, didn't like it.  too stateful and fragile.
     73 
     74 - hail: did not try.  looks abandoned.  pulls updates from hydra.
     75 
     76 - morph: did not try.  looks complex.
     77 
     78 - krops: did not try.  actively used.  builds remotely, which I don't
     79   want.  A production server should serve specific purpose and things
     80   which don't serve that purpose should not be there, i.e. I don't
     81   want to build there anything and I don't want the build artefacts to
     82   be stored there.
     83 
     84 - nixos-rebuild: nixos native command.  supports deploying to other
     85   machines but doesn't do substitutes, which is a major flaw on
     86   asymetric connections with bad upload speed.
     87 
     88 nixos-rebuild is actually closest to what I want.
     89 
     90 Here is an example of a deployment scripts for several machines, each
     91 with different nixpkgs.  Deployment scripts are first built for all
     92 machines (can be built and cached by hydra, for example).  Running a
     93 deployment script handles local and remote deployments accordingly.
     94 Remote deployments immitate "nixos-rebuild switch" but allow
     95 substitutes by copying the closure first.
     96 
     97 Have subdir with configuration.nix for each machine.  default.nix can
     98 look something like this:
     99 
    100     # nix-build && ./result/bin/deploy-all
    101     # nix-build && ./result/bin/deploy-hostname1
    102     # nix-build && ./result/bin/deploy-hostname2
    103     let
    104       pkgs = import <nixpkgs> {};
    105       nixpkgs1809 = fetchTarball {
    106         url = https://nixos.org/channels/nixos-18.09/nixexprs.tar.xz;
    107       };
    108       nixpkgs1903 = fetchTarball {
    109         url = https://nixos.org/channels/nixos-19.03/nixexprs.tar.xz;
    110       };
    111       local = name: nixpkgs:
    112         pkgs.writeScript "deploy-local-${name}" ''
    113           sudo nixos-rebuild switch \
    114             -I nixos-config=./${name}/configuration.nix \
    115             -I nixpkgs=${nixpkgs}
    116         '';
    117       buildSystem = name: nixpkgs:
    118         let
    119           # https://stackoverflow.com/questions/47655567/how-to-build-a-nixops-deployment-on-hydra
    120           pkgs2 = import nixpkgs {};
    121           nixosSystem = import (pkgs2.path + "/nixos/lib/eval-config.nix") {
    122             inherit (pkgs2) system;
    123             modules = [(./. + "/${name}/configuration.nix")];
    124           };
    125         in nixosSystem.config.system.build.toplevel;
    126       remote = name: nixpkgs:
    127         let
    128           sshName = "${name}.tincnet";
    129           system = buildSystem name nixpkgs;
    130           pkgs2 = import nixpkgs {};
    131           switch = pkgs.writeScript "switch-${name}" ''
    132             #!${pkgs2.bash}/bin/bash
    133             set -euo pipefail
    134             cd /tmp
    135             ls -al /nix/var/nix/profiles
    136             echo register ${system}
    137             sudo nix-env -p /nix/var/nix/profiles/system --set ${system}
    138             echo switch
    139             sudo nohup ${system}/bin/switch-to-configuration switch
    140             ls -al /nix/var/nix/profiles
    141           '';
    142         in
    143           pkgs.writeScript "deploy-remote-${name}" ''
    144             #!${pkgs.bash}/bin/bash
    145             set -euo pipefail
    146             echo starting ${name} to ${sshName}
    147             #nix-copy-closure --sign --use-substitutes --to ${sshName} ${switch}
    148             nix-copy-closure --gzip --use-substitutes --to ${sshName} ${switch}
    149             #nix copy --to ssh://${sshName} ${switch}
    150             ssh -t ${sshName} ${switch}
    151             echo ok ${name} to ${sshName}
    152           '';
    153       deploy1 = name: nixpkgs:
    154         pkgs.writeScriptBin "deploy-${name}" ''
    155           #!${pkgs.bash}/bin/bash
    156           set -euo pipefail
    157           if test ${name} == $(hostname -s); then
    158             exec ${local name nixpkgs}
    159           else
    160             exec ${remote name nixpkgs}
    161           fi
    162         '';
    163       all = [
    164         (deploy1 "hostname1" nixpkgs1809)
    165         (deploy1 "hostname2" nixpkgs1903)
    166       ];
    167     in
    168       pkgs.buildEnv {
    169         name = "deploy";
    170         paths = all ++ [
    171           (pkgs.writeScriptBin "deploy-all" (''
    172             #!${pkgs.bash}/bin/bash
    173             set -euo pipefail
    174            ''
    175            + (pkgs.stdenv.lib.concatMapStrings (x: "${x}\n") all)))
    176         ];
    177       }
    178 
    179 If the closure is not signed, your user needs to be trusted by nix in
    180 the target machine configuration.nix:
    181 
    182     nix.trustedUsers = ["root" "myuser"];
    183 
    184 ## Secrets
    185 
    186 Nix does not address management of secrets.
    187 
    188 Some NixOS deployment tools try to handle it by creating the secret
    189 keys somewhere and then pushing them to the target machines.  I am not
    190 convinced that this is the right approach.  Secrets should not be
    191 pushed around unnecessarily.
    192 
    193 What I do, for example, for tinc:
    194 
    195 - define the tinc service with empty fields for unknown public keys
    196 
    197 - deploy the the tinc service, let it generate the keys on the target
    198   machine
    199 
    200 - read the public key from the target machine and update the tinc
    201   service with the newly acquired public key
    202 
    203 - deploy the tinc service for the second time, this time with the
    204   public key already filled in