mirror of
https://github.com/Swarsel/.dotfiles.git
synced 2025-12-06 09:07:21 +01:00
feat: option for unencrypted Impermanence
This commit is contained in:
parent
e4d507d5c1
commit
43e13334c0
8 changed files with 216 additions and 196 deletions
|
|
@ -1285,6 +1285,7 @@ My work machine. Built for more security, this is the gold standard of my config
|
||||||
hasFingerprint = true;
|
hasFingerprint = true;
|
||||||
impermanence = false;
|
impermanence = false;
|
||||||
isBtrfs = true;
|
isBtrfs = true;
|
||||||
|
isCrypted = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
home-manager.users.swarsel.swarselsystems = {
|
home-manager.users.swarsel.swarselsystems = {
|
||||||
|
|
@ -1612,102 +1613,6 @@ My server setup was originally built on Proxmox VE; back when I started, I creat
|
||||||
|
|
||||||
I have removed most of the machines from this section. What remains are some hosts that I have deployed on OCI (mostly sync for medium-important data) and one other machine that I left for now as a reference.
|
I have removed most of the machines from this section. What remains are some hosts that I have deployed on OCI (mostly sync for medium-important data) and one other machine that I left for now as a reference.
|
||||||
|
|
||||||
**** Toto (QEMU VM)
|
|
||||||
|
|
||||||
#+begin_src nix :tangle hosts/nixos/toto/default.nix
|
|
||||||
{ self, inputs, outputs, config, pkgs, lib, ... }:
|
|
||||||
let
|
|
||||||
profilesPath = "${self}/profiles";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
inputs.disko.nixosModules.disko
|
|
||||||
"${self}/hosts/nixos/toto/disk-config.nix"
|
|
||||||
{
|
|
||||||
_module.args = {
|
|
||||||
withSwap = false;
|
|
||||||
withImpermanence = true;
|
|
||||||
withEncryption = false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
./hardware-configuration.nix
|
|
||||||
|
|
||||||
inputs.sops-nix.nixosModules.sops
|
|
||||||
|
|
||||||
"${profilesPath}/optional/nixos/autologin.nix"
|
|
||||||
"${profilesPath}/common/nixos/settings.nix"
|
|
||||||
"${profilesPath}/common/nixos/home-manager.nix"
|
|
||||||
"${profilesPath}/common/nixos/xserver.nix"
|
|
||||||
"${profilesPath}/common/nixos/users.nix"
|
|
||||||
"${profilesPath}/common/nixos/sops.nix"
|
|
||||||
"${profilesPath}/server/nixos/ssh.nix"
|
|
||||||
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
{
|
|
||||||
home-manager.users.swarsel.imports = [
|
|
||||||
inputs.sops-nix.homeManagerModules.sops
|
|
||||||
"${profilesPath}/common/home/settings.nix"
|
|
||||||
"${profilesPath}/common/home/sops.nix"
|
|
||||||
"${profilesPath}/common/home/ssh.nix"
|
|
||||||
|
|
||||||
] ++ (builtins.attrValues outputs.homeManagerModules);
|
|
||||||
}
|
|
||||||
] ++ (builtins.attrValues outputs.nixosModules);
|
|
||||||
|
|
||||||
|
|
||||||
nixpkgs = {
|
|
||||||
overlays = [ outputs.overlays.default ];
|
|
||||||
config = {
|
|
||||||
allowUnfree = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
curl
|
|
||||||
git
|
|
||||||
gnupg
|
|
||||||
rsync
|
|
||||||
ssh-to-age
|
|
||||||
sops
|
|
||||||
vim
|
|
||||||
just
|
|
||||||
];
|
|
||||||
|
|
||||||
system.stateVersion = lib.mkForce "23.05";
|
|
||||||
|
|
||||||
boot = {
|
|
||||||
loader.systemd-boot.enable = lib.mkForce true;
|
|
||||||
loader.efi.canTouchEfiVariables = true;
|
|
||||||
supportedFilesystems = [ "btrfs" ];
|
|
||||||
kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
networking = {
|
|
||||||
hostName = "toto";
|
|
||||||
firewall.enable = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
swarselsystems = {
|
|
||||||
wallpaper = self + /wallpaper/lenovowp.png;
|
|
||||||
impermanence = true;
|
|
||||||
isBtrfs = false;
|
|
||||||
initialSetup = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
home-manager.users.swarsel.swarselsystems = {
|
|
||||||
isLaptop = false;
|
|
||||||
isNixos = true;
|
|
||||||
isBtrfs = false;
|
|
||||||
flakePath = "/home/swarsel/.dotfiles";
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
**** Sync (OCI)
|
**** Sync (OCI)
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: h:4c5febb0-fdf6-44c5-8d51-7ea0f8930abf
|
:CUSTOM_ID: h:4c5febb0-fdf6-44c5-8d51-7ea0f8930abf
|
||||||
|
|
@ -1822,6 +1727,109 @@ This machine mainly acts as an external sync helper. It manages the following th
|
||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Utility hosts
|
*** Utility hosts
|
||||||
|
**** Toto (Physical/VM)
|
||||||
|
|
||||||
|
This is a slim setup for developing base configuration.
|
||||||
|
|
||||||
|
#+begin_src nix :tangle hosts/nixos/toto/default.nix
|
||||||
|
{ self, inputs, outputs, config, pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
profilesPath = "${self}/profiles";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
inputs.disko.nixosModules.disko
|
||||||
|
"${self}/hosts/nixos/toto/disk-config.nix"
|
||||||
|
{
|
||||||
|
_module.args = {
|
||||||
|
withSwap = true;
|
||||||
|
swapSize = "8";
|
||||||
|
rootDisk = "/dev/vda";
|
||||||
|
withImpermanence = true;
|
||||||
|
withEncryption = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
./hardware-configuration.nix
|
||||||
|
|
||||||
|
inputs.sops-nix.nixosModules.sops
|
||||||
|
inputs.impermanence.nixosModules.impermanence
|
||||||
|
|
||||||
|
"${profilesPath}/optional/nixos/autologin.nix"
|
||||||
|
"${profilesPath}/common/nixos/settings.nix"
|
||||||
|
"${profilesPath}/common/nixos/home-manager.nix"
|
||||||
|
"${profilesPath}/common/nixos/xserver.nix"
|
||||||
|
"${profilesPath}/common/nixos/users.nix"
|
||||||
|
"${profilesPath}/common/nixos/impermanence.nix"
|
||||||
|
"${profilesPath}/common/nixos/sops.nix"
|
||||||
|
"${profilesPath}/server/nixos/ssh.nix"
|
||||||
|
|
||||||
|
inputs.home-manager.nixosModules.home-manager
|
||||||
|
{
|
||||||
|
home-manager.users.swarsel.imports = [
|
||||||
|
inputs.sops-nix.homeManagerModules.sops
|
||||||
|
"${profilesPath}/common/home/settings.nix"
|
||||||
|
"${profilesPath}/common/home/sops.nix"
|
||||||
|
"${profilesPath}/common/home/ssh.nix"
|
||||||
|
|
||||||
|
] ++ (builtins.attrValues outputs.homeManagerModules);
|
||||||
|
}
|
||||||
|
] ++ (builtins.attrValues outputs.nixosModules);
|
||||||
|
|
||||||
|
|
||||||
|
nixpkgs = {
|
||||||
|
overlays = [ outputs.overlays.default ];
|
||||||
|
config = {
|
||||||
|
allowUnfree = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
curl
|
||||||
|
git
|
||||||
|
gnupg
|
||||||
|
rsync
|
||||||
|
ssh-to-age
|
||||||
|
sops
|
||||||
|
vim
|
||||||
|
just
|
||||||
|
];
|
||||||
|
|
||||||
|
system.stateVersion = lib.mkForce "23.05";
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
loader.systemd-boot.enable = lib.mkForce true;
|
||||||
|
loader.efi.canTouchEfiVariables = true;
|
||||||
|
supportedFilesystems = [ "btrfs" ];
|
||||||
|
kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
hostName = "toto";
|
||||||
|
firewall.enable = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
swarselsystems = {
|
||||||
|
wallpaper = self + /wallpaper/lenovowp.png;
|
||||||
|
impermanence = true;
|
||||||
|
isBtrfs = true;
|
||||||
|
isCrypted = false;
|
||||||
|
initialSetup = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
home-manager.users.swarsel.swarselsystems = {
|
||||||
|
isLaptop = false;
|
||||||
|
isNixos = true;
|
||||||
|
isBtrfs = true;
|
||||||
|
flakePath = "/home/swarsel/.dotfiles";
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#+end_src
|
||||||
|
|
||||||
**** drugstore (ISO)
|
**** drugstore (ISO)
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: h:8583371d-5d47-468b-84ba-210aad7e2c90
|
:CUSTOM_ID: h:8583371d-5d47-468b-84ba-210aad7e2c90
|
||||||
|
|
@ -1990,7 +1998,7 @@ This is the "reference implementation" of a setup that runs without NixOS, only
|
||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
**** ChaosTheatre (Demo)
|
**** ChaosTheatre (Demo Physical/VM)
|
||||||
|
|
||||||
This is just a demo host. It applies all the configuration found in the common parts of the flake, but disables all secrets-related features (as they would not work without the proper SSH keys).
|
This is just a demo host. It applies all the configuration found in the common parts of the flake, but disables all secrets-related features (as they would not work without the proper SSH keys).
|
||||||
|
|
||||||
|
|
@ -2840,11 +2848,9 @@ This program sets up a new NixOS host.
|
||||||
temp=$1
|
temp=$1
|
||||||
;;
|
;;
|
||||||
--impermanence)
|
--impermanence)
|
||||||
shift
|
|
||||||
persist_dir="/persist"
|
persist_dir="/persist"
|
||||||
;;
|
;;
|
||||||
--encryption)
|
--encryption)
|
||||||
shift
|
|
||||||
disk_encryption=1
|
disk_encryption=1
|
||||||
;;
|
;;
|
||||||
--debug)
|
--debug)
|
||||||
|
|
@ -2984,6 +2990,7 @@ This program sets up a new NixOS host.
|
||||||
|
|
||||||
if [ -n "$persist_dir" ]; then
|
if [ -n "$persist_dir" ]; then
|
||||||
$ssh_root_cmd "cp -r /home/$target_user/.dotfiles $persist_dir/.dotfiles || true"
|
$ssh_root_cmd "cp -r /home/$target_user/.dotfiles $persist_dir/.dotfiles || true"
|
||||||
|
$ssh_root_cmd "cp -r /home/$target_user/.ssh $persist_dir/.ssh || true"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if yes_or_no "Do you want to rebuild immediately?"; then
|
if yes_or_no "Do you want to rebuild immediately?"; then
|
||||||
|
|
@ -3566,6 +3573,7 @@ I usually use =mutableUsers = false= in my NixOS configuration. However, on a ne
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
};
|
};
|
||||||
|
options.swarselsystems.isCrypted = lib.mkEnableOption "uses full disk encryption";
|
||||||
options.swarselsystems.isPublic = lib.mkEnableOption "is a public machine (no secrets)";
|
options.swarselsystems.isPublic = lib.mkEnableOption "is a public machine (no secrets)";
|
||||||
options.swarselsystems.initialSetup = lib.mkEnableOption "initial setup (no sops keys available)";
|
options.swarselsystems.initialSetup = lib.mkEnableOption "initial setup (no sops keys available)";
|
||||||
options.swarselsystems.server.enable = lib.mkEnableOption "is a server machine";
|
options.swarselsystems.server.enable = lib.mkEnableOption "is a server machine";
|
||||||
|
|
@ -4957,7 +4965,7 @@ I use sops-nix to handle secrets that I want to have available on my machines at
|
||||||
{
|
{
|
||||||
sops = lib.mkIf (!config.swarselsystems.isPublic) {
|
sops = lib.mkIf (!config.swarselsystems.isPublic) {
|
||||||
|
|
||||||
age.sshKeyPaths = mkIfElse config.swarselsystems.isBtrfs [ "/persist/.ssh/sops" ] [ "${config.users.users.swarsel.home}/.ssh/sops" "/etc/ssh/ssh_host_ed25519_key" ];
|
age.sshKeyPaths = mkIfElse config.swarselsystems.isBtrfs [ "/persist/.ssh/sops" "/persist/.ssh/ssh_host_ed25519_key" ] [ "${config.users.users.swarsel.home}/.ssh/sops" "/etc/ssh/ssh_host_ed25519_key" ];
|
||||||
defaultSopsFile = mkIfElse config.swarselsystems.isBtrfs "/persist/.dotfiles/secrets/general/secrets.yaml" "${config.users.users.swarsel.home}/.dotfiles/secrets/general/secrets.yaml";
|
defaultSopsFile = mkIfElse config.swarselsystems.isBtrfs "/persist/.dotfiles/secrets/general/secrets.yaml" "${config.users.users.swarsel.home}/.dotfiles/secrets/general/secrets.yaml";
|
||||||
|
|
||||||
validateSopsFiles = false;
|
validateSopsFiles = false;
|
||||||
|
|
@ -5488,6 +5496,15 @@ Normally, doing that also resets the lecture that happens on the first use of =s
|
||||||
|
|
||||||
#+begin_src nix :tangle profiles/common/nixos/impermanence.nix
|
#+begin_src nix :tangle profiles/common/nixos/impermanence.nix
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
mkIfElse = p: yes: no: if p then yes else no;
|
||||||
|
mkIfElseList = p: yes: no: lib.mkMerge [
|
||||||
|
(lib.mkIf p yes)
|
||||||
|
(lib.mkIf (!p) no)
|
||||||
|
];
|
||||||
|
mapperTarget = mkIfElse config.swarselsystems.isCrypted "/dev/mapper/cryptroot" "/dev/disk/by-label/nixos";
|
||||||
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
security.sudo.extraConfig = lib.mkIf config.swarselsystems.impermanence ''
|
security.sudo.extraConfig = lib.mkIf config.swarselsystems.impermanence ''
|
||||||
|
|
@ -5506,7 +5523,8 @@ Normally, doing that also resets the lecture that happens on the first use of =s
|
||||||
wantedBy = [ "initrd.target" ];
|
wantedBy = [ "initrd.target" ];
|
||||||
# make sure it's done after encryption
|
# make sure it's done after encryption
|
||||||
# i.e. LUKS/TPM process
|
# i.e. LUKS/TPM process
|
||||||
after = [ "systemd-cryptsetup@enc.service" ];
|
after = mkIfElseList config.swarselsystems.isCrypted [ "systemd-cryptsetup@cryptroot.service" ] [ "dev-disk-by\\x2dlabel-nixos.device" ];
|
||||||
|
requires = lib.mkIf (!config.swarselsystems.isCrypted) [ "dev-disk-by\\x2dlabel-nixos.device" ];
|
||||||
# mount the root fs before clearing
|
# mount the root fs before clearing
|
||||||
before = [ "sysroot.mount" ];
|
before = [ "sysroot.mount" ];
|
||||||
unitConfig.DefaultDependencies = "no";
|
unitConfig.DefaultDependencies = "no";
|
||||||
|
|
@ -5516,7 +5534,7 @@ Normally, doing that also resets the lecture that happens on the first use of =s
|
||||||
|
|
||||||
# We first mount the btrfs root to /mnt
|
# We first mount the btrfs root to /mnt
|
||||||
# so we can manipulate btrfs subvolumes.
|
# so we can manipulate btrfs subvolumes.
|
||||||
mount -o subvol=/ /dev/mapper/cryptroot /mnt
|
mount -o subvolid=5 -t btrfs ${mapperTarget} /mnt
|
||||||
btrfs subvolume list -o /mnt/root
|
btrfs subvolume list -o /mnt/root
|
||||||
|
|
||||||
# While we're tempted to just delete /root and create
|
# While we're tempted to just delete /root and create
|
||||||
|
|
@ -5533,13 +5551,13 @@ Normally, doing that also resets the lecture that happens on the first use of =s
|
||||||
cut -f9 -d' ' |
|
cut -f9 -d' ' |
|
||||||
while read subvolume; do
|
while read subvolume; do
|
||||||
echo "deleting /$subvolume subvolume..."
|
echo "deleting /$subvolume subvolume..."
|
||||||
# btrfs subvolume delete "/mnt/$subvolume"
|
btrfs subvolume delete "/mnt/$subvolume"
|
||||||
done &&
|
done &&
|
||||||
echo "deleting /root subvolume..." &&
|
echo "deleting /root subvolume..." &&
|
||||||
# btrfs subvolume delete /mnt/root
|
btrfs subvolume delete /mnt/root
|
||||||
|
|
||||||
echo "restoring blank /root subvolume..."
|
echo "restoring blank /root subvolume..."
|
||||||
# btrfs subvolume snapshot /mnt/root-blank /mnt/root
|
btrfs subvolume snapshot /mnt/root-blank /mnt/root
|
||||||
|
|
||||||
# Once we're done rolling back to a blank snapshot,
|
# Once we're done rolling back to a blank snapshot,
|
||||||
# we can unmount /mnt and continue on the boot process.
|
# we can unmount /mnt and continue on the boot process.
|
||||||
|
|
@ -5556,7 +5574,6 @@ Normally, doing that also resets the lecture that happens on the first use of =s
|
||||||
"/srv"
|
"/srv"
|
||||||
"/etc/nixos"
|
"/etc/nixos"
|
||||||
"/etc/nix"
|
"/etc/nix"
|
||||||
"/home/swarsel/.dotfiles"
|
|
||||||
"/etc/NetworkManager/system-connections"
|
"/etc/NetworkManager/system-connections"
|
||||||
"/etc/secureboot"
|
"/etc/secureboot"
|
||||||
"/var/db/sudo"
|
"/var/db/sudo"
|
||||||
|
|
@ -5565,13 +5582,10 @@ Normally, doing that also resets the lecture that happens on the first use of =s
|
||||||
];
|
];
|
||||||
|
|
||||||
files = [
|
files = [
|
||||||
# ssh stuff
|
|
||||||
/*
|
|
||||||
"/etc/ssh/ssh_host_ed25519_key"
|
"/etc/ssh/ssh_host_ed25519_key"
|
||||||
"/etc/ssh/ssh_host_ed25519_key.pub"
|
"/etc/ssh/ssh_host_ed25519_key.pub"
|
||||||
"/etc/ssh/ssh_host_rsa_key"
|
"/etc/ssh/ssh_host_rsa_key"
|
||||||
"/etc/ssh/ssh_host_rsa_key.pub"
|
"/etc/ssh/ssh_host_rsa_key.pub"
|
||||||
,*/
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ in
|
||||||
hasFingerprint = true;
|
hasFingerprint = true;
|
||||||
impermanence = false;
|
impermanence = false;
|
||||||
isBtrfs = true;
|
isBtrfs = true;
|
||||||
|
isCrypted = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
home-manager.users.swarsel.swarselsystems = {
|
home-manager.users.swarsel.swarselsystems = {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,9 @@ in
|
||||||
"${self}/hosts/nixos/toto/disk-config.nix"
|
"${self}/hosts/nixos/toto/disk-config.nix"
|
||||||
{
|
{
|
||||||
_module.args = {
|
_module.args = {
|
||||||
withSwap = false;
|
withSwap = true;
|
||||||
|
swapSize = "8";
|
||||||
|
rootDisk = "/dev/vda";
|
||||||
withImpermanence = true;
|
withImpermanence = true;
|
||||||
withEncryption = false;
|
withEncryption = false;
|
||||||
};
|
};
|
||||||
|
|
@ -17,12 +19,14 @@ in
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
|
|
||||||
inputs.sops-nix.nixosModules.sops
|
inputs.sops-nix.nixosModules.sops
|
||||||
|
inputs.impermanence.nixosModules.impermanence
|
||||||
|
|
||||||
"${profilesPath}/optional/nixos/autologin.nix"
|
"${profilesPath}/optional/nixos/autologin.nix"
|
||||||
"${profilesPath}/common/nixos/settings.nix"
|
"${profilesPath}/common/nixos/settings.nix"
|
||||||
"${profilesPath}/common/nixos/home-manager.nix"
|
"${profilesPath}/common/nixos/home-manager.nix"
|
||||||
"${profilesPath}/common/nixos/xserver.nix"
|
"${profilesPath}/common/nixos/xserver.nix"
|
||||||
"${profilesPath}/common/nixos/users.nix"
|
"${profilesPath}/common/nixos/users.nix"
|
||||||
|
"${profilesPath}/common/nixos/impermanence.nix"
|
||||||
"${profilesPath}/common/nixos/sops.nix"
|
"${profilesPath}/common/nixos/sops.nix"
|
||||||
"${profilesPath}/server/nixos/ssh.nix"
|
"${profilesPath}/server/nixos/ssh.nix"
|
||||||
|
|
||||||
|
|
@ -75,14 +79,15 @@ in
|
||||||
swarselsystems = {
|
swarselsystems = {
|
||||||
wallpaper = self + /wallpaper/lenovowp.png;
|
wallpaper = self + /wallpaper/lenovowp.png;
|
||||||
impermanence = true;
|
impermanence = true;
|
||||||
isBtrfs = false;
|
isBtrfs = true;
|
||||||
|
isCrypted = false;
|
||||||
initialSetup = true;
|
initialSetup = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
home-manager.users.swarsel.swarselsystems = {
|
home-manager.users.swarsel.swarselsystems = {
|
||||||
isLaptop = false;
|
isLaptop = false;
|
||||||
isNixos = true;
|
isNixos = true;
|
||||||
isBtrfs = false;
|
isBtrfs = true;
|
||||||
flakePath = "/home/swarsel/.dotfiles";
|
flakePath = "/home/swarsel/.dotfiles";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,69 @@
|
||||||
# NOTE: ... is needed because dikso passes diskoFile
|
# NOTE: ... is needed because dikso passes diskoFile
|
||||||
{ lib
|
{ lib
|
||||||
, pkgs
|
, pkgs
|
||||||
, swapSize
|
, rootDisk
|
||||||
|
, swapSize ? "8"
|
||||||
, withSwap ? true
|
, withSwap ? true
|
||||||
, withEncryption ? true
|
, withEncryption ? true
|
||||||
, withImpermanence ? true
|
, withImpermanence ? true
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
|
let
|
||||||
|
type = "btrfs";
|
||||||
|
extraArgs = [ "-L" "nixos" "-f" ]; # force overwrite
|
||||||
|
subvolumes = {
|
||||||
|
"/root" = {
|
||||||
|
mountpoint = "/";
|
||||||
|
mountOptions = [
|
||||||
|
"subvol=root"
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"/home" = lib.mkIf withImpermanence {
|
||||||
|
mountpoint = "/home";
|
||||||
|
mountOptions = [
|
||||||
|
"subvol=home"
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"/persist" = lib.mkIf withImpermanence {
|
||||||
|
mountpoint = "/persist";
|
||||||
|
mountOptions = [
|
||||||
|
"subvol=persist"
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"/log" = lib.mkIf withImpermanence {
|
||||||
|
mountpoint = "/var/log";
|
||||||
|
mountOptions = [
|
||||||
|
"subvol=log"
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"/nix" = {
|
||||||
|
mountpoint = "/nix";
|
||||||
|
mountOptions = [
|
||||||
|
"subvol=nix"
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"/swap" = lib.mkIf withSwap {
|
||||||
|
mountpoint = "/.swapvol";
|
||||||
|
swap.swapfile.size = "${swapSize}G";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
{
|
{
|
||||||
disko.devices = {
|
disko.devices = {
|
||||||
disk = {
|
disk = {
|
||||||
disk0 = {
|
disk0 = {
|
||||||
type = "disk";
|
type = "disk";
|
||||||
device = "/dev/vda";
|
device = rootDisk;
|
||||||
content = {
|
content = {
|
||||||
type = "gpt";
|
type = "gpt";
|
||||||
partitions = {
|
partitions = {
|
||||||
|
|
@ -31,41 +82,13 @@
|
||||||
root = lib.mkIf (!withEncryption) {
|
root = lib.mkIf (!withEncryption) {
|
||||||
size = "100%";
|
size = "100%";
|
||||||
content = {
|
content = {
|
||||||
type = "btrfs";
|
inherit type subvolumes extraArgs;
|
||||||
extraArgs = [ "-f" ]; # force overwrite
|
|
||||||
postCreateHook = lib.mkIf withImpermanence ''
|
postCreateHook = lib.mkIf withImpermanence ''
|
||||||
MNTPOINT=$(mktemp -d)
|
MNTPOINT=$(mktemp -d)
|
||||||
mount "/dev/mapper/root" "$MNTPOINT" -o subvol=/
|
mount "/dev/disk/by-label/nixos" "$MNTPOINT" -o subvolid=5
|
||||||
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
|
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
|
||||||
btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
|
btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
|
||||||
'';
|
'';
|
||||||
subvolumes = {
|
|
||||||
"@root" = {
|
|
||||||
mountpoint = "/";
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
"@persist" = lib.mkIf withImpermanence {
|
|
||||||
mountpoint = "/persist";
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
"@nix" = {
|
|
||||||
mountpoint = "/nix";
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
"@swap" = lib.mkIf withSwap {
|
|
||||||
mountpoint = "/.swapvol";
|
|
||||||
swap.swapfile.size = "${swapSize}G";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
luks = lib.mkIf withEncryption {
|
luks = lib.mkIf withEncryption {
|
||||||
|
|
@ -73,7 +96,7 @@
|
||||||
content = {
|
content = {
|
||||||
type = "luks";
|
type = "luks";
|
||||||
name = "cryptroot";
|
name = "cryptroot";
|
||||||
passwordFile = "/tmp/disko-password"; # this is populated by bootstrap-nixos.sh
|
passwordFile = "/tmp/disko-password"; # this is populated by bootstrap.sh
|
||||||
settings = {
|
settings = {
|
||||||
allowDiscards = true;
|
allowDiscards = true;
|
||||||
# https://github.com/hmajid2301/dotfiles/blob/a0b511c79b11d9b4afe2a5e2b7eedb2af23e288f/systems/x86_64-linux/framework/disks.nix#L36
|
# https://github.com/hmajid2301/dotfiles/blob/a0b511c79b11d9b4afe2a5e2b7eedb2af23e288f/systems/x86_64-linux/framework/disks.nix#L36
|
||||||
|
|
@ -82,44 +105,14 @@
|
||||||
"token-timeout=10"
|
"token-timeout=10"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
# Subvolumes must set a mountpoint in order to be mounted,
|
|
||||||
# unless their parent is mounted
|
|
||||||
content = {
|
content = {
|
||||||
type = "btrfs";
|
inherit type subvolumes extraArgs;
|
||||||
extraArgs = [ "-f" ]; # force overwrite
|
|
||||||
postCreateHook = lib.mkIf withImpermanence ''
|
postCreateHook = lib.mkIf withImpermanence ''
|
||||||
MNTPOINT=$(mktemp -d)
|
MNTPOINT=$(mktemp -d)
|
||||||
mount "/dev/mapper/cryptroot" "$MNTPOINT" -o subvol=/
|
mount "/dev/mapper/cryptroot" "$MNTPOINT" -o subvolid=5
|
||||||
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
|
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
|
||||||
btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
|
btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
|
||||||
'';
|
'';
|
||||||
subvolumes = {
|
|
||||||
"@root" = {
|
|
||||||
mountpoint = "/";
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
"@persist" = lib.mkIf withImpermanence {
|
|
||||||
mountpoint = "/persist";
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
"@nix" = {
|
|
||||||
mountpoint = "/nix";
|
|
||||||
mountOptions = [
|
|
||||||
"compress=zstd"
|
|
||||||
"noatime"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
"@swap" = lib.mkIf withSwap {
|
|
||||||
mountpoint = "/.swapvol";
|
|
||||||
swap.swapfile.size = "${swapSize}G";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -130,8 +123,9 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/persist".neededForBoot = lib.mkIf withImpermanence true;
|
fileSystems."/persist".neededForBoot = lib.mkIf withImpermanence true;
|
||||||
|
fileSystems."/home".neededForBoot = lib.mkIf withImpermanence true;
|
||||||
|
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
pkgs.yubikey-manager # For luks fido2 enrollment before full install
|
pkgs.yubikey-manager
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ in
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
};
|
};
|
||||||
|
options.swarselsystems.isCrypted = lib.mkEnableOption "uses full disk encryption";
|
||||||
options.swarselsystems.isPublic = lib.mkEnableOption "is a public machine (no secrets)";
|
options.swarselsystems.isPublic = lib.mkEnableOption "is a public machine (no secrets)";
|
||||||
options.swarselsystems.initialSetup = lib.mkEnableOption "initial setup (no sops keys available)";
|
options.swarselsystems.initialSetup = lib.mkEnableOption "initial setup (no sops keys available)";
|
||||||
options.swarselsystems.server.enable = lib.mkEnableOption "is a server machine";
|
options.swarselsystems.server.enable = lib.mkEnableOption "is a server machine";
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,13 @@
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
mkIfElse = p: yes: no: if p then yes else no;
|
||||||
|
mkIfElseList = p: yes: no: lib.mkMerge [
|
||||||
|
(lib.mkIf p yes)
|
||||||
|
(lib.mkIf (!p) no)
|
||||||
|
];
|
||||||
|
mapperTarget = mkIfElse config.swarselsystems.isCrypted "/dev/mapper/cryptroot" "/dev/disk/by-label/nixos";
|
||||||
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
security.sudo.extraConfig = lib.mkIf config.swarselsystems.impermanence ''
|
security.sudo.extraConfig = lib.mkIf config.swarselsystems.impermanence ''
|
||||||
|
|
@ -17,7 +26,8 @@
|
||||||
wantedBy = [ "initrd.target" ];
|
wantedBy = [ "initrd.target" ];
|
||||||
# make sure it's done after encryption
|
# make sure it's done after encryption
|
||||||
# i.e. LUKS/TPM process
|
# i.e. LUKS/TPM process
|
||||||
after = [ "systemd-cryptsetup@enc.service" ];
|
after = mkIfElseList config.swarselsystems.isCrypted [ "systemd-cryptsetup@cryptroot.service" ] [ "dev-disk-by\\x2dlabel-nixos.device" ];
|
||||||
|
requires = lib.mkIf (!config.swarselsystems.isCrypted) [ "dev-disk-by\\x2dlabel-nixos.device" ];
|
||||||
# mount the root fs before clearing
|
# mount the root fs before clearing
|
||||||
before = [ "sysroot.mount" ];
|
before = [ "sysroot.mount" ];
|
||||||
unitConfig.DefaultDependencies = "no";
|
unitConfig.DefaultDependencies = "no";
|
||||||
|
|
@ -27,7 +37,7 @@
|
||||||
|
|
||||||
# We first mount the btrfs root to /mnt
|
# We first mount the btrfs root to /mnt
|
||||||
# so we can manipulate btrfs subvolumes.
|
# so we can manipulate btrfs subvolumes.
|
||||||
mount -o subvol=/ /dev/mapper/cryptroot /mnt
|
mount -o subvolid=5 -t btrfs ${mapperTarget} /mnt
|
||||||
btrfs subvolume list -o /mnt/root
|
btrfs subvolume list -o /mnt/root
|
||||||
|
|
||||||
# While we're tempted to just delete /root and create
|
# While we're tempted to just delete /root and create
|
||||||
|
|
@ -44,13 +54,13 @@
|
||||||
cut -f9 -d' ' |
|
cut -f9 -d' ' |
|
||||||
while read subvolume; do
|
while read subvolume; do
|
||||||
echo "deleting /$subvolume subvolume..."
|
echo "deleting /$subvolume subvolume..."
|
||||||
# btrfs subvolume delete "/mnt/$subvolume"
|
btrfs subvolume delete "/mnt/$subvolume"
|
||||||
done &&
|
done &&
|
||||||
echo "deleting /root subvolume..." &&
|
echo "deleting /root subvolume..." &&
|
||||||
# btrfs subvolume delete /mnt/root
|
btrfs subvolume delete /mnt/root
|
||||||
|
|
||||||
echo "restoring blank /root subvolume..."
|
echo "restoring blank /root subvolume..."
|
||||||
# btrfs subvolume snapshot /mnt/root-blank /mnt/root
|
btrfs subvolume snapshot /mnt/root-blank /mnt/root
|
||||||
|
|
||||||
# Once we're done rolling back to a blank snapshot,
|
# Once we're done rolling back to a blank snapshot,
|
||||||
# we can unmount /mnt and continue on the boot process.
|
# we can unmount /mnt and continue on the boot process.
|
||||||
|
|
@ -67,7 +77,6 @@
|
||||||
"/srv"
|
"/srv"
|
||||||
"/etc/nixos"
|
"/etc/nixos"
|
||||||
"/etc/nix"
|
"/etc/nix"
|
||||||
"/home/swarsel/.dotfiles"
|
|
||||||
"/etc/NetworkManager/system-connections"
|
"/etc/NetworkManager/system-connections"
|
||||||
"/etc/secureboot"
|
"/etc/secureboot"
|
||||||
"/var/db/sudo"
|
"/var/db/sudo"
|
||||||
|
|
@ -76,13 +85,10 @@
|
||||||
];
|
];
|
||||||
|
|
||||||
files = [
|
files = [
|
||||||
# ssh stuff
|
|
||||||
/*
|
|
||||||
"/etc/ssh/ssh_host_ed25519_key"
|
"/etc/ssh/ssh_host_ed25519_key"
|
||||||
"/etc/ssh/ssh_host_ed25519_key.pub"
|
"/etc/ssh/ssh_host_ed25519_key.pub"
|
||||||
"/etc/ssh/ssh_host_rsa_key"
|
"/etc/ssh/ssh_host_rsa_key"
|
||||||
"/etc/ssh/ssh_host_rsa_key.pub"
|
"/etc/ssh/ssh_host_rsa_key.pub"
|
||||||
*/
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ in
|
||||||
{
|
{
|
||||||
sops = lib.mkIf (!config.swarselsystems.isPublic) {
|
sops = lib.mkIf (!config.swarselsystems.isPublic) {
|
||||||
|
|
||||||
age.sshKeyPaths = mkIfElse config.swarselsystems.isBtrfs [ "/persist/.ssh/sops" ] [ "${config.users.users.swarsel.home}/.ssh/sops" "/etc/ssh/ssh_host_ed25519_key" ];
|
age.sshKeyPaths = mkIfElse config.swarselsystems.isBtrfs [ "/persist/.ssh/sops" "/persist/.ssh/ssh_host_ed25519_key" ] [ "${config.users.users.swarsel.home}/.ssh/sops" "/etc/ssh/ssh_host_ed25519_key" ];
|
||||||
defaultSopsFile = mkIfElse config.swarselsystems.isBtrfs "/persist/.dotfiles/secrets/general/secrets.yaml" "${config.users.users.swarsel.home}/.dotfiles/secrets/general/secrets.yaml";
|
defaultSopsFile = mkIfElse config.swarselsystems.isBtrfs "/persist/.dotfiles/secrets/general/secrets.yaml" "${config.users.users.swarsel.home}/.dotfiles/secrets/general/secrets.yaml";
|
||||||
|
|
||||||
validateSopsFiles = false;
|
validateSopsFiles = false;
|
||||||
|
|
|
||||||
|
|
@ -115,11 +115,9 @@ while [[ $# -gt 0 ]]; do
|
||||||
temp=$1
|
temp=$1
|
||||||
;;
|
;;
|
||||||
--impermanence)
|
--impermanence)
|
||||||
shift
|
|
||||||
persist_dir="/persist"
|
persist_dir="/persist"
|
||||||
;;
|
;;
|
||||||
--encryption)
|
--encryption)
|
||||||
shift
|
|
||||||
disk_encryption=1
|
disk_encryption=1
|
||||||
;;
|
;;
|
||||||
--debug)
|
--debug)
|
||||||
|
|
@ -259,6 +257,7 @@ if yes_or_no "Do you want to copy your full nix-config and nix-secrets to $targe
|
||||||
|
|
||||||
if [ -n "$persist_dir" ]; then
|
if [ -n "$persist_dir" ]; then
|
||||||
$ssh_root_cmd "cp -r /home/$target_user/.dotfiles $persist_dir/.dotfiles || true"
|
$ssh_root_cmd "cp -r /home/$target_user/.dotfiles $persist_dir/.dotfiles || true"
|
||||||
|
$ssh_root_cmd "cp -r /home/$target_user/.ssh $persist_dir/.ssh || true"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if yes_or_no "Do you want to rebuild immediately?"; then
|
if yes_or_no "Do you want to rebuild immediately?"; then
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue