add usb-stick nixos article and fixed some image issues

master
Ingolf Wagner 2022-10-19 20:56:23 +02:00
parent 48ed8f0042
commit 7433e20e01
Signed by: palo
GPG Key ID: 76BF5F1928B9618B
16 changed files with 368 additions and 40 deletions

0
.hugo_build.lock Normal file
View File

36
Taskfile.yml Normal file
View File

@ -0,0 +1,36 @@
version: '3'
vars:
SERVER: robi.private
SERVER_PATH: /srv/www/tech
tasks:
server:
deps: [assets]
cmds: ["hugo serve"]
build:
deps: [assets]
cmds: ["hugo"]
assets:
deps: [css]
css:
cmds:
- lessc src/lessc/page/main.less static/css/main.css
publish:
deps: [assets, build]
cmds:
- |
rsync \
--recursive \
--compress \
--checksum \
--verbose \
--human-readable \
--partial --progress \
--protect-args \
--delete-after \
public/ {{.SERVER}}:{{.SERVER_PATH}}/

View File

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

@ -0,0 +1,233 @@
---
title: "nixos on encrypted USB stick"
date: 2022-10-19T10:00:00+02:00
tags:
- NixOS
- Bootable
- USB
summary: >
In this article I will describe how to
create an encrypted bootable USB stick
running NixOS.
---
How to Create and update an bootable Linux USB stick, which is encrypted
is quite easy and has some use cases.
* As ultimate backup
* As a holiday tool
* For schools
# Requirments
## USB Stick
You need an USB stick with at least 64GB otherwise major updates might get problematic.
The USB stick, which should hold the system, will be `/dev/sdb`.
You can plugin the usb stick and run `dmesg` to find out which device we are using
# Step by Step Guide
Here are the steps I use to create my encrypted USB sticks running NixOS.
## format and create gpt partition table
```
┌────────────────────────────────┐
│USB-stick │
│ ┌──────────────────────────────┤
│ │ /dev/sda1 boot1 (MBR 1MB) │
│ ├──────────────────────────────┤
│ │ /dev/sda2 boot2 (EFI 511MB) │
│ ├──────────────────────────────┤
│ │ │
│ │ /dev/sda3 root (ext4 > 64GB) │
│ │ (encrypted) │
└─┴──────────────────────────────┘
```
> We use 511 MB for the boot partition, but you might want to increas this partition,
> if you want to place bootable ISOs on that partiton you want to boot instead of your NixOS system.
> We create an EFI partition as well a 1MB MBR partiton to make the stick boot
> on all kinds of computers.
I always delete all partitions using `fdisk` before starting repartitioning.
Than I start with the partitioning.
```shell
parted /dev/sdb -- mklabel gpt
parted /dev/sdb -- mkpart no-fs 1MB 2MB
parted /dev/sdb -- set 1 bios_grub on
parted /dev/sdb -- mkpart ESP fat32 2MiB 512MiB
parted /dev/sdb -- set 2 boot on
parted /dev/sdb -- mkpart primary 512MiB 100%
```
It most likely is not necesary but to be sure, I unplug and plug the USB device again
to be sure the new partiton table will be used.
## create and encrypt partition
```shell
cryptsetup luksFormat /dev/sdb3
cryptsetup luksOpen /dev/sdb3 root-enc
```
This will be the password you have to type in every time you boot the USB Stick.
## create boot partitions
```shell
mkfs.fat -F 32 -n boot /dev/sdb2
mkfs.ext4 -L root /dev/mapper/root-enc
```
## prepare installation
We have to mount the created partitons.
```shell
mount /dev/mapper/root-enc /mnt
mkdir /mnt/boot && mount /dev/sdb2 /mnt/boot
```
And generate inital configuration files.
```shell
nixos-generate-config --root /mnt
```
Now you can update `configuration.nix`
before installation.
You can `hardware-configuration.nix` edit as too,
but usally that is not necessary.
> don't forget to set your ssh key in `users.users.<name>.openssh.authorizedKeys.keys`
> und `users.users.<name>.openssh.authorizedKeys.keyFiles`
I usually have also these configurations set
```
environment.systemPackages = with pkgs; [
vim
wget
htop
silver-searcher
iotop
];
environment.extraInit = ''
# use vi shortcuts
# ----------------
set -o vi
EDITOR=vim
'';
```
These options have to be added to make it bootable and to start it with qemu-kvm (See [Update stick using qemu-kvm](#update-stick-using-qemu-kvm))
```
boot.loader.grub.enable = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.device = "/dev/sdb"; # todo : change me once the system booted
boot.loader.grub.efiInstallAsRemovable = true;
boot.tmpOnTmpfs = true;
```
You most likely have to disable these parameters
```
boot.loader.systemd-boot.enable = false;
boot.loader.efi.canTouchEfiVariables = false;
```
## Install system
```shell
nixos-install --root /mnt
```
## Unmount everything
You most likely don't want to restart your host machine, so you have to unmount everything manually
```
umount /mnt/boot
umount /mnt
cryptsetup luksClose /dev/mapper/root-enc
```
You are able to plug the USB stick in a computer now and boot from it and you
root partition is encrypted.
# Update stick using qemu-kvm
To run frequent updates, it might be a hassle to boot a dedicated machine to access these updates.
This is why I use `qemu` to start the machine and update the machine via [colmena](https://colmena.cli.rs/unstable/reference/)
which my prefered NixOS provisioning system. Of course your favorit provisioning tool will work as well.
```
┌────┬─────────────────────────────────────┐
│host│ │
├────┘ │
│ │ ┌───────────┐
│ colmena /dev/sdb ◄─────┬────────────┼────┤ usb-stick │
│ │ │ │ └───────────┘
│ │ │ │
│ │ ┌───────────────┴─┬────────┐ │
│ │ │qemu-kvm /dev/sdb│ │ │
│ │ ├─────────────────┘ │ │
│ │ │ │ │
│ └────────┤► sshd ───────┐ │ │
│ │ ▼ │ │
│ │ nixos-rebuild switch │ │
│ │ │ │
│ └──────────────────────────┘ │
│ │
└──────────────────────────────────────────┘
```
To run `qemu-kvm` on you machine, you need these options in your host `configuration.nix`.
```
virtualisation.libvirtd.enable = true;
users.users.mainUser.extraGroups = [ "libvirtd" ];
environment.systemPackages = [
pkgs.qemu_kvm
pkgs.virt-manager
];
```
To start the machine you simple have to run this command:
```shell
sudo qemu-kvm \
-m 4G \
-drive file=/dev/sdb,format=raw,index=0,media=disk \
-net user,hostfwd=tcp:127.0.0.1:2222-:22 \
-net nic
```
![screenshot1.png](../images/screenshot1.png)
Once you unlocked the root partition you should be able to access the guest system using
```
ssh root@localhost -p2222
```
{{% content-big %}}
![screenshot2.png](../images/screenshot2.png)
{{% /content-big %}}
So you should be able to update you usb stick with the comfort of you normal desktop setup.
# further inspirations
* [Yubikey based Full Disk Encryption (NixOS Wiki)](https://nixos.wiki/wiki/Yubikey_based_Full_Disk_Encryption_(FDE)_on_NixOS)
* [Using LUKS and Yubikey](https://github.com/sgillespie/nixos-yubikey-luks)

View File

@ -108,7 +108,7 @@ You can have multiple computers which are reachable from the internet
but for this example we only have one.
{{< card >}}
{{<figure src="/nixos/tinc/3computers.svg" width=100% >}}
{{<figure src="../images/3computers.svg" width=100% >}}
{{< /card >}}
Here is the `configuration.nix`.
@ -235,7 +235,7 @@ It can be resolved by using the `tincSubnet` parameter,
to configure sub-network routing.
{{< card >}}
{{<figure src="/nixos/tinc/2subnets.svg" width=100% >}}
{{<figure src="../images/2subnets.svg" width=100% >}}
{{< /card >}}
Achieving this is very simple,

42
flake.lock Normal file
View File

@ -0,0 +1,42 @@
{
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1666171135,
"narHash": "sha256-+0AIbPDd24ZVjZgFobJH3uuJuyLVZjiH0oQNb01hyWE=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "5720791e7fcdcc89834732e11848d73151356966",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

48
flake.nix Normal file
View File

@ -0,0 +1,48 @@
{
description = "my website";
inputs.nixpkgs.url = "github:nixos/nixpkgs";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, nixpkgs, flake-utils }:
(flake-utils.lib.eachDefaultSystem (system:
let pkgs = nixpkgs.legacyPackages.${system};
in {
# nix develop
devShell = pkgs.mkShell {
buildInputs = with pkgs; [ hugo lessc rake go-task feh ion inotify-tools ];
};
# nix run
apps.default = self.apps.${system}.server;
# nix run ".#server"
apps.server = {
type = "app";
program = toString (pkgs.writers.writeBash "server" ''
set -e
set -o pipefail
PATH=${
pkgs.lib.makeBinPath [ pkgs.lessc pkgs.go-task pkgs.ion pkgs.hugo ]
}
task server
'');
};
# nix run ".#publish"
apps.publish = {
type = "app";
program = toString (pkgs.writers.writeBash "publish" ''
set -e
set -o pipefail
PATH=${
pkgs.lib.makeBinPath [ pkgs.lessc pkgs.go-task pkgs.ion pkgs.hugo pkgs.rsync pkgs.openssh ]
}
task publish
''
);
};
}));
}

View File

@ -1,21 +0,0 @@
nwdiag {
internet [shape = cloud];
internet -- Gibson [address = "my.awesome.dns.com"]
network private {
address = "10.1.1.0/24";
Gibson [address = "10.1.1.1"];
Hackbardt [address = "10.1.1.2"];
HAL [address = "10.1.1.3"];
}
network "private (subnet)" {
Hackbardt [address = "10.2.2.0/24"];
HAL [address = "10.2.3.0/24"];
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -1,16 +0,0 @@
nwdiag {
internet [shape = cloud];
internet -- Gibson [address = "my.awesome.dns.com"]
network private {
address = "10.1.1.0/24";
Gibson [address = "10.1.1.1"];
Hackbardt [address = "10.1.1.2"];
HAL [address = "10.1.1.3"];
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

View File

@ -1,6 +1,7 @@
@font-normal: ~"'Roboto', sans-serif";
@font-code: ~"'Inconsolata', monospace";
//@font-code: ~"'Inconsolata', monospace";
@font-code: ~"monospace"; // because diagrams look strange
@font-header: ~"'Roboto', sans-serif";
//@font-header: ~"'Zilla Slab', serif";

View File

@ -110,3 +110,8 @@ a:hover {
}
// images
img {
width: 100%;
}