chore(): New blog post on installing NixOS on ecrypted ZFS
This commit is contained in:
parent
1903876116
commit
d3513686ee
2 changed files with 468 additions and 0 deletions
|
@ -5903,6 +5903,232 @@ I made my modification to the =base.tmpl= and rendered the blog. It was that sim
|
||||||
|
|
||||||
**** Conclusion
|
**** Conclusion
|
||||||
You can always clone the /theme repository/ and make your modifications to it. But maintenance becomes an issue. This seems to be a cleaner way for me to make modifications on the original /theme/ I'm using. This is how you can too.
|
You can always clone the /theme repository/ and make your modifications to it. But maintenance becomes an issue. This seems to be a cleaner way for me to make modifications on the original /theme/ I'm using. This is how you can too.
|
||||||
|
** Nix :@nix:
|
||||||
|
*** DONE NixOS on encrypted ZFS :@nixos:zfs:encryption:
|
||||||
|
:PROPERTIES:
|
||||||
|
:EXPORT_HUGO_LASTMOD: 2021-10-17
|
||||||
|
:EXPORT_DATE: 2021-10-17
|
||||||
|
:EXPORT_FILE_NAME: nixos-on-encrypted-zfs
|
||||||
|
:CUSTOM_ID: nixos-on-encrypted-zfs
|
||||||
|
:END:
|
||||||
|
|
||||||
|
I wouldn't call myself a distro hopper. The decision of distribution is solely
|
||||||
|
based on requirements. I have requirements and I want the distribution to
|
||||||
|
fulfill them as much as possible. After 15 years, I know what I want and I go
|
||||||
|
and find it.
|
||||||
|
|
||||||
|
In this case, an unexpected project caught my eye. The idea is so radically
|
||||||
|
different that I wasn't actually searching for it this time. It is one of those
|
||||||
|
times where it found me first.
|
||||||
|
|
||||||
|
After looking into *Nix* and *NixOS*, I decided it is going to be my
|
||||||
|
distribution of choice on the desktop. I will use that as my test bed before
|
||||||
|
migrating all the serious work there. That's how I got my first taste of *NixOS*
|
||||||
|
outside of the deterministic virtualization layer and into the wild.
|
||||||
|
|
||||||
|
#+hugo: more
|
||||||
|
|
||||||
|
**** Requirements
|
||||||
|
Before installing any new system, I draftdown a list of requirements I would
|
||||||
|
need this system to run. These are things that are very hard to change on the
|
||||||
|
fly in the future without some serious work. Also, things that simply need to be
|
||||||
|
there in this day and age.
|
||||||
|
|
||||||
|
***** Filesystem
|
||||||
|
I'm a big fan of ~zfs~. I've been running it on Linux, since the ~openzfs~
|
||||||
|
project successfully ported it, with no issues. It's a solid choice for a
|
||||||
|
filesystem and I don't see a reason not to choose it.
|
||||||
|
|
||||||
|
Is it really a requirement ?
|
||||||
|
|
||||||
|
Well, yes. By now, ~openzfs~ should be accessible to all distributions but my
|
||||||
|
choice of distribution is not usually for the beginner user. I need to know
|
||||||
|
it's supported and documented. I can figure out the rest from there.
|
||||||
|
|
||||||
|
***** Encryption
|
||||||
|
This is the first requirement, I always want encryption. The reason why I put it
|
||||||
|
second in the list is that I needed to talk about ~zfs~ first.
|
||||||
|
|
||||||
|
The ~zfs~ filesystem offers encryption. Unfortunately, my research have shown
|
||||||
|
that ~zfs~ might not encrypt some metadata. This might not be a big deal but the
|
||||||
|
choice of using Luks is there as well.
|
||||||
|
|
||||||
|
With Luks, we can encrypt the whole drive. So let's do that; Luks with ~zfs~ on top.
|
||||||
|
|
||||||
|
**** NixOS
|
||||||
|
*NixOS* utilizes *Nix* to build you an OS from a configuration file. This
|
||||||
|
configuration file is written in the ~nix~ language. It is very analogous to
|
||||||
|
written an ~Ansible~ playbook but it builds an OS instead.
|
||||||
|
|
||||||
|
The idea sounded appealing to me. A good friend of mine, [[https://setkeh.com/][setkeh]], gave me a quick and
|
||||||
|
dirty overview, at first. That pushed me into doing more research of my own
|
||||||
|
where I found out that I can spawn off a ~nix-shell~ with whatever dependencies
|
||||||
|
I want without having them installed on my system. What a great concept for
|
||||||
|
development or even running applications you don't really want to run. ~Java~
|
||||||
|
stuff for example.
|
||||||
|
|
||||||
|
Anyway, for all of these different reasons I have chosen *NixOS* to be the OS of
|
||||||
|
choice to go on the desktop.
|
||||||
|
|
||||||
|
**** Installation
|
||||||
|
After testing [[https://nixos.org/][*NixOS*]] in a VM a few times, I got =setkeh= on a conference
|
||||||
|
session and we dug into this.
|
||||||
|
|
||||||
|
***** Filesystem partitioning
|
||||||
|
For the filesystem, we're going to create two partitions. We need one, ~vfat~,
|
||||||
|
for the boot and another, ~zfs~, for the rest of the filesystem.
|
||||||
|
|
||||||
|
#+BEGIN_EXPORT html
|
||||||
|
<div class="admonition note">
|
||||||
|
<p class="admonition-title"><b>Note</b></p>
|
||||||
|
#+END_EXPORT
|
||||||
|
The assumption is that we're installing *NixOS* on an ~EFI~ enabled system.
|
||||||
|
#+BEGIN_EXPORT html
|
||||||
|
</div>
|
||||||
|
#+END_EXPORT
|
||||||
|
|
||||||
|
We can start by creating the first partition of =1GB=.
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
sgdisk -n3:1M:+1024M -t3:EF00 /dev/disk/by-id/VENDOR-ID
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Followed by the rest of the filesystem.
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
sgdisk -n1:0:0 -t1:BF01 /dev/disk/by-id/VENDOR-ID
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+BEGIN_EXPORT html
|
||||||
|
<div class="admonition note">
|
||||||
|
<p class="admonition-title"><b>Note</b></p>
|
||||||
|
#+END_EXPORT
|
||||||
|
It is usually easier to do the partitioning using =GParted=. Make sure that the
|
||||||
|
partitions are unformatted, if you do so.
|
||||||
|
#+BEGIN_EXPORT html
|
||||||
|
</div>
|
||||||
|
#+END_EXPORT
|
||||||
|
|
||||||
|
#+BEGIN_EXPORT html
|
||||||
|
<div class="admonition warning">
|
||||||
|
<p class="admonition-title"><b>Warning</b></p>
|
||||||
|
#+END_EXPORT
|
||||||
|
Do *NOT* forget to enable the boot flag on the first partition or your system
|
||||||
|
will not boot.
|
||||||
|
#+BEGIN_EXPORT html
|
||||||
|
</div>
|
||||||
|
#+END_EXPORT
|
||||||
|
|
||||||
|
***** Filesystem formatting
|
||||||
|
Now that we got our partitions creates, let's go ahead and format them properly.
|
||||||
|
|
||||||
|
Starting with the ~boot~ partition first.
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
mkfs.vfat /dev/disk/by-id/VENDOR-ID-part1
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+BEGIN_EXPORT html
|
||||||
|
<div class="admonition warning">
|
||||||
|
<p class="admonition-title"><b>Warning</b></p>
|
||||||
|
#+END_EXPORT
|
||||||
|
At this sage, you're formatting a partition. Make sure you're pointing to the
|
||||||
|
partition and not your whole disk as in the previous section.
|
||||||
|
#+BEGIN_EXPORT html
|
||||||
|
</div>
|
||||||
|
#+END_EXPORT
|
||||||
|
|
||||||
|
Then our ~zfs~ partition, but we need to encrypt it first. So, we create the
|
||||||
|
Luks partition.
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
cryptsetup luksFormat /dev/disk/by-id/VENDOR-ID-part2
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
At this stage, stage we are done with the filesystem formatting and we need to
|
||||||
|
create the ~zfs~ pool. To do so, we need to mount the encrypted ~root~
|
||||||
|
filesystem; Luks.
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
cryptsetup open --type luks /dev/disk/by-id/VENDOR-ID-part2 crypt
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
This mounts the filesystem in =/dev/mapper/crypt=. We'll use that to create the pool.
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
zpool create -O mountpoint=none rpool /dev/mapper/crypt
|
||||||
|
zfs create -o mountpoint=legacy rpool/root
|
||||||
|
zfs create -o mountpoint=legacy rpool/root/nixos
|
||||||
|
zfs create -o mountpoint=legacy rpool/home
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
***** Filesystem mounting
|
||||||
|
After creating the filesystem, let's mount everything.
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
# Mounting filesystem
|
||||||
|
mount -t zfs rpool/root/nixos /mnt
|
||||||
|
mkdir /mnt/home
|
||||||
|
mkdir /mnt/boot
|
||||||
|
# Mounting home directory
|
||||||
|
mount -t zfs rpool/home /mnt/home
|
||||||
|
# Mounting boot partition
|
||||||
|
mount /dev/disk/by-id/VENDOR-ID-part1 /mnt/boot
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
***** Generating NixOS configuration
|
||||||
|
At this stage, we need a =nix= configuration to build our system from. I didn't
|
||||||
|
have any configuration to start from so I generated one.
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
nixos-generate-config --root /mnt
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
***** NixOS configuration
|
||||||
|
Due to the weird configuration we've had, we need to make a few adjustements to
|
||||||
|
the suggested configuration layed out in the docs.
|
||||||
|
|
||||||
|
The required configuration bits to be added to
|
||||||
|
=/mnt/etc/nixos/configuration.nix= are:
|
||||||
|
|
||||||
|
#+begin_src nix
|
||||||
|
boot.supportedFilesystems = [ "zfs" ];
|
||||||
|
# Make sure you set the networking.hostId option, which ZFS requires:
|
||||||
|
networking.hostId = "<random 8-digit hex string>";
|
||||||
|
# See https://nixos.org/nixos/manual/options.html#opt-networking.hostId for more.
|
||||||
|
|
||||||
|
# Use the GRUB 2 boot loader.
|
||||||
|
boot.loader.grub = {
|
||||||
|
enable = true;
|
||||||
|
version =2;
|
||||||
|
device = "nodev";
|
||||||
|
efiSupport = true;
|
||||||
|
enableCryptodisk = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.initrd.luks.devices = {
|
||||||
|
root = {
|
||||||
|
device = "/dev/disk/by-uuid/VENDOR-UUID-part2"; ## Use blkid to find this UUID
|
||||||
|
# Required even if we're not using LVM
|
||||||
|
preLVM = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
***** NixOS installation
|
||||||
|
If we're done with all of the configuration as described above, we should be
|
||||||
|
able to build a bootable system. Let's try that out by installing *NixOS*.
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
nixos-install
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
**** Conclusion
|
||||||
|
It took a bit of trial and error, and a loooooooot of mounting over and over
|
||||||
|
again. At the end, though, it wasn't as bad as I thought it would be. I'm still
|
||||||
|
trying to get myself familiarised with *NixOS* and the new way of doing things.
|
||||||
|
All in all, I would recommend trying *NixOS*, or the very least *Nix*.
|
||||||
|
|
||||||
** Revision Control :@revision_control:
|
** Revision Control :@revision_control:
|
||||||
*** DONE Git! First Steps... :git:
|
*** DONE Git! First Steps... :git:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
|
|
242
content/posts/nixos-on-encrypted-zfs.md
Normal file
242
content/posts/nixos-on-encrypted-zfs.md
Normal file
|
@ -0,0 +1,242 @@
|
||||||
|
+++
|
||||||
|
title = "NixOS on encrypted ZFS"
|
||||||
|
author = ["Elia el Lazkani"]
|
||||||
|
date = 2021-10-17
|
||||||
|
lastmod = 2021-10-17
|
||||||
|
tags = ["zfs", "encryption"]
|
||||||
|
categories = ["nix", "nixos"]
|
||||||
|
draft = false
|
||||||
|
+++
|
||||||
|
|
||||||
|
I wouldn't call myself a distro hopper. The decision of distribution is solely
|
||||||
|
based on requirements. I have requirements and I want the distribution to
|
||||||
|
fulfill them as much as possible. After 15 years, I know what I want and I go
|
||||||
|
and find it.
|
||||||
|
|
||||||
|
In this case, an unexpected project caught my eye. The idea is so radically
|
||||||
|
different that I wasn't actually searching for it this time. It is one of those
|
||||||
|
times where it found me first.
|
||||||
|
|
||||||
|
After looking into **Nix** and **NixOS**, I decided it is going to be my
|
||||||
|
distribution of choice on the desktop. I will use that as my test bed before
|
||||||
|
migrating all the serious work there. That's how I got my first taste of **NixOS**
|
||||||
|
outside of the deterministic virtualization layer and into the wild.
|
||||||
|
|
||||||
|
<!--more-->
|
||||||
|
|
||||||
|
|
||||||
|
## Requirements {#requirements}
|
||||||
|
|
||||||
|
Before installing any new system, I draftdown a list of requirements I would
|
||||||
|
need this system to run. These are things that are very hard to change on the
|
||||||
|
fly in the future without some serious work. Also, things that simply need to be
|
||||||
|
there in this day and age.
|
||||||
|
|
||||||
|
|
||||||
|
### Filesystem {#filesystem}
|
||||||
|
|
||||||
|
I'm a big fan of `zfs`. I've been running it on Linux, since the `openzfs`
|
||||||
|
project successfully ported it, with no issues. It's a solid choice for a
|
||||||
|
filesystem and I don't see a reason not to choose it.
|
||||||
|
|
||||||
|
Is it really a requirement ?
|
||||||
|
|
||||||
|
Well, yes. By now, `openzfs` should be accessible to all distributions but my
|
||||||
|
choice of distribution is not usually for the beginner user. I need to know
|
||||||
|
it's supported and documented. I can figure out the rest from there.
|
||||||
|
|
||||||
|
|
||||||
|
### Encryption {#encryption}
|
||||||
|
|
||||||
|
This is the first requirement, I always want encryption. The reason why I put it
|
||||||
|
second in the list is that I needed to talk about `zfs` first.
|
||||||
|
|
||||||
|
The `zfs` filesystem offers encryption. Unfortunately, my research have shown
|
||||||
|
that `zfs` might not encrypt some metadata. This might not be a big deal but the
|
||||||
|
choice of using Luks is there as well.
|
||||||
|
|
||||||
|
With Luks, we can encrypt the whole drive. So let's do that; Luks with `zfs` on top.
|
||||||
|
|
||||||
|
|
||||||
|
## NixOS {#nixos}
|
||||||
|
|
||||||
|
**NixOS** utilizes **Nix** to build you an OS from a configuration file. This
|
||||||
|
configuration file is written in the `nix` language. It is very analogous to
|
||||||
|
written an `Ansible` playbook but it builds an OS instead.
|
||||||
|
|
||||||
|
The idea sounded appealing to me. A good friend of mine, [setkeh](https://setkeh.com/), gave me a quick and
|
||||||
|
dirty overview, at first. That pushed me into doing more research of my own
|
||||||
|
where I found out that I can spawn off a `nix-shell` with whatever dependencies
|
||||||
|
I want without having them installed on my system. What a great concept for
|
||||||
|
development or even running applications you don't really want to run. `Java`
|
||||||
|
stuff for example.
|
||||||
|
|
||||||
|
Anyway, for all of these different reasons I have chosen **NixOS** to be the OS of
|
||||||
|
choice to go on the desktop.
|
||||||
|
|
||||||
|
|
||||||
|
## Installation {#installation}
|
||||||
|
|
||||||
|
After testing [**NixOS**](https://nixos.org/) in a VM a few times, I got `setkeh` on a conference
|
||||||
|
session and we dug into this.
|
||||||
|
|
||||||
|
|
||||||
|
### Filesystem partitioning {#filesystem-partitioning}
|
||||||
|
|
||||||
|
For the filesystem, we're going to create two partitions. We need one, `vfat`,
|
||||||
|
for the boot and another, `zfs`, for the rest of the filesystem.
|
||||||
|
|
||||||
|
<div class="admonition note">
|
||||||
|
<p class="admonition-title"><b>Note</b></p>
|
||||||
|
|
||||||
|
The assumption is that we're installing **NixOS** on an `EFI` enabled system.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
We can start by creating the first partition of `1GB`.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sgdisk -n3:1M:+1024M -t3:EF00 /dev/disk/by-id/VENDOR-ID
|
||||||
|
```
|
||||||
|
|
||||||
|
Followed by the rest of the filesystem.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sgdisk -n1:0:0 -t1:BF01 /dev/disk/by-id/VENDOR-ID
|
||||||
|
```
|
||||||
|
|
||||||
|
<div class="admonition note">
|
||||||
|
<p class="admonition-title"><b>Note</b></p>
|
||||||
|
|
||||||
|
It is usually easier to do the partitioning using `GParted`. Make sure that the
|
||||||
|
partitions are unformatted, if you do so.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="admonition warning">
|
||||||
|
<p class="admonition-title"><b>Warning</b></p>
|
||||||
|
|
||||||
|
Do **NOT** forget to enable the boot flag on the first partition or your system
|
||||||
|
will not boot.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
### Filesystem formatting {#filesystem-formatting}
|
||||||
|
|
||||||
|
Now that we got our partitions creates, let's go ahead and format them properly.
|
||||||
|
|
||||||
|
Starting with the `boot` partition first.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
mkfs.vfat /dev/disk/by-id/VENDOR-ID-part1
|
||||||
|
```
|
||||||
|
|
||||||
|
<div class="admonition warning">
|
||||||
|
<p class="admonition-title"><b>Warning</b></p>
|
||||||
|
|
||||||
|
At this sage, you're formatting a partition. Make sure you're pointing to the
|
||||||
|
partition and not your whole disk as in the previous section.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Then our `zfs` partition, but we need to encrypt it first. So, we create the
|
||||||
|
Luks partition.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cryptsetup luksFormat /dev/disk/by-id/VENDOR-ID-part2
|
||||||
|
```
|
||||||
|
|
||||||
|
At this stage, stage we are done with the filesystem formatting and we need to
|
||||||
|
create the `zfs` pool. To do so, we need to mount the encrypted `root`
|
||||||
|
filesystem; Luks.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cryptsetup open --type luks /dev/disk/by-id/VENDOR-ID-part2 crypt
|
||||||
|
```
|
||||||
|
|
||||||
|
This mounts the filesystem in `/dev/mapper/crypt`. We'll use that to create the pool.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
zpool create -O mountpoint=none rpool /dev/mapper/crypt
|
||||||
|
zfs create -o mountpoint=legacy rpool/root
|
||||||
|
zfs create -o mountpoint=legacy rpool/root/nixos
|
||||||
|
zfs create -o mountpoint=legacy rpool/home
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Filesystem mounting {#filesystem-mounting}
|
||||||
|
|
||||||
|
After creating the filesystem, let's mount everything.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Mounting filesystem
|
||||||
|
mount -t zfs rpool/root/nixos /mnt
|
||||||
|
mkdir /mnt/home
|
||||||
|
mkdir /mnt/boot
|
||||||
|
# Mounting home directory
|
||||||
|
mount -t zfs rpool/home /mnt/home
|
||||||
|
# Mounting boot partition
|
||||||
|
mount /dev/disk/by-id/VENDOR-ID-part1 /mnt/boot
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Generating NixOS configuration {#generating-nixos-configuration}
|
||||||
|
|
||||||
|
At this stage, we need a `nix` configuration to build our system from. I didn't
|
||||||
|
have any configuration to start from so I generated one.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
nixos-generate-config --root /mnt
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### NixOS configuration {#nixos-configuration}
|
||||||
|
|
||||||
|
Due to the weird configuration we've had, we need to make a few adjustements to
|
||||||
|
the suggested configuration layed out in the docs.
|
||||||
|
|
||||||
|
The required configuration bits to be added to
|
||||||
|
`/mnt/etc/nixos/configuration.nix` are:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
boot.supportedFilesystems = [ "zfs" ];
|
||||||
|
# Make sure you set the networking.hostId option, which ZFS requires:
|
||||||
|
networking.hostId = "<random 8-digit hex string>";
|
||||||
|
# See https://nixos.org/nixos/manual/options.html#opt-networking.hostId for more.
|
||||||
|
|
||||||
|
# Use the GRUB 2 boot loader.
|
||||||
|
boot.loader.grub = {
|
||||||
|
enable = true;
|
||||||
|
version =2;
|
||||||
|
device = "nodev";
|
||||||
|
efiSupport = true;
|
||||||
|
enableCryptodisk = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.initrd.luks.devices = {
|
||||||
|
root = {
|
||||||
|
device = "/dev/disk/by-uuid/VENDOR-UUID-part2"; ## Use blkid to find this UUID
|
||||||
|
# Required even if we're not using LVM
|
||||||
|
preLVM = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### NixOS installation {#nixos-installation}
|
||||||
|
|
||||||
|
If we're done with all of the configuration as described above, we should be
|
||||||
|
able to build a bootable system. Let's try that out by installing **NixOS**.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
nixos-install
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Conclusion {#conclusion}
|
||||||
|
|
||||||
|
It took a bit of trial and error, and a loooooooot of mounting over and over
|
||||||
|
again. At the end, though, it wasn't as bad as I thought it would be. I'm still
|
||||||
|
trying to get myself familiarised with **NixOS** and the new way of doing things.
|
||||||
|
All in all, I would recommend trying **NixOS**, or the very least **Nix**.
|
Loading…
Reference in a new issue