summaryrefslogtreecommitdiff
path: root/src/nixos.thrust
blob: 9d669aadc8c9530ce72d305335e3a13446a2bfc6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
---
title: Nix & NixOS
date: 2020-07-06
---
{% extends 'templates/base.html' %}
{% block body %}
	<nav>
		<a href='/projects'>&gt; projects home</a>
	</nav>
	<header>
		<h1>{{ title }}</h1>
		<p>{{ subtitle }}</p>
	</header>
	<article>
{% markdown %}
This article contains tips & tricks for using [NixOS](https://nixos.org).

[TOC]

## Installing NixOS

This guide lays out how to install NixOS with an encrypted root and swap disk.
The resulting system will have 2 physical partitions:

- `/boot`.
- `/dev/mapper/cryptroot`, an encrypted partition with 2 virtual partitions:
    - `/dev/vg/root`, mounted as `/`.
    - `/dev/vg/swap`, used for swap.

### Physical partitions

First, determine if your machine supports UEFI (most modern PCs), or only has BIOS (e.g. my Thinkpad X201).

If it has UEFI, the below snippet creates a 512MiB UEFI boot partition, which has to be FAT32, and uses the rest of the disk for our cryptroot.

    $ parted /dev/sda
    > mklabel gpt
    > mkpart ESP fat32 1MiB 512MiB
    > set 1 boot on
    > mkpart primary 512MiB 100%
    > quit

For machines without UEFI, the procedure is similar, but needs to use BIOS and MBR formats.

    $ parted /dev/sda
    > mklabel msdos
    > mkpart primary 1MiB 512MiB
    > set 1 boot on
    > mkpart primary 512MiB 100%
    > quit

To set up [LUKS](https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup) disk encryption, first encrypt the second partition (`/dev/sda2`), then unlock it and map it at `/dev/mapper/cryptroot`:

    $ cryptsetup luksFormat /dev/sda2
    $ cryptsetup open /dev/sda2 cryptroot

### Virtual Partitions

To split our LUKS-encrypted partition into two virtual partitions, we will use [LVM](https://en.wikipedia.org/wiki/Logical_Volume_Manager_(Linux)) to create a _Physical Volume_ containing a _Volume Group_ containing 2 _Logical Volumes_.

Create a Physical Volume (`pv`):

    $ pvcreate /dev/mapper/cryptroot

Create a Volume Group (`vg`) on that `pv`:

    $ vgcreate vg /dev/mapper/cryptroot

Create two Logical Volumes (`lv`) on that `vg`, one for swap and one for data:

    $ lvcreate -L 8G -n swap vg
    $ lvcreate -l '100%FREE' -n root vg

### Formatting & Mounting

For UEFI, format the boot partition as FAT32:

    $ mkfs.fat -F 32 -n boot /dev/sda1

For BIOS / MBR, format the boot partition as EXT4:

    $ mkfs.ext4 -L boot /dev/sda1

For both, format `/` and the swap partition:

    $ mkfs.ext4 -L root /dev/vg/root
    $ mkswap -L swap /dev/vd/swap

Then mount them all:

    $ mount /dev/vg/root /mnt
    $ mkdir /mnt/boot
    $ mount /dev/sda1 /mnt/boot
    $ swapon /dev/vg/swap

### Actually installing NixOS

We will need to make sure that our encrypted physical partition is unencrypted early in boot, so that the virtual partitions can be mounted.

Generate an initial `configuration.nix`:

    $ nixos-generate-config --root /mnt

The file `/mnt/etc/nixos/hardware-configuration.nix` should reference the UUIDs for the physical `/dev/sda1` and _logical_ `/dev/vg/root` and `/dev/vg/swap`.

To mount the encrypted LVM partitions early in boot, we need to pass the UUID of the physical partition `/dev/sda2` to `initrd`.
This can be found with `ls -l /dev/disk/by-uuid` and seeing which UUID is pointing to `/dev/sda2`:

    $ ls -l /dev/disk/by-uuid
    ... b2bacfda-0929-43ef-9f8f-c326c41d9126 -> ../../sda1
    ... 4e906a20-63fc-4aec-93de-8502f24daa91 -> ../../sda2
    ... 97650361-78bc-4026-962d-0774fc388d63 -> ../../dm-1
    ... fa099f4f-38b8-4ebc-914c-86b11598128d -> ../../dm-2

This value must then be 

    $ cat /mnt/etc/nixos/configuration.nix
    ...
    boot.loader.grub.device = "/dev/sda";
    boot.initrd.luks.devices.root = {
      device = "/dev/disk/by-uuid/4e906a20-63fc-4aec-93de-8502f24daa91";
      preLVM = true;  # we need to decrypt the physical partition before LVM mounts our logical partitions.
      allowDiscards = true;  # enables TRIM, optional.
    };

Continue NixOS installation, rebooting after:

    $ nixos-install
    $ reboot

After rebooting, you will need to type your LUKS password, and it should boot normally from there on.
{% endmarkdown %}
	</article>
{% endblock %}