agenix
This commit is contained in:
parent
d16c7baa4a
commit
9241fe5e5c
30
README.md
30
README.md
|
@ -21,7 +21,7 @@ the unofficial NixOS wiki [Full Disk Encryption](https://nixos.wiki/wiki/Full_Di
|
||||||
gist](https://gist.github.com/martijnvermaat/76f2e24d0239470dd71050358b4d5134).
|
gist](https://gist.github.com/martijnvermaat/76f2e24d0239470dd71050358b4d5134).
|
||||||
|
|
||||||
We create a 1GiB EFI boot partition (`/dev/sda1`) and the rest will be our LUKS-encrypted volume:
|
We create a 1GiB EFI boot partition (`/dev/sda1`) and the rest will be our LUKS-encrypted volume:
|
||||||
```bash
|
```fish
|
||||||
# Create partition table
|
# Create partition table
|
||||||
parted /dev/sda -- mklabel gpt
|
parted /dev/sda -- mklabel gpt
|
||||||
|
|
||||||
|
@ -58,19 +58,35 @@ sda
|
||||||
└─vg-root ext4 1.0 nix
|
└─vg-root ext4 1.0 nix
|
||||||
```
|
```
|
||||||
|
|
||||||
### Installation
|
|
||||||
Whereas the [NixOS manual](https://nixos.org/manual/nixos/stable/index.html#sec-installation-manual-installing) mounts
|
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`:
|
the newly-created `nixos` partition to `/mnt`, we will follow the _tmpfs as root_ blogpost and mount `/mnt` as `tmpfs`:
|
||||||
```bash
|
```fish
|
||||||
mount -t tmpfs none /mnt
|
mount -t tmpfs none /mnt
|
||||||
mount --mkdir /dev/disk/by-label/BOOT /mnt/boot
|
mount --mkdir /dev/disk/by-label/BOOT /mnt/boot
|
||||||
mount --mkdir /dev/disk/by-label/nix /mnt/nix
|
mount --mkdir /dev/disk/by-label/nix /mnt/nix
|
||||||
mkdir -p /mnt/nix/persist/
|
mkdir -p /mnt/nix/persist/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Secrets
|
||||||
|
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.
|
||||||
|
|
||||||
|
To bootstrap a new system, we must first generate a host key manually using `ssh-keygen -A -f /mnt/nix/persist`
|
||||||
|
during installation. Then, on an existing system, add the new host's public key to `secrets.nix` and rekey all
|
||||||
|
secrets using `agenix --rekey`. Commit and push the changes and proceed below.
|
||||||
|
|
||||||
|
When managing secrets, the Keepass recovery key is used like so:
|
||||||
|
```fish
|
||||||
|
set AGE_KEY_FILE (mktemp); read -s > $AGE_KEY_FILE
|
||||||
|
agenix -i $AGE_KEY_FILE -e foo.age
|
||||||
|
```
|
||||||
|
|
||||||
|
### Installation
|
||||||
The remaining installation can be done (more or less) according to the [NixOS
|
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).
|
manual](https://nixos.org/manual/nixos/stable/index.html#sec-installation-manual-installing).
|
||||||
```bash
|
```fish
|
||||||
cd /mnt/nix
|
cd /mnt/nix
|
||||||
git clone https://git.caspervk.net/caspervk/nixos.git tmp
|
git clone https://git.caspervk.net/caspervk/nixos.git tmp
|
||||||
cd tmp/
|
cd tmp/
|
||||||
|
@ -78,10 +94,6 @@ nixos-generate-config --root /mnt --show-hardware-config
|
||||||
vim hosts/omega/hardware.nix
|
vim hosts/omega/hardware.nix
|
||||||
git add . # nix sometimes ignores files outside version control
|
git add . # nix sometimes ignores files outside version control
|
||||||
nixos-install --no-root-passwd --flake .#omega
|
nixos-install --no-root-passwd --flake .#omega
|
||||||
|
|
||||||
# Make sure to set a password
|
|
||||||
mkpasswd > /mnt/nix/persist/passwordfile
|
|
||||||
chmod 400 /mnt/nix/persist/passwordfile
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Hardware Configuration
|
### Hardware Configuration
|
||||||
|
@ -94,7 +106,7 @@ enough](https://sourcegraph.com/search?q=context%3Aglobal+repo%3A%5Egithub%5C.co
|
||||||
|
|
||||||
|
|
||||||
## Useful Commands
|
## Useful Commands
|
||||||
```bash
|
```fish
|
||||||
# upgrade system
|
# upgrade system
|
||||||
sudo nixos-rebuild switch --flake .
|
sudo nixos-rebuild switch --flake .
|
||||||
|
|
||||||
|
|
65
flake.lock
65
flake.lock
|
@ -1,5 +1,30 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"agenix": {
|
||||||
|
"inputs": {
|
||||||
|
"darwin": [],
|
||||||
|
"home-manager": [
|
||||||
|
"home-manager"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1707830867,
|
||||||
|
"narHash": "sha256-PAdwm5QqdlwIqGrfzzvzZubM+FXtilekQ/FA0cI49/o=",
|
||||||
|
"owner": "ryantm",
|
||||||
|
"repo": "agenix",
|
||||||
|
"rev": "8cb01a0e717311680e0cbca06a76cbceba6f3ed6",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "ryantm",
|
||||||
|
"repo": "agenix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"home-manager": {
|
"home-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
@ -28,11 +53,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1708451036,
|
"lastModified": 1708591310,
|
||||||
"narHash": "sha256-tgZ38NummEdnXvxj4D0StHBzXgceAw8CptytHljH790=",
|
"narHash": "sha256-8mQGVs8JccWTnORgoLOTh9zvf6Np+x2JzhIc+LDcJ9s=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "517601b37c6d495274454f63c5a483c8e3ca6be1",
|
"rev": "0e0e9669547e45ea6cca2de4044c1a384fd0fe55",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -79,11 +104,11 @@
|
||||||
},
|
},
|
||||||
"nixos-hardware": {
|
"nixos-hardware": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1708091350,
|
"lastModified": 1708594753,
|
||||||
"narHash": "sha256-o28BJYi68qqvHipT7V2jkWxDiMS1LF9nxUsou+eFUPQ=",
|
"narHash": "sha256-c/gH7iXS/IYH9NrFOT+aJqTq+iEBkvAkpWuUHGU3+f0=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixos-hardware",
|
"repo": "nixos-hardware",
|
||||||
"rev": "106d3fec43bcea19cb2e061ca02531d54b542ce3",
|
"rev": "3f7d0bca003eac1a1a7f4659bbab9c8f8c2a0958",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -95,11 +120,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1708294118,
|
"lastModified": 1708566995,
|
||||||
"narHash": "sha256-evZzmLW7qoHXf76VCepvun1esZDxHfVRFUJtumD7L2M=",
|
"narHash": "sha256-e/THimsoxxMAHSbwMKov5f5Yg+utTj6XVGEo24Lhx+0=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e0da498ad77ac8909a980f07eff060862417ccf7",
|
"rev": "3cb4ae6689d2aa3f363516234572613b31212b78",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -111,11 +136,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1708296515,
|
"lastModified": 1708655239,
|
||||||
"narHash": "sha256-FyF489fYNAUy7b6dkYV6rGPyzp+4tThhr80KNAaF/yY=",
|
"narHash": "sha256-ZrP/yACUvDB+zbqYJsln4iwotbH6CTZiTkANJ0AgDv4=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "b98a4e1746acceb92c509bc496ef3d0e5ad8d4aa",
|
"rev": "cbc4211f0afffe6dfd2478a62615dd5175a13f9a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -127,6 +152,7 @@
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
|
"agenix": "agenix",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"home-manager-unstable": "home-manager-unstable",
|
"home-manager-unstable": "home-manager-unstable",
|
||||||
"impermanence": "impermanence",
|
"impermanence": "impermanence",
|
||||||
|
@ -135,6 +161,21 @@
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"nixpkgs-unstable": "nixpkgs-unstable"
|
"nixpkgs-unstable": "nixpkgs-unstable"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
impermanence = {
|
impermanence = {
|
||||||
url = "github:nix-community/impermanence";
|
url = "github:nix-community/impermanence";
|
||||||
};
|
};
|
||||||
|
agenix = {
|
||||||
|
url = "github:ryantm/agenix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs"; # use the same nixpkgs as the system
|
||||||
|
inputs.home-manager.follows = "home-manager"; # use the same home-manager as the system
|
||||||
|
inputs.darwin.follows = ""; # don't download dawrin dependencies
|
||||||
|
};
|
||||||
nix-index-database = {
|
nix-index-database = {
|
||||||
url = "github:nix-community/nix-index-database";
|
url = "github:nix-community/nix-index-database";
|
||||||
inputs.nixpkgs.follows = "nixpkgs"; # use the same nixpkgs as the system
|
inputs.nixpkgs.follows = "nixpkgs"; # use the same nixpkgs as the system
|
||||||
|
|
21
modules/base/agenix.nix
Normal file
21
modules/base/agenix.nix
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{ agenix, pkgs, ... }: {
|
||||||
|
# Agenix manages the deployment of secrets by public-key encrypting them to
|
||||||
|
# each system's ssh host key. See the README for more information.
|
||||||
|
# https://github.com/ryantm/agenix
|
||||||
|
# https://nixos.wiki/wiki/Comparison_of_secret_managing_schemes
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
agenix.nixosModules.default
|
||||||
|
];
|
||||||
|
|
||||||
|
# Agenix attempts to decrypt secrets before impermanence symlinks the ssh
|
||||||
|
# host key. Refer directly to the key on the persistent partition, which is
|
||||||
|
# mounted in stage 1 of the boot process, before agenix runs.
|
||||||
|
# https://github.com/ryantm/agenix/issues/45#issuecomment-901383985
|
||||||
|
age.identityPaths = [ "/nix/persist/etc/ssh/ssh_host_ed25519_key" ];
|
||||||
|
|
||||||
|
# `agenix` cli tool
|
||||||
|
environment.systemPackages = [
|
||||||
|
agenix.packages.${pkgs.system}.default
|
||||||
|
];
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
{ ... }: {
|
{ ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
|
./agenix.nix
|
||||||
./docker.nix
|
./docker.nix
|
||||||
./fish.nix
|
./fish.nix
|
||||||
./git.nix
|
./git.nix
|
||||||
|
|
|
@ -1,22 +1,16 @@
|
||||||
{ pkgs, ... }: {
|
{ config, pkgs, ... }: {
|
||||||
users = {
|
users = {
|
||||||
# Don't allow imperative modifications to users (incompatible with impermanence)
|
# Don't allow imperative modifications to users (incompatible with impermanence)
|
||||||
mutableUsers = false;
|
mutableUsers = false;
|
||||||
|
|
||||||
users = {
|
users = {
|
||||||
root = {
|
root = {
|
||||||
# TODO: The passwordfile is manually generated during the initial setup
|
hashedPasswordFile = config.age.secrets.users-hashed-password-file.path;
|
||||||
# to avoid (hashed) secrets in the public git repo. It should replaced
|
|
||||||
# with a proper secret management scheme, such as agenix.
|
|
||||||
hashedPasswordFile = "/nix/persist/passwordfile";
|
|
||||||
};
|
};
|
||||||
caspervk = {
|
caspervk = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
description = "Casper V. Kristensen";
|
description = "Casper V. Kristensen";
|
||||||
# TODO: The hashedPasswordFile is manually generated during the initial
|
hashedPasswordFile = config.age.secrets.users-hashed-password-file.path;
|
||||||
# setup to avoid (hashed) secrets in the public git repo. It should
|
|
||||||
# replaced with a proper secret management scheme, such as agenix.
|
|
||||||
hashedPasswordFile = "/nix/persist/passwordfile";
|
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"wheel" # allows sudo
|
"wheel" # allows sudo
|
||||||
"video" # allows controlling brightness
|
"video" # allows controlling brightness
|
||||||
|
@ -27,4 +21,11 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
age.secrets.users-hashed-password-file = {
|
||||||
|
file = ../../secrets/users-hashed-password-file.age;
|
||||||
|
mode = "400";
|
||||||
|
owner = "root";
|
||||||
|
group = "root";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
23
secrets/secrets.nix
Normal file
23
secrets/secrets.nix
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# This file is NOT imported into the NixOS configuration. It is only used for
|
||||||
|
# the agenix CLI tool to know which public keys to use for encryption. See the
|
||||||
|
# README for more information.
|
||||||
|
# https://github.com/ryantm/agenix
|
||||||
|
|
||||||
|
let
|
||||||
|
# Get a system's public key using:
|
||||||
|
# > cat /etc/ssh/ssh_host_ed25519_key.pub
|
||||||
|
# If you change or add a key, all secrets need to be `agenix --rekey`'ed.
|
||||||
|
mu = "todo";
|
||||||
|
omega = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILvFN4vnqPX31+4/ZJxOJ7/bSUEu2xB6ovezPQjLm13H root@omega";
|
||||||
|
tor = "todo";
|
||||||
|
zeta = "todo";
|
||||||
|
# Recovery and management key from Keepass. Used like so:
|
||||||
|
# > set AGE_KEY_FILE (mktemp); read -s > $AGE_KEY_FILE
|
||||||
|
# > agenix -i $AGE_KEY_FILE -e foo.age
|
||||||
|
recovery = "age1rd6hhd724s3r9xe4gfuy38rl0xfu8c7pkuefsrdwqfcknujzecyqz7ldyj";
|
||||||
|
|
||||||
|
all = [ omega recovery ];
|
||||||
|
in
|
||||||
|
{
|
||||||
|
"users-hashed-password-file.age".publicKeys = all;
|
||||||
|
}
|
7
secrets/users-hashed-password-file.age
Normal file
7
secrets/users-hashed-password-file.age
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 fY+XUg ThWnidSUv20sqdMebPW0aV512ascEV4WyDia72vhTnI
|
||||||
|
fbFAnyqqqpp9fEct2EiLG1wWw//U8kWcpf0QnbSh33Y
|
||||||
|
-> X25519 ZbC+v0St7P+W/AHq1Afst7ylmZUFA7OIhiElfexTHgg
|
||||||
|
2DbCqyjULhmDji3E1HrPuO8WW74dIia1GFOSCaeGliU
|
||||||
|
--- 6W7LaM4dc6tJONcmtVAwhI/NcOE8EUYPrg75K6Qpynw
|
||||||
|
%?ó4k=/ýä_ƒ<5F>½a#]Éào>Ÿ¬¨tVÆ°EªW“õµŽåRþ÷~¾8Ñ;më¬"˜€&˹ÏGŠ]ïsAN¦pÀŸõW²ƒŽÅNKø„Ɖ˜™p¿ƒªóP$8e
|
Loading…
Reference in a new issue