Compare commits
54
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0009e53e7 | ||
|
|
bb6ef87068 | ||
|
|
6192f21937 | ||
|
|
ed458bf06f | ||
|
|
2e39ad6ee4 | ||
|
|
28327b40f1 | ||
|
|
2041aca077 | ||
|
|
804e4e8e62 | ||
|
|
b027cf5493 | ||
|
|
5524070d7d | ||
|
|
6055ca801c | ||
|
|
9e60352132 | ||
|
|
a7775786ce | ||
|
|
dcc3c6ce37 | ||
|
|
7cbef5a277 | ||
|
|
7e749b59a0 | ||
|
|
95f0b2eaaf | ||
|
|
8fe2a76ab0 | ||
|
|
5a9f6279ee | ||
|
|
bf64bcf546 | ||
|
|
af4e471f53 | ||
|
|
2f82c42363 | ||
|
|
922bd6adbb | ||
|
|
080f68860e | ||
|
|
97d022a875 | ||
|
|
7449d26f86 | ||
|
|
9f08e4cc6e | ||
|
|
ea090ca4df | ||
|
|
857dea48de | ||
|
|
826d6b5266 | ||
|
|
2417049fff | ||
|
|
4139883ad4 | ||
|
|
9cec481ecf | ||
|
|
2d6880e109 | ||
|
|
a2e14d1177 | ||
|
|
a5bd3e09f5 | ||
|
|
e68ba20f0c | ||
|
|
3ac20ba460 | ||
|
|
35bb9dbe17 | ||
|
|
93f9b65c03 | ||
|
|
06b5564bc1 | ||
|
|
acffac3adf | ||
|
|
097da98b35 | ||
|
|
60a713eb95 | ||
|
|
19f86677d5 | ||
|
|
ec295de0f4 | ||
|
|
db3c673a5f | ||
|
|
d6efac769e | ||
|
|
ae5bd60194 | ||
|
|
95cc3f34dd | ||
|
|
e62b4436e5 | ||
|
|
802103921e | ||
|
|
aa0a76aed2 | ||
|
|
74a8c0cc40 |
+15
-21
@@ -1,24 +1,18 @@
|
||||
* Minimal NixOS Root on ZFS configuration
|
||||
This repo contains a minimal set of configuration needed for
|
||||
installing NixOS on a computer with ZFS as root filesystem.
|
||||
* Install NixOS with ZFS as root filesystem
|
||||
This repo contains a minimal set of configuration for installing
|
||||
NixOS, using ZFS as root filesystem.
|
||||
|
||||
#+begin_src text
|
||||
.gitignore
|
||||
LICENSE
|
||||
configuration.nix <- configuration shared by all hosts
|
||||
flake.lock
|
||||
flake.nix
|
||||
hosts/exampleHost/default.nix <- per-host configuration
|
||||
hosts/exampleHost/sshUnlock.txt
|
||||
modules/boot/default.nix
|
||||
modules/default.nix
|
||||
modules/fileSystems/default.nix
|
||||
modules/networking/default.nix
|
||||
modules/users/default.nix
|
||||
#+end_src
|
||||
ZFS is a modern filesystem with many features such as snapshot,
|
||||
self-healing and pooled storage, see [[https://openzfs.org/wiki/Main_Page#Introduction_to_OpenZFS][Introduction]] for details.
|
||||
|
||||
Just enough to get you started.
|
||||
For using this repo on your computer, see [[https://openzfs.github.io/openzfs-docs/Getting%20Started/NixOS/Root%20on%20ZFS.html][Documentation]].
|
||||
|
||||
See [[https://github.com/ne9z/personal-dotfiles][my personal dotfiles repo]] for an example of how to configure
|
||||
servers and desktop computers in the same git repository, based on
|
||||
this template repo you are viewing now.
|
||||
Upon initial installation, only the bootloader, mountpoints and root
|
||||
password are configured.
|
||||
|
||||
- Refer to =man configuration.nix= for available options;
|
||||
- Search for available packages with [[https://search.nixos.org/packages][Package Search]];
|
||||
- Search for options with [[https://search.nixos.org/options][Option Search]].
|
||||
|
||||
[[https://codeberg.org/m0p/dotfiles][My personal dotfiles repo]] contains an example of desktop configuration
|
||||
based on sway, tmux and Emacs.
|
||||
|
||||
+54
-198
@@ -1,67 +1,37 @@
|
||||
{
|
||||
my-config, zfs-root, inputs, pkgs, lib, ...
|
||||
}:
|
||||
let
|
||||
kubeMasterIP = "10.1.1.2";
|
||||
kubeMasterHostname = "api.kube";
|
||||
kubeMasterAPIServerPort = 6443;
|
||||
in
|
||||
{
|
||||
# load module config to top-level configuration
|
||||
inherit my-config zfs-root;
|
||||
|
||||
# Let 'nixos-version --json' know about the Git revision
|
||||
# of this flake.
|
||||
system.configurationRevision = if (inputs.self ? rev) then
|
||||
inputs.self.rev
|
||||
else
|
||||
throw "refuse to build: git tree is dirty";
|
||||
|
||||
system.stateVersion = "22.11";
|
||||
|
||||
system.activationScripts = {
|
||||
enableLingering = ''
|
||||
# remove all existing lingering users
|
||||
rm -r /var/lib/systemd/linger
|
||||
mkdir /var/lib/systemd/linger
|
||||
# enable for the subset of declared users
|
||||
touch /var/lib/systemd/linger/marc
|
||||
'';
|
||||
};
|
||||
|
||||
virtualisation.docker.enable = true;
|
||||
# configuration in this file is shared by all hosts
|
||||
|
||||
{ pkgs, pkgs-unstable, inputs, ... }:
|
||||
let inherit (inputs) self;
|
||||
in {
|
||||
# Enable NetworkManager for wireless networking,
|
||||
# You can configure networking with "nmtui" command.
|
||||
# networking.useDHCP = true;
|
||||
networking.hostName = "tower";
|
||||
networking.networkmanager.enable = true;
|
||||
networking.wireless.iwd.enable = true;
|
||||
networking.networkmanager.wifi.backend = "iwd";
|
||||
|
||||
services.xserver.enable = true;
|
||||
services.xserver.displayManager.gdm.enable = true;
|
||||
|
||||
hardware.pulseaudio.enable = true;
|
||||
hardware.bluetooth.enable = true;
|
||||
programs.hyprland.enable = true;
|
||||
networking.useDHCP = true;
|
||||
networking.networkmanager.enable = false;
|
||||
|
||||
users.users = {
|
||||
root = {
|
||||
isNormalUser = false;
|
||||
shell = pkgs.zsh;
|
||||
initialHashedPassword = "$6$0QAYnBqAJtqB12p3$2lb7rAS2sYw49GUJt0L0bAEpZJSv4HZARQjlbYPhexSmeRB71IRMBzXjf3b4rX6fuDxOuDLydP/Kni9uraS5j/";
|
||||
openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDiUE73uIEgijfmSsDwBvZmecQnqjBUPRKlMDmevsThc1YJNWEHl57NNIUcx6XSCDPKu5azayImLqIBt8wT5xlqtNX20uCnikDfXZ8gFbGlMRTGZKutQZIRmUrUS5mz97S4dVVK+n5WU+OwOfEg/XKXPh4WbTVDpfTTg7RopRAXkma56HV2TJM0ndPRN8VLmBmtnwdQwEpJ0tRRY+KOHmTojsH65eaZ89+BHbto+Kg+lk6x8IH5VDCRQNHgTEccOpOGYBSHRpoZi1a5h3yajf/eGAQ9Cd38DOsfMtm84oFlii7oXPyxwXoM+uH1SDnvLXyheIrV/XLUurSbEb4aJni6Zu79Z9l8xHhUNmVNSZqWOWUvPbAHlDKUzsbxgk9Zs9OTvSDaRzGhViYl4e1Qc993yerGSW1HHIvYUKM7o5nSQqskSOvOI+ahL5fIbgdyVx4FeuURZIyZSxCz4jIJTK15/6pkT/miHKv+vmQhsoLCqgyXY4SG1p9ruzKkzBe03ZQVW5WeFDLYRjZ+Z4Q2IL2K3BmLgp8tInkPJizQ7v5UGSiajJmPxY0j+CqdH9ZlIBdf8GS+run/N4hpMC1/ayUZRbCY5jg4c8bev8dKEZYJKPs/Hq2zLRZe4YtxcKuiGhgIwQOzo/QrCvSM4pVDgo+d2DjEzIdapqE8hF6BHWDg/w== marc.partensky@gmail.com" ];
|
||||
initialHashedPassword = "rootHash_placeholder";
|
||||
openssh.authorizedKeys.keys = [ "sshKey_placeholder" ];
|
||||
};
|
||||
marc = {
|
||||
isNormalUser = true;
|
||||
home = "/home/marc";
|
||||
description = "Marc Partensky";
|
||||
extraGroups = ["wheel" "networkmanager" "docker" "seat" "kvm" "video"];
|
||||
# openssh.authorizedKeys.keys =
|
||||
shell = pkgs.zsh;
|
||||
initialHashedPassword = "$6$0QAYnBqAJtqB12p3$2lb7rAS2sYw49GUJt0L0bAEpZJSv4HZARQjlbYPhexSmeRB71IRMBzXjf3b4rX6fuDxOuDLydP/Kni9uraS5j/";
|
||||
openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDiUE73uIEgijfmSsDwBvZmecQnqjBUPRKlMDmevsThc1YJNWEHl57NNIUcx6XSCDPKu5azayImLqIBt8wT5xlqtNX20uCnikDfXZ8gFbGlMRTGZKutQZIRmUrUS5mz97S4dVVK+n5WU+OwOfEg/XKXPh4WbTVDpfTTg7RopRAXkma56HV2TJM0ndPRN8VLmBmtnwdQwEpJ0tRRY+KOHmTojsH65eaZ89+BHbto+Kg+lk6x8IH5VDCRQNHgTEccOpOGYBSHRpoZi1a5h3yajf/eGAQ9Cd38DOsfMtm84oFlii7oXPyxwXoM+uH1SDnvLXyheIrV/XLUurSbEb4aJni6Zu79Z9l8xHhUNmVNSZqWOWUvPbAHlDKUzsbxgk9Zs9OTvSDaRzGhViYl4e1Qc993yerGSW1HHIvYUKM7o5nSQqskSOvOI+ahL5fIbgdyVx4FeuURZIyZSxCz4jIJTK15/6pkT/miHKv+vmQhsoLCqgyXY4SG1p9ruzKkzBe03ZQVW5WeFDLYRjZ+Z4Q2IL2K3BmLgp8tInkPJizQ7v5UGSiajJmPxY0j+CqdH9ZlIBdf8GS+run/N4hpMC1/ayUZRbCY5jg4c8bev8dKEZYJKPs/Hq2zLRZe4YtxcKuiGhgIwQOzo/QrCvSM4pVDgo+d2DjEzIdapqE8hF6BHWDg/w== marc.partensky@gmail.com" ];
|
||||
};
|
||||
|
||||
## enable GNOME desktop.
|
||||
## You need to configure a normal, non-root user.
|
||||
# services.xserver = {
|
||||
# enable = true;
|
||||
# desktopManager.gnome.enable = true;
|
||||
# displayManager.gdm.enable = true;
|
||||
# };
|
||||
|
||||
## enable ZFS auto snapshot on datasets
|
||||
## You need to set the auto snapshot property to "true"
|
||||
## on datasets for this to work, such as
|
||||
# zfs set com.sun:auto-snapshot=true rpool/nixos/home
|
||||
services.zfs = {
|
||||
autoSnapshot = {
|
||||
enable = false;
|
||||
flags = "-k -p --utc";
|
||||
monthly = 48;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -71,164 +41,50 @@ in
|
||||
vimAlias = true;
|
||||
};
|
||||
|
||||
imports = [
|
||||
"${inputs.nixpkgs}/nixos/modules/installer/scan/not-detected.nix"
|
||||
# "${inputs.nixpkgs}/nixos/modules/profiles/qemu-guest.nix"
|
||||
];
|
||||
|
||||
services.openssh = {
|
||||
enable = lib.mkDefault true;
|
||||
settings = { PasswordAuthentication = lib.mkDefault true; };
|
||||
enable = true;
|
||||
settings = { PasswordAuthentication = false; };
|
||||
};
|
||||
|
||||
# kubernetes https://nixos.wiki/wiki/K3s
|
||||
networking.firewall.allowedTCPPorts = [ 6443 5900 ];
|
||||
# services.k3s = {
|
||||
# enable = true;
|
||||
# role = "server";
|
||||
# # TODO describe how to enable zfs snapshotter in containerd
|
||||
# extraFlags = toString [
|
||||
# "--container-runtime-endpoint unix:///run/containerd/containerd.sock"
|
||||
# ];
|
||||
# };
|
||||
boot.zfs.forceImportRoot = false;
|
||||
|
||||
# kubernetes zfs support
|
||||
# virtualisation.containerd = {
|
||||
# enable = true;
|
||||
# settings =
|
||||
# let
|
||||
# fullCNIPlugins = pkgs.buildEnv {
|
||||
# name = "full-cni";
|
||||
# paths = with pkgs;[
|
||||
# cni-plugins
|
||||
# cni-plugin-flannel
|
||||
# ];
|
||||
# };
|
||||
# in {
|
||||
# plugins."io.containerd.grpc.v1.cri".cni = {
|
||||
# bin_dir = "${fullCNIPlugins}/bin";
|
||||
# conf_dir = "/var/lib/rancher/k3s/agent/etc/cni/net.d/";
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
|
||||
# kubernetes support
|
||||
# resolve master hostname
|
||||
# networking.extraHosts = "${kubeMasterIP} ${kubeMasterHostname}";
|
||||
|
||||
|
||||
# services.kubernetes = {
|
||||
# roles = ["master" "node"];
|
||||
# masterAddress = kubeMasterHostname;
|
||||
# apiserverAddress = "https://${kubeMasterHostname}:${toString kubeMasterAPIServerPort}";
|
||||
# easyCerts = true;
|
||||
# apiserver = {
|
||||
# securePort = kubeMasterAPIServerPort;
|
||||
# advertiseAddress = kubeMasterIP;
|
||||
# };
|
||||
|
||||
# # use coredns
|
||||
# addons.dns.enable = true;
|
||||
|
||||
# # needed if you use swap
|
||||
# kubelet.extraOpts = "--fail-swap-on=false";
|
||||
# };
|
||||
|
||||
boot.zfs.forceImportRoot = lib.mkDefault false;
|
||||
|
||||
nix.settings.experimental-features = lib.mkDefault [ "nix-command" "flakes" ];
|
||||
boot.initrd.systemd.enable = true;
|
||||
|
||||
programs.git.enable = true;
|
||||
programs.zsh.enable = true;
|
||||
|
||||
security = {
|
||||
doas.enable = lib.mkDefault true;
|
||||
sudo.enable = lib.mkDefault false;
|
||||
};
|
||||
|
||||
nix = {
|
||||
package = pkgs.nixFlakes;
|
||||
extraOptions = ''
|
||||
experimental-features = nix-command flakes
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.tunneltower = {
|
||||
enable = true;
|
||||
description = "Connect to my tower remotely";
|
||||
unitConfig = {
|
||||
# Type = "simple";
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.autossh}/bin/autossh -M 0 \
|
||||
-o ServerAliveInterval=30 \
|
||||
-o ServerAliveCountMax=3 \
|
||||
-o PubkeyAuthentication=yes \
|
||||
-o PasswordAuthentication=no \
|
||||
-NR localhost:42070:localhost:22 \
|
||||
-p 42069 \
|
||||
-i ~/.ssh/id_rsa \
|
||||
marc@207.180.235.56
|
||||
'';
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
doas.enable = true;
|
||||
sudo.enable = false;
|
||||
};
|
||||
|
||||
environment.systemPackages = builtins.attrValues {
|
||||
inherit (pkgs)
|
||||
k3s
|
||||
autossh
|
||||
mg # emacs-like editor
|
||||
jq # other programs
|
||||
neovim
|
||||
stow
|
||||
coreutils
|
||||
gnumake
|
||||
bat
|
||||
gnupg
|
||||
home-manager
|
||||
htop
|
||||
kompose
|
||||
kubectl
|
||||
kubernetes
|
||||
killall
|
||||
seatd
|
||||
mcfly
|
||||
sddm
|
||||
;
|
||||
# By default, the system will only use packages from the
|
||||
# stable channel. i.e.
|
||||
# inherit (pkg) my-favorite-stable-package;
|
||||
# You can selectively install packages
|
||||
# from the unstable channel. Such as
|
||||
# inherit (pkgs-unstable) my-favorite-unstable-package;
|
||||
# You can also add more
|
||||
# channels to pin package version.
|
||||
};
|
||||
|
||||
# Safety mechanism: refuse to build unless everything is
|
||||
# tracked by git
|
||||
system.configurationRevision = if (self ? rev) then
|
||||
self.rev
|
||||
else
|
||||
throw "refuse to build: git tree is dirty";
|
||||
|
||||
i18n.defaultLocale = "fr_FR.UTF-8";
|
||||
i18n.extraLocaleSettings = {
|
||||
LC_ADDRESS = "fr_FR.UTF-8";
|
||||
LC_IDENTIFICATION = "fr_FR.UTF-8";
|
||||
LC_MEASUREMENT = "fr_FR.UTF-8";
|
||||
LC_MONETARY = "fr_FR.UTF-8";
|
||||
LC_NAME = "fr_FR.UTF-8";
|
||||
LC_NUMERIC = "fr_FR.UTF-8";
|
||||
LC_PAPER = "fr_FR.UTF-8";
|
||||
LC_TELEPHONE = "fr_FR.UTF-8";
|
||||
LC_TIME = "fr_FR.UTF-8";
|
||||
};
|
||||
system.stateVersion = "23.05";
|
||||
|
||||
environment.sessionVariables = {
|
||||
# POLKIT_AUTH_AGENT = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1";
|
||||
# GSETTINGS_SCHEMA_DIR = "${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}/glib-2.0/schemas";
|
||||
# LIBVA_DRIVER_NAME = "nvidia";
|
||||
# XDG_SESSION_TYPE = "wayland";
|
||||
# GBM_BACKEND = "nvidia-drm";
|
||||
# __GLX_VENDOR_LIBRARY_NAME = "nvidia";
|
||||
# WLR_NO_HARDWARE_CURSORS = "1";
|
||||
# NIXOS_OZONE_WL = "1";
|
||||
# MOZ_ENABLE_WAYLAND = "1";
|
||||
# SDL_VIDEODRIVER = "wayland";
|
||||
# _JAVA_AWT_WM_NONREPARENTING = "1";
|
||||
# CLUTTER_BACKEND = "wayland";
|
||||
# WLR_RENDERER = "vulkan";
|
||||
# XDG_CURRENT_DESKTOP = "Hyprland";
|
||||
# XDG_SESSION_DESKTOP = "Hyprland";
|
||||
# GTK_USE_PORTAL = "1";
|
||||
# NIXOS_XDG_OPEN_USE_PORTAL = "1";
|
||||
};
|
||||
# let nix commands follow system nixpkgs revision
|
||||
nix.registry.nixpkgs.flake = inputs.nixpkgs;
|
||||
# you can then test any package in a nix shell, such as
|
||||
# $ nix shell nixpkgs#neovim
|
||||
}
|
||||
|
||||
Generated
+47
-10
@@ -1,24 +1,61 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"home-manager": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1687466461,
|
||||
"narHash": "sha256-oupXI7g7RPzlpGUfAu1xG4KBK53GrZH8/xeKgKDB4+Q=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ecb441f22067ba1d6312f4932a7c64efa8d19a7b",
|
||||
"lastModified": 1695108154,
|
||||
"narHash": "sha256-gSg7UTVtls2yO9lKtP0yb66XBHT1Fx5qZSZbGMpSn2c=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "07682fff75d41f18327a871088d20af2710d4744",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-23.05",
|
||||
"repo": "nixpkgs",
|
||||
"owner": "nix-community",
|
||||
"ref": "release-23.05",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1696983906,
|
||||
"narHash": "sha256-L7GyeErguS7Pg4h8nK0wGlcUTbfUMDu+HMf1UcyP72k=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "bd1cde45c77891214131cbbea5b1203e485a9d51",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-23.05",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1697349934,
|
||||
"narHash": "sha256-mSOXTIvCMA31nD/XEYmeSOebrXl0lFKirM14LK845e4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f320b0d46ee33f521f50d7c6885605714210e5c9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "master",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
"home-manager": "home-manager",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,27 +1,61 @@
|
||||
{
|
||||
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
|
||||
## after reboot, you can track rolling release by using
|
||||
#inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
description = "Barebones NixOS on ZFS config";
|
||||
|
||||
outputs = { self, nixpkgs }@inputs:
|
||||
inputs = {
|
||||
nixpkgs.url = "nixpkgs/nixos-23.05";
|
||||
nixpkgs-unstable.url = "nixpkgs/master";
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager/release-23.05";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, nixpkgs-unstable, home-manager }@inputs:
|
||||
let
|
||||
lib = nixpkgs.lib;
|
||||
mkHost = { my-config, zfs-root, pkgs, system, ... }:
|
||||
lib.nixosSystem {
|
||||
inherit system;
|
||||
mkHost = hostName: system:
|
||||
nixpkgs.lib.nixosSystem {
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
# settings to nixpkgs goes to here
|
||||
# nixpkgs.pkgs.zathura.useMupdf = true;
|
||||
# nixpkgs.config.allowUnfree = false;
|
||||
};
|
||||
|
||||
specialArgs = {
|
||||
# By default, the system will only use packages from the
|
||||
# stable channel. You can selectively install packages
|
||||
# from the unstable channel. You can also add more
|
||||
# channels to pin package version.
|
||||
pkgs-unstable = import nixpkgs-unstable {
|
||||
inherit system;
|
||||
# settings to nixpkgs-unstable goes to here
|
||||
};
|
||||
|
||||
# make all inputs availabe in other nix files
|
||||
inherit inputs;
|
||||
};
|
||||
|
||||
modules = [
|
||||
# Root on ZFS related configuration
|
||||
./modules
|
||||
(import ./configuration.nix {
|
||||
inherit my-config zfs-root inputs pkgs lib;
|
||||
})
|
||||
|
||||
# Configuration shared by all hosts
|
||||
./configuration.nix
|
||||
|
||||
# Configuration per host
|
||||
./hosts/${hostName}
|
||||
|
||||
# home-manager
|
||||
home-manager.nixosModules.home-manager
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
in {
|
||||
nixosConfigurations = {
|
||||
tower = let
|
||||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in mkHost (import ./hosts/tower { inherit system pkgs; });
|
||||
exampleHost = mkHost "exampleHost" "x86_64-linux";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
How to set hostname for a host.
|
||||
|
||||
You need to change the host name in three different places.
|
||||
|
||||
Place 1.
|
||||
|
||||
./flake.nix
|
||||
|
||||
Change
|
||||
|
||||
exampleHost = mkHost "exampleHost" "x86_64-linux";
|
||||
|
||||
to
|
||||
|
||||
myHost = mkHost "myHost" "x86_64-linux";
|
||||
|
||||
Place 2.
|
||||
|
||||
Move directory
|
||||
|
||||
./hosts/exampleHost
|
||||
|
||||
to
|
||||
|
||||
./hosts/myHost
|
||||
|
||||
Place 3.
|
||||
|
||||
./hosts/exampleHost/default.nix
|
||||
|
||||
Change
|
||||
|
||||
networking.hostName = "exampleHost";
|
||||
|
||||
to
|
||||
|
||||
networking.hostName = "myHost";
|
||||
|
||||
End.
|
||||
@@ -0,0 +1,24 @@
|
||||
{ config, pkgs, lib, inputs, modulesPath, ... }: {
|
||||
zfs-root = {
|
||||
boot = {
|
||||
devNodes = "/dev/disk/by-id/";
|
||||
bootDevices = [ "bootDevices_placeholder" ];
|
||||
immutable.enable = false;
|
||||
removableEfi = true;
|
||||
luks.enable = false;
|
||||
};
|
||||
};
|
||||
boot.initrd.availableKernelModules = [ "kernelModules_placeholder" ];
|
||||
boot.kernelParams = [ ];
|
||||
networking.hostId = "abcd1234";
|
||||
# read changeHostName.txt file.
|
||||
networking.hostName = "exampleHost";
|
||||
time.timeZone = "Europe/Berlin";
|
||||
|
||||
# import preconfigured profiles
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
# (modulesPath + "/profiles/hardened.nix")
|
||||
# (modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
How to set hostname for a host.
|
||||
|
||||
This repo is structured in a way that allows managing multiple hosts
|
||||
in a single repo. As a consequence of this, hostname appears in
|
||||
several different places and should be updated together if needed.
|
||||
|
||||
The entry point of this repo is ``flake.nix'' file, which takes a
|
||||
revision of the nixpkgs as input then gives an attribute set (attrset)
|
||||
as output:
|
||||
|
||||
{
|
||||
nixosConfigurations = {
|
||||
exampleHost = { ... };
|
||||
host2 = { ... };
|
||||
host3 = { ... };
|
||||
...
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
The hostname specified here inside nixosConfigurations attrset is used
|
||||
when ``nix command'' is invoked, as in
|
||||
|
||||
nixos-install --flake ./#exampleHost
|
||||
|
||||
The hostname also appears in the filesystem path of the per-host
|
||||
configuration file:
|
||||
|
||||
hosts/exampleHost/default.nix
|
||||
hosts/host2/default.nix
|
||||
...
|
||||
|
||||
Finally, the hostname is specified in the zfs-boot.networking.hostName
|
||||
option inside per-host configuration file at
|
||||
hosts/exampleHost/default.nix:
|
||||
|
||||
zfs-boot.networking.hostName = "exampleHost";
|
||||
|
||||
If the value of this option is identical to the name of
|
||||
nixosConfigurations.<hostname> attrset, all subsequent invocations of
|
||||
``nix command'' will default to this hostname, i.e. the command:
|
||||
|
||||
nixos-rebuild boot
|
||||
|
||||
will automatically append ``#hostName'' when evaluating the flake.
|
||||
@@ -1,37 +0,0 @@
|
||||
# #
|
||||
##
|
||||
## per-host configuration for exampleHost
|
||||
##
|
||||
##
|
||||
|
||||
{ system, pkgs, ... }: {
|
||||
inherit pkgs system;
|
||||
zfs-root = {
|
||||
boot = {
|
||||
devNodes = "/dev/";
|
||||
bootDevices = [ "nvme0n1" ];
|
||||
immutable = false;
|
||||
availableKernelModules = [ "nvme" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ];
|
||||
removableEfi = true;
|
||||
kernelParams = [ ];
|
||||
sshUnlock = {
|
||||
# read sshUnlock.txt file.
|
||||
enable = false;
|
||||
authorizedKeys = [ ];
|
||||
};
|
||||
};
|
||||
networking = {
|
||||
# read changeHostName.txt file.
|
||||
hostName = "tower";
|
||||
timeZone = "Europe/Paris";
|
||||
hostId = "97a4a6a0";
|
||||
};
|
||||
};
|
||||
|
||||
# To add more options to per-host configuration, you can create a
|
||||
# custom configuration module, then add it here.
|
||||
my-config = {
|
||||
# Enable custom gnome desktop on exampleHost
|
||||
template.desktop.gnome.enable = false;
|
||||
};
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
Audience
|
||||
|
||||
This text is intended for users who wish to remotely unlock their
|
||||
natively encrypted ZFS root filesystem with SSH during the early
|
||||
stages of system boot up.
|
||||
|
||||
=================================================================
|
||||
|
||||
Steps
|
||||
|
||||
By default, the initial RAM disk image, (hereafter refered to as
|
||||
initrd) only includes essential kernel modules needed for mounting the
|
||||
root filesystem.
|
||||
|
||||
To enable network connection during this stage of system boot, you
|
||||
need to instruct NixOS to include kernel modules needed for the
|
||||
network adapter.
|
||||
|
||||
Check which module is needed with:
|
||||
|
||||
nix-shell -p pciutils --run "lspci -v | grep -iA8 'network\|ethernet'"
|
||||
|
||||
Then, add the the modules to
|
||||
|
||||
zfs-root.boot.availableKernelModules
|
||||
|
||||
option inside the per-host configuration file. This file is located
|
||||
at hosts/exampleHost/default.nix.
|
||||
|
||||
By default, initrd uses DHCP auto-configuration for networking. If
|
||||
you need to specify a static IP address, see the documentation for
|
||||
"ip=" kernel command line option for NFS root:
|
||||
|
||||
https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt
|
||||
|
||||
Then, add the necessary kernel command line options to
|
||||
|
||||
zfs-root.boot.kernelParams
|
||||
|
||||
option inside the per-host configuration file.
|
||||
|
||||
Finally, you need to generate a pair of SSH private keys exclusively
|
||||
for use with decrypting the root filesystem during boot. This pair of
|
||||
keys should not be used anywhere else. Reasons for this can be found
|
||||
in the documentation NixOS option:
|
||||
|
||||
boot.initrd.network.ssh.hostKeys
|
||||
|
||||
> Do NOT use your regular SSH host private keys for this purpose or
|
||||
> you'll expose them to regular users! Additionally, even if your initrd
|
||||
> supports secrets, if you're using initrd SSH to unlock an encrypted
|
||||
> disk then using your regular host keys exposes the private keys on
|
||||
> your unencrypted boot partition.
|
||||
|
||||
You can generate host key with:
|
||||
|
||||
ssh-keygen -t ed25519 -N "" -f "/var/lib/ssh_unlock_zfs_ed25519_key"
|
||||
ssh-keygen -t rsa -N "" -f "/var/lib/ssh_unlock_zfs_rsa_key"
|
||||
|
||||
If you are performing a system installation, change path from
|
||||
/var/lib to /mnt/var/lib in both commands.
|
||||
+35
-59
@@ -11,6 +11,11 @@ in {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
luks.enable = mkOption {
|
||||
description = "Use luks encryption";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
devNodes = mkOption {
|
||||
description = "Specify where to discover ZFS pools";
|
||||
type = types.str;
|
||||
@@ -24,15 +29,7 @@ in {
|
||||
description = "Specify boot devices";
|
||||
type = types.nonEmptyListOf types.str;
|
||||
};
|
||||
availableKernelModules = mkOption {
|
||||
type = types.nonEmptyListOf types.str;
|
||||
default = [ "uas" "nvme" "ahci" ];
|
||||
};
|
||||
kernelParams = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
immutable = mkOption {
|
||||
immutable.enable = mkOption {
|
||||
description = "Enable root on ZFS immutable root support";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
@@ -44,56 +41,61 @@ in {
|
||||
};
|
||||
partitionScheme = mkOption {
|
||||
default = {
|
||||
biosBoot = "p5";
|
||||
efiBoot = "p1";
|
||||
swap = "p4";
|
||||
bootPool = "p2";
|
||||
rootPool = "p3";
|
||||
biosBoot = "-part5";
|
||||
efiBoot = "-part1";
|
||||
swap = "-part4";
|
||||
bootPool = "-part2";
|
||||
rootPool = "-part3";
|
||||
};
|
||||
description = "Describe on disk partitions";
|
||||
type = types.attrsOf types.str;
|
||||
};
|
||||
sshUnlock = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
authorizedKeys = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
config = mkIf (cfg.enable) (mkMerge [
|
||||
{
|
||||
zfs-root.fileSystems.datasets = {
|
||||
# rpool/path/to/dataset = "/path/to/mountpoint"
|
||||
"rpool/nixos/home" = mkDefault "/home";
|
||||
"rpool/nixos/var/lib" = mkDefault "/var/lib";
|
||||
"rpool/nixos/var/log" = mkDefault "/var/log";
|
||||
"bpool/nixos/root" = "/boot";
|
||||
};
|
||||
}
|
||||
(mkIf (!cfg.immutable) {
|
||||
(mkIf cfg.luks.enable {
|
||||
boot.initrd.luks.devices = mkMerge (map (diskName: {
|
||||
"luks-rpool-${diskName}${cfg.partitionScheme.rootPool}" = {
|
||||
device = (cfg.devNodes + diskName + cfg.partitionScheme.rootPool);
|
||||
allowDiscards = true;
|
||||
bypassWorkqueues = true;
|
||||
};
|
||||
}) cfg.bootDevices);
|
||||
})
|
||||
(mkIf (!cfg.immutable.enable) {
|
||||
zfs-root.fileSystems.datasets = { "rpool/nixos/root" = "/"; };
|
||||
})
|
||||
(mkIf cfg.immutable {
|
||||
(mkIf cfg.immutable.enable {
|
||||
zfs-root.fileSystems = {
|
||||
datasets = {
|
||||
# rpool/path/to/dataset = "/path/to/mountpoint"
|
||||
"rpool/nixos/empty" = "/";
|
||||
"rpool/nixos/root" = "/oldroot";
|
||||
};
|
||||
bindmounts = {
|
||||
# /bindmount/source = /bindmount/target
|
||||
"/oldroot/nix" = "/nix";
|
||||
"/oldroot/etc/nixos" = "/etc/nixos";
|
||||
};
|
||||
};
|
||||
boot.initrd.postDeviceCommands = ''
|
||||
if ! grep -q zfs_no_rollback /proc/cmdline; then
|
||||
zpool import -N rpool
|
||||
zfs rollback -r rpool/nixos/empty@start
|
||||
zpool export -a
|
||||
fi
|
||||
'';
|
||||
boot.initrd.systemd.services.immutable-zfs-root = {
|
||||
description = "Rollback root filesystem to an empty snapshot";
|
||||
unitConfig.DefaultDependencies = false;
|
||||
wantedBy = [ "zfs.target" ];
|
||||
after = [ "zfs-import-rpool.service" ];
|
||||
before = [ "sysroot.mount" ];
|
||||
path = [ pkgs.zfs ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = "zfs rollback -r rpool/nixos/empty@start";
|
||||
};
|
||||
})
|
||||
{
|
||||
zfs-root.fileSystems = {
|
||||
@@ -104,10 +106,6 @@ in {
|
||||
(map (diskName: diskName + cfg.partitionScheme.swap) cfg.bootDevices);
|
||||
};
|
||||
boot = {
|
||||
kernelPackages =
|
||||
mkDefault config.boot.zfs.package.latestCompatibleLinuxPackages;
|
||||
initrd.availableKernelModules = cfg.availableKernelModules;
|
||||
kernelParams = cfg.kernelParams;
|
||||
supportedFilesystems = [ "zfs" ];
|
||||
zfs = {
|
||||
devNodes = cfg.devNodes;
|
||||
@@ -136,27 +134,5 @@ in {
|
||||
};
|
||||
};
|
||||
}
|
||||
(mkIf cfg.sshUnlock.enable {
|
||||
boot.initrd = {
|
||||
network = {
|
||||
enable = true;
|
||||
ssh = {
|
||||
enable = true;
|
||||
hostKeys = [
|
||||
"/var/lib/ssh_unlock_zfs_ed25519_key"
|
||||
"/var/lib/ssh_unlock_zfs_rsa_key"
|
||||
];
|
||||
authorizedKeys = cfg.sshUnlock.authorizedKeys;
|
||||
};
|
||||
postCommands = ''
|
||||
tee -a /root/.profile >/dev/null <<EOF
|
||||
if zfs load-key rpool/nixos; then
|
||||
pkill zfs
|
||||
fi
|
||||
exit
|
||||
EOF'';
|
||||
};
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
+1
-3
@@ -1,3 +1 @@
|
||||
{ config, lib, pkgs, ... }: {
|
||||
imports = [ ./boot ./fileSystems ./networking ./my-config ];
|
||||
}
|
||||
{ config, lib, pkgs, ... }: { imports = [ ./boot ./fileSystems ]; }
|
||||
|
||||
@@ -41,7 +41,7 @@ in {
|
||||
};
|
||||
}) cfg.bindmounts ++ map (esp: {
|
||||
"/boot/efis/${esp}" = {
|
||||
device = "${config.zfs-root.boot.devNodes}/${esp}";
|
||||
device = "${config.zfs-root.boot.devNodes}${esp}";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"x-systemd.idle-timeout=1min"
|
||||
@@ -54,7 +54,7 @@ in {
|
||||
};
|
||||
}) cfg.efiSystemPartitions);
|
||||
config.swapDevices = mkDefault (map (swap: {
|
||||
device = "${config.zfs-root.boot.devNodes}/${swap}";
|
||||
device = "${config.zfs-root.boot.devNodes}${swap}";
|
||||
discardPolicy = mkDefault "both";
|
||||
randomEncryption = {
|
||||
enable = true;
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let inherit (lib) types mkIf mkDefault mkOption;
|
||||
in {
|
||||
options.my-config = {
|
||||
template.desktop.gnome.enable = mkOption {
|
||||
description = "Enable my customized GNOME desktop";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
|
||||
# if my-config.template.desktop.gnome.enable is set to true
|
||||
# set the following options
|
||||
config = mkIf config.my-config.template.desktop.gnome.enable {
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
desktopManager.gnome.enable = true;
|
||||
displayManager.gdm.enable = true;
|
||||
};
|
||||
|
||||
# GNOME must be used with a non-root user,
|
||||
# add a non-root user
|
||||
users.users.alice = {
|
||||
# Generate hashed password with "mkpasswd -m sha-512" command,
|
||||
# "!" disables login.
|
||||
# "mkpasswd" without "-m sha-512" will not work
|
||||
initialHashedPassword = "!";
|
||||
description = "Full Name";
|
||||
# Users in "wheel" group are allowed to use "doas" command
|
||||
# to obtain root permissions.
|
||||
extraGroups = [ "wheel" ];
|
||||
packages = builtins.attrValues {
|
||||
inherit (pkgs)
|
||||
mg # emacs-like editor
|
||||
jq # other programs
|
||||
;
|
||||
};
|
||||
isNormalUser = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.zfs-root.networking;
|
||||
inherit (lib) types mkDefault mkOption;
|
||||
in {
|
||||
options.zfs-root.networking = {
|
||||
hostName = mkOption {
|
||||
description = "The name of the machine. Used by nix flake.";
|
||||
type = types.str;
|
||||
default = "exampleHost";
|
||||
};
|
||||
timeZone = mkOption {
|
||||
type = types.str;
|
||||
default = "Etc/UTC";
|
||||
};
|
||||
hostId = mkOption {
|
||||
description = "Set host id";
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
networking.hostId = cfg.hostId;
|
||||
time.timeZone = cfg.timeZone;
|
||||
networking = {
|
||||
firewall.enable = mkDefault true;
|
||||
hostName = cfg.hostName;
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user