nixos/README.md

180 lines
7 KiB
Markdown
Raw Normal View History

2023-06-25 01:28:19 +02:00
# nixos
2023-08-01 15:35:09 +02:00
## Installation
2024-04-06 00:33:42 +02:00
Follow the [NixOS
manual](https://nixos.org/manual/nixos/stable/index.html#ch-installation) to
obtain and boot the installation medium. Use the graphical ISO image since it
ships with useful programs such as `nmtui`; the installation can still be done
through the terminal.
2023-08-01 15:35:09 +02:00
### Disk Partitioning
2024-04-06 00:33:42 +02:00
For [impermanence](https://nixos.wiki/wiki/Impermanence), partitioning should
be done as outlined in the [tmpfs as
root](https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/) blogpost, but with
`/nix` as a [LUKS-encrypted file
system](https://nixos.org/manual/nixos/stable/index.html#sec-luks-file-systems).
The boot partition will not be encrypted, since that is poorly supported by
systemd-boot. Persistent files will be saved under `/nix/persist`. To find out
which of our darlings will be erased on reboot do `tree -x /` or `ncdu -x /`.
The following is based on the [tmpfs as
root](https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/) blogpost, the NixOS
manual's
[partitioning](https://nixos.org/manual/nixos/stable/index.html#sec-installation-manual-partitioning),
[formatting](https://nixos.orgmanual/nixos/stable/index.html#sec-installation-manual-partitioning-formatting)
and [LUKS-Encrypted File
Systems](https://nixos.org/manual/nixos/stable/index.html#sec-luks-file-systems)
sections, ArchWiki's [LVM on
LUKS](https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS),
the unofficial NixOS wiki [Full Disk
Encryption](https://nixos.wiki/wiki/Full_Disk_Encryption), and [this GitHub
2023-08-01 15:35:09 +02:00
gist](https://gist.github.com/martijnvermaat/76f2e24d0239470dd71050358b4d5134).
2024-04-06 00:33:42 +02:00
We create a 1GiB EFI boot partition (`/dev/sda1`) and the rest will be our
LUKS-encrypted volume:
2024-02-24 02:11:59 +01:00
```fish
2023-08-01 15:35:09 +02:00
# Create partition table
parted /dev/sda -- mklabel gpt
# Create /boot partition
parted /dev/sda -- mkpart ESP fat32 1MiB 1024MiB
parted /dev/sda -- set 1 esp on
# Create /nix partition
parted /dev/sda -- mkpart primary 1024MiB 100%
# Create and open LUKS-encrypted container
cryptsetup --type=luks2 luksFormat --label=crypted /dev/sda2
cryptsetup open /dev/sda2 crypted
# Create LVM volume group
pvcreate /dev/mapper/crypted
vgcreate vg /dev/mapper/crypted
# Create root logical volume
lvcreate -l 100%FREE vg -n root
# Format partitions
mkfs.fat -F32 -n BOOT /dev/sda1
mkfs.ext4 -L nix /dev/vg/root
```
The result should be the following (`lsblk -f`):
```text
NAME FSTYPE FSVER LABEL
2023-08-12 15:31:37 +02:00
sda
├─sda1 vfat FAT32 BOOT
└─sda2 crypto_LUKS 2 crypted
2023-08-01 15:35:09 +02:00
└─crypted LVM2_member LVM2 001
└─vg-root ext4 1.0 nix
```
2024-04-06 00:33:42 +02:00
Whereas the [NixOS
manual](https://nixos.org/manual/nixos/stable/index.html#sec-installation-manual-installing)
mounts the newly-created `nixos` partition to `/mnt`, we will follow the _tmpfs
as root_ blogpost and mount `/mnt` as `tmpfs`:
2024-02-24 02:11:59 +01:00
```fish
2023-08-01 15:35:09 +02:00
mount -t tmpfs none /mnt
mount --mkdir /dev/disk/by-label/BOOT /mnt/boot
mount --mkdir /dev/disk/by-label/nix /mnt/nix
mkdir -p /mnt/nix/persist/
```
2024-02-24 02:11:59 +01:00
### Secrets
2024-04-06 00:33:42 +02:00
All files in the Nix store are world-readable, so it is not a suitable place
for including cleartext secrets, even if we had a scheme to securely transfer
them to each system. [Agenix](https://github.com/ryantm/agenix) solves this
issue by encrypting the secrets using
[age](https://github.com/FiloSottile/age), and then decrypting and symlinking
them using the system's SSH host key during system activation.
2024-02-24 02:11:59 +01:00
2024-03-28 16:35:03 +01:00
All secrets, and other private configuration such as DNS zonefiles, are stored
in a separate, private [repo](https://git.caspervk.net/caspervk/nixos-secrets).
2024-04-06 00:33:42 +02:00
To bootstrap a new system, we must generate a host key manually during
installation:
```fish
mkdir -p /mnt/nix/persist/etc/ssh/
ssh-keygen -A -f /mnt/nix/persist
nc alpha.caspervk.net 1337 < /mnt/nix/persist/etc/ssh/ssh_host_ed25519.pub
```
Then, on an existing system, add the new host's public key to `secrets.nix` in
the `nixos-secrets` repo and **rekey** all secrets. When managing secrets, the
Keepass recovery key is used like so:
2024-02-24 02:11:59 +01:00
```fish
set AGE_KEY_FILE (mktemp); read -s > $AGE_KEY_FILE
2024-04-06 00:33:42 +02:00
agenix -i $AGE_KEY_FILE --rekey
2024-02-24 02:11:59 +01:00
agenix -i $AGE_KEY_FILE -e foo.age
```
2024-04-06 00:33:42 +02:00
The new system needs to be able to pull the `nixos-secrets` repo temporarily
during installation:
```fish
ssh-keygen -t ed25519
nc alpha.caspervk.net 1337 < /root/.ssh/id_ed25519.pub
# https://git.caspervk.net/caspervk/nixos-secrets/settings/keys
```
After bootstrapping, servers will auto-upgrade using the shared `autoUpgrade`
SSH key. Desktops will need to add `~caspervk/.ssh/id_ed25519.pub` either as a
deploy key for the `nixos-secrets` repo, or to the entire git user.
2024-02-24 02:11:59 +01:00
### Installation
2023-08-01 15:35:09 +02:00
The remaining installation can be done (more or less) according to the [NixOS
manual](https://nixos.org/manual/nixos/stable/index.html#sec-installation-manual-installing).
2024-02-24 02:11:59 +01:00
```fish
2023-08-01 15:35:09 +02:00
cd /mnt/nix
2024-04-06 00:33:42 +02:00
git clone https://git.caspervk.net/caspervk/nixos.git
cd nixos/
2023-08-01 15:35:09 +02:00
nixos-generate-config --root /mnt --show-hardware-config
vim hosts/omega/hardware.nix
2023-08-05 18:13:59 +02:00
git add . # nix sometimes ignores files outside version control
2024-04-06 00:33:42 +02:00
nixos-install --no-root-passwd --flake .#omega
2023-08-01 15:35:09 +02:00
```
2024-02-06 02:09:39 +01:00
### Hardware Configuration
2024-04-06 00:33:42 +02:00
`hosts/*/hardware.nix`, while initially generated by `nixos-generate-config
--show-hardware-config`, _is_ manually modified.
2023-08-01 15:35:09 +02:00
2024-06-02 22:56:02 +02:00
### Upgrading
2024-04-06 00:33:42 +02:00
Nixpkgs uses `stateVersion` so sparingly that auditing the entire nixpkgs repo
is [easy
2024-06-02 22:56:02 +02:00
enough](https://sourcegraph.com/search?q=context:global+repo:%5Egithub%5C.com/NixOS/nixpkgs%24+lang:Nix+stateVersion+AND+24.05&patternType=keyword&sm=0).
Important changes to home-manager is available at
<https://nix-community.github.io/home-manager/release-notes.xhtml> and
<https://github.com/nix-community/home-manager/blob/master/modules/misc/news.nix>.
2023-08-01 15:35:09 +02:00
2024-02-06 02:09:39 +01:00
## Useful Commands
2024-02-24 02:11:59 +01:00
```fish
2024-03-28 16:35:03 +01:00
# development
sudo nixos-rebuild switch --flake . --override-input secrets ./../nixos-secrets/
2023-08-16 02:29:53 +02:00
2024-02-06 02:09:39 +01:00
# start build environment with user's default shell instead of bash
nix develop --command $SHELL
2023-12-01 17:32:41 +01:00
2024-02-06 02:09:39 +01:00
# nix shell with python packages
# https://discourse.nixos.org/t/nix-shell-for-python-packages/16575
# https://github.com/NixOS/nix/issues/5567
2024-02-18 20:55:45 +01:00
nix shell --impure --expr 'with builtins.getFlake "nixpkgs"; with legacyPackages.${builtins.currentSystem}; python3.withPackages (ps: with ps; [ numpy ])'
2024-02-06 02:09:39 +01:00
```
2023-12-01 17:32:41 +01:00
2024-02-06 02:09:39 +01:00
### Debugging
2024-02-18 20:55:45 +01:00
```nix
2024-02-06 02:09:39 +01:00
# load flake into repl
2024-03-28 16:35:03 +01:00
nix repl . --override-input secrets ./../nixos-secrets/
2024-02-06 02:09:39 +01:00
2024-02-18 20:55:45 +01:00
# print a configuration option
:p nixosConfigurations.omega.options.services.openssh.ports.declarationPositions # declaration
:p nixosConfigurations.omega.options.services.openssh.ports.default # declaration default
:p nixosConfigurations.omega.options.services.openssh.ports.definitionsWithLocations # overwrites
:p nixosConfigurations.omega.options.services.openssh.ports.value # current value
# print derivation package names
:p builtins.map (d: d.name) outputs.nixosConfigurations.omega.options.environment.systemPackages.value
2024-02-06 02:09:39 +01:00
2023-12-13 20:24:08 +01:00
# print version of package in nixpkgs
2024-02-18 20:55:45 +01:00
:p inputs.nixpkgs.outputs.legacyPackages.${builtins.currentSystem}.openssh.version
2023-08-16 02:29:53 +02:00
```
2024-03-05 22:17:26 +01:00
## References
- https://github.com/nix-community/srvos/tree/29a48ae201fbd69b6b71acdae5e19fa2ceaa8181