Compare commits

..

No commits in common. "805f9ace72b9b8c5b80fd91a0b189e092b1810ce" and "748a03aa7bad65e60a5ba3d42ac21d7171d8c38b" have entirely different histories.

18 changed files with 259 additions and 260 deletions

View File

@ -29,11 +29,11 @@
]
},
"locked": {
"lastModified": 1716773194,
"narHash": "sha256-rskkGmWlvYFb+CXedBiL8eWEuED0Es0XR4CkJ11RQKY=",
"lastModified": 1716431128,
"narHash": "sha256-t3T8HlX3udO6f4ilLcN+j5eC3m2gqsouzSGiriKK6vk=",
"owner": "nix-community",
"repo": "disko",
"rev": "10986091e47fb1180620b78438512b294b7e8f67",
"rev": "7ffc4354dfeb37c8c725ae1465f04a9b45ec8606",
"type": "github"
},
"original": {
@ -126,38 +126,11 @@
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": "flake-compat_2",
"gitignore": "gitignore",
"nixpkgs": [
"nixvim",
"nixpkgs"
],
"nixpkgs-stable": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1716213921,
"narHash": "sha256-xrsYFST8ij4QWaV6HEokCUNIZLjjLP1bYC60K8XiBVA=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "0e8fcc54b842ad8428c9e705cb5994eaf05c26a0",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"nixvim",
"git-hooks",
"pre-commit-hooks",
"nixpkgs"
]
},
@ -182,11 +155,11 @@
]
},
"locked": {
"lastModified": 1716847642,
"narHash": "sha256-rjEswRV0o23eBBils8lJXyIGha+l/VjV73IPg+ztxgk=",
"lastModified": 1716736760,
"narHash": "sha256-h3RmnNknKYtVA+EvUSra6QAwfZjC2q1G8YA7W0gat8Y=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "10c7c219b7dae5795fb67f465a0d86cbe29f25fa",
"rev": "5d151429e1e79107acf6d06dcc5ace4e642ec239",
"type": "github"
},
"original": {
@ -255,11 +228,11 @@
"nix-secrets": {
"flake": false,
"locked": {
"lastModified": 1716900655,
"narHash": "sha256-YQBKCTcP+CKP0LWSjVlP+qQ4kbk8ZWjir/nTPIl4+Bs=",
"lastModified": 1716758960,
"narHash": "sha256-CcI0sEjih/z9ChQg81QY0+fyY//gx9KZ6CoMxAwWJBA=",
"ref": "refs/heads/master",
"rev": "c000be534d2c23315a746555e82a30b512c42f65",
"revCount": 69,
"rev": "d0f16258f5867769ed35445b24286cc831ff730c",
"revCount": 60,
"type": "git",
"url": "ssh://git@git.bitlab21.com/sam/nix-secrets.git"
},
@ -318,20 +291,20 @@
"flake-compat": "flake-compat",
"flake-parts": "flake-parts",
"flake-root": "flake-root",
"git-hooks": "git-hooks",
"home-manager": "home-manager_2",
"nix-darwin": "nix-darwin",
"nixpkgs": [
"nixpkgs"
],
"pre-commit-hooks": "pre-commit-hooks",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1716833970,
"narHash": "sha256-K3tVrTna4EN86GW9IeOQJkbj57zT2xNGJg1hh26xy5c=",
"lastModified": 1716746631,
"narHash": "sha256-0/G9FQaVm321BoCKREwRqr4l93ZwtvW+4x8gjN67bWs=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "a2afa5634495ee739e682e5ccb743c5c6dd90ec1",
"rev": "9697385115fe557468b2ddcbd1277602b3e58d5e",
"type": "github"
},
"original": {
@ -340,6 +313,33 @@
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat_2",
"gitignore": "gitignore",
"nixpkgs": [
"nixvim",
"nixpkgs"
],
"nixpkgs-stable": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1716213921,
"narHash": "sha256-xrsYFST8ij4QWaV6HEokCUNIZLjjLP1bYC60K8XiBVA=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "0e8fcc54b842ad8428c9e705cb5994eaf05c26a0",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"root": {
"inputs": {
"disko": "disko",

View File

@ -8,5 +8,4 @@
home.packages = [
pkgs.ripgrep
];
home.stateVersion = "23.11";
}

View File

@ -3,28 +3,17 @@ let
pubKeys = lib.filesystem.listFilesRecursive (../common/users/keys);
secretsDirectory = builtins.toString inputs.nix-secrets;
secretsFile = "${secretsDirectory}/secrets.yaml";
sopsHashedPasswordFile = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."passwords/root".path;
hasOptinPersistence = config.environment.persistence ? "/persist";
# Disko setup
fsType = "btrfs";
dev = "/dev/vda";
encrypted = true;
btrfsMountDevice = if encrypted then "/dev/mapper/crypted" else "/dev/root_vg/root";
in
{
imports =
[
# Disk configuration
inputs.sops-nix.nixosModules.sops
# Disk configuration
inputs.disko.nixosModules.disko
(import ../common/disks { device = dev; fsType = fsType; encrypted = encrypted; })
# Impermanence
(import ../common/disks/luks-btrfs-subvolumes.nix { device = "/dev/vda" ; })
#(import ../common/disks/std-disk-config.nix { device = "/dev/vda" ; })
../common/optional/btrfs-impermanence.nix
inputs.impermanence.nixosModules.impermanence
(import ../common/disks/btrfs-impermanence.nix { btrfsMountDevice = btrfsMountDevice; lib = lib; })
# Import core options
./hardware-configuration.nix
@ -50,9 +39,11 @@ in
files = [
"/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/ssh_host_ed25519_key.pub"
"/etc/ssh/deploy_key-ssh-ed25519"
];
};
i18n.defaultLocale = "en_GB.UTF-8";
console = {
font = "Lat2-Terminus16";
@ -73,7 +64,7 @@ in
mutableUsers = true;
extraUsers = {
root = {
hashedPasswordFile = sopsHashedPasswordFile;
initialPassword = "1234";
openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key);
};
};
@ -90,7 +81,7 @@ in
validateSopsFiles = false;
age = {
sshKeyPaths = [ "${lib.optionalString hasOptinPersistence "/persist"}/etc/ssh/ssh_host_ed25519_key" ];
sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
};
secrets = {
"passwords/root".neededForUsers = true;
@ -113,7 +104,7 @@ in
ports = [22];
authorizedKeysFiles = lib.mkForce ["/etc/ssh/authorized_keys.d/%u"];
hostKeys = [{
path = "${lib.optionalString hasOptinPersistence "/persist"}/persist/etc/ssh/ssh_host_ed25519_key";
path = "/persist/etc/ssh/ssh_host_ed25519_key";
type = "ed25519";
}];
settings = {

View File

@ -6,6 +6,7 @@ in
imports = [
./sops.nix
./locale.nix
inputs.impermanence.nixosModules.impermanence
];
nixpkgs = {
@ -43,5 +44,4 @@ in
pkgs.vim
];
system.stateVersion = "23.11";
}

View File

@ -1,37 +0,0 @@
{device ? throw "Must define a device, e.g. /dev/sda"}:
{
disko.devices = {
disk = {
vdb = {
type = "disk";
inherit device;
content = {
type = "gpt";
partitions = {
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"defaults"
];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
passwordFile = "/tmp/luks_secret.key"; # Interactive
content = (import ./btrfs-persist.nix);
};
};
};
};
};
};
};
}

View File

@ -1,45 +0,0 @@
{device ? throw "Must define a device, e.g. /dev/sda"}:
{
disko.devices = {
disk.main = {
inherit device;
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = {
priority = 1;
name = "ESP";
start = "1M";
end = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
name = "root";
size = "100%";
content = {
type = "lvm_pv";
vg = "root_vg";
};
};
};
};
};
lvm_vg = {
root_vg = {
type = "lvm_vg";
lvs = {
root = {
size = "100%FREE";
content = (import ./btrfs-persist.nix);
};
};
};
};
};
}

View File

@ -1,25 +0,0 @@
{
type = "btrfs";
extraArgs = ["-f"];
subvolumes = {
"/root" = {
mountpoint = "/";
};
"/persist" = {
mountOptions = [ "subvol=persist" ];
mountpoint = "/persist";
};
"/nix" = {
mountOptions = [ "subvol=nix" "noatime" ];
mountpoint = "/nix";
};
"/swap" = {
mountOptions = [ "noatime" ];
mountpoint = "/.swapvol";
swap.swapfile.size = "8192M";
};
};
}

View File

@ -1,11 +0,0 @@
{ device, fsType, encrypted, ... }:
let
# basic and perists configs. basic fs = ext4, persist fs = btrfs either encrypted or under lvm
basic = import ./gpt-bios-compact.nix { inherit device; };
btrfs-persist-lvm = import ./btrfs-lvm.nix { inherit device; };
btrfs-persist-luks = import ./btrfs-luks.nix { inherit device; };
in
if fsType == "ext4" then basic
else if fsType == "btrfs" && encrypted then btrfs-persist-luks
else if fsType == "btrfs" then btrfs-persist-lvm
else null # or some default value

View File

@ -3,7 +3,7 @@
disko.devices = {
disk = {
vda = {
inherit device;
device = "/dev/vda";
type = "disk";
content = {
type = "gpt";

View File

@ -0,0 +1,66 @@
{device ? throw "Must define a device, e.g. /dev/sda"}:
{
disko.devices = {
disk = {
vdb = {
type = "disk";
inherit device;
content = {
type = "gpt";
partitions = {
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"defaults"
];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
# disable settings.keyFile if you want to use interactive password entry
passwordFile = "/tmp/luks_secret.key"; # Interactive
# settings = {
# allowDiscards = true;
# keyFile = "${sopsHashedPasswordFile}";
# };
content = {
type = "btrfs";
extraArgs = ["-f"];
subvolumes = {
"/root" = {
mountpoint = "/";
};
"/persist" = {
mountOptions = [ "subvol=persist" ];
mountpoint = "/persist";
};
"/nix" = {
mountOptions = [ "subvol=nix" "noatime" ];
mountpoint = "/nix";
};
"/swap" = {
mountOptions = [ "noatime" ];
mountpoint = "/.swapvol";
swap.swapfile.size = "8192M";
};
};
};
};
};
};
};
};
};
};
}

View File

@ -0,0 +1,69 @@
{device ? throw "Must define a device, e.g. /dev/sda"}:
{
disko.devices = {
disk.main = {
inherit device;
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = {
priority = 1;
name = "ESP";
start = "1M";
end = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
name = "root";
size = "100%";
content = {
type = "lvm_pv";
vg = "root_vg";
};
};
};
};
};
lvm_vg = {
root_vg = {
type = "lvm_vg";
lvs = {
root = {
size = "100%FREE";
content = {
type = "btrfs";
extraArgs = ["-f"];
subvolumes = {
"/root" = {
mountpoint = "/";
};
"/persist" = {
mountOptions = [ "subvol=persist" ];
mountpoint = "/persist";
};
"/nix" = {
mountOptions = [ "subvol=nix" "noatime" ];
mountpoint = "/nix";
};
"/swap" = {
mountOptions = [ "noatime" ];
mountpoint = "/.swapvol";
swap.swapfile.size = "8192M";
};
};
};
};
};
};
};
};
}

View File

@ -1,11 +1,8 @@
{lib, btrfsMountDevice, ...}:
let
device = btrfsMountDevice;
in
{lib, ...}:
{
boot.initrd.postDeviceCommands = lib.mkAfter ''
mkdir /btrfs_tmp
mount ${device} /btrfs_tmp
mount /dev/mapper/crypted /btrfs_tmp
if [[ -e /btrfs_tmp/root ]]; then
mkdir -p /btrfs_tmp/old_roots
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S")

View File

@ -8,12 +8,9 @@
"/var/lib/nixos"
"/var/lib/systemd/coredump"
"/etc/NetworkManager/system-connections"
"/var/lib/flatpak"
"/run/secrets-for-users"
];
files = [
"/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/deploy_key-ssh-ed25519"
"/etc/ssh/ssh_host_ed25519_key.pub"
];
};

View File

@ -1,55 +1,24 @@
{ pkgs, inputs, config, lib, ... }:
let
username = "admin";
pubKeys = lib.filesystem.listFilesRecursive (../keys);
hostname = config.networking.hostName;
sopsHashedPasswordFile = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."passwords/${username}".path;
secretsDirectory = builtins.toString inputs.nix-secrets;
secretsFile = "${secretsDirectory}/secrets.yaml";
in
{
users.users.${username} = {
users.users.admin = {
isNormalUser = true;
password = "nixos"; # Overridden if sops is working
shell = pkgs.zsh; # default shell
hashedPasswordFile = sopsHashedPasswordFile;
openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key);
extraGroups =
[
"wheel"
[ "qemu-libvirtd" "libvirtd"
"wheel" "video" "audio" "disk" "networkmanager"
];
packages = with pkgs; [
flatpak
gnome.gnome-software
];
};
sops.secrets = {
"passwords/${username}" = {
sopsFile = "${secretsFile}";
neededForUsers = true;
};
"ssh_keys/${username}/id_ed25519" = {
path = "/home/${username}/.ssh/id_ed25519";
mode = "0600";
owner = "${username}";
};
"ssh_keys/${username}/id_ed25519.pub" = {
path = "/home/${username}/.ssh/id_ed25519.pub";
mode = "0644";
owner = "${username}";
};
};
programs.zsh.enable = true;
programs.fuse.userAllowOther = true;
home-manager = {
extraSpecialArgs = { inherit inputs; };
users = {
${username} = import ../../../../home/${hostname}.nix;
};
};
environment.systemPackages = [
];
}

View File

@ -46,5 +46,7 @@
enableSSHSupport = true;
};
system.stateVersion = "23.11";
}

View File

@ -30,5 +30,8 @@ in
};
services.libinput.enable = true;
system.stateVersion = "23.11";
}

View File

@ -1,24 +1,17 @@
{ inputs, config, lib, pkgs, outputs,... }:
let
# Disko setup
fsType = "btrfs"; # one of ext4 or btrfs. Use btrfs if using impermanence
dev = "/dev/vda"; # depends on target hardware
encrypted = false; # currrently only applies to btrfs
btrfsMountDevice = if encrypted then "/dev/mapper/crypted" else "/dev/root_vg/root";
dev = "/dev/vda";
in
{
imports =
[
# Create users for this host
../common/users/media
# Disk configuration
inputs.disko.nixosModules.disko
(import ../common/disks { device = dev; fsType = fsType; encrypted = encrypted; })
(import ../common/disks/luks-btrfs-subvolumes.nix { device = "/dev/vda" ; })
../common/optional/btrfs-impermanence.nix
# Impermanence
inputs.impermanence.nixosModules.impermanence
(import ../common/disks/btrfs-impermanence.nix { btrfsMountDevice = btrfsMountDevice; lib = lib; })
# Create users for this host
../common/users/media
# Import core options
./hardware-configuration.nix
@ -38,6 +31,13 @@ in
};
};
environment.persistence."/persist" = {
hideMounts = true;
directories = [
"/var/lib/flatpak"
];
};
networking = {
hostName = "sparky";
networkmanager.enable = true;
@ -54,4 +54,5 @@ in
cinnamon.enable = true;
};
};
}

View File

@ -4,19 +4,17 @@ echo -e "
Before using this tool, ensure that the host has been setup correctly.
Boot the latest Nixos-minimal install ISO on the host and access the tty.
Use 'ip a' to get the ip address, then 'sudo su' to change to root. Finally Run
'passwd' and set a temporary password for the root user.
Also, ensure secrets for the new host and users have been set in secrets.yaml
Use 'ip a' to get the ip address, then 'sudo su' to change to root. Finally
Run 'passwd' and set a temporary password (something simple like '1234')
for the root user.
"
read -p "Confirm host had been setup using the above steps...(yes|no): " confirm
[ "$confirm" != "yes" ] && echo "Exiting" && exit 0
read -p "Enter hostname of target: " hostname
read -p "Enter IP of target: " ip
read -p "Enter config to install on target: " config
read -p "Enter username (if none, use 'root'): " username
hostname="sparky"
ip="192.168.122.193"
config="bootstrap"
# Delete key in known hosts if exists
sed -i "/$ip/d" ~/.ssh/known_hosts
@ -26,29 +24,28 @@ echo "Copying pubkey to target host"
ssh-copy-id -i "$(readlink -f "$HOME/.ssh/id_ed25519.pub")" "root@$ip"
# Create temp directory for ssh and luks keys to be copied to host:
temp=$(mktemp -d)
temp_ssh=$(mktemp -d)
touch /tmp/luks_secret.key
# Function to cleanup temporary directory on exit
cleanup() {
rm -rf "$temp" /tmp/luks_secret.key
rm -rf "$temp_ssh" /tmp/luks_secret.key
}
trap cleanup EXIT
# Create the directory for target host keys
install -d -m755 "$temp/persist/etc/ssh"
# Create the directory where sshd expects to find the host keys
install -d -m755 "$temp_ssh/persist/etc/ssh"
# Create ssh keys
# Create ssh keys if not exists
echo "Creating '$hostname' ssh keys"
ssh-keygen -t ed25519 -f "$temp/persist/etc/ssh/ssh_host_ed25519_key" -C root@"$hostname" -N ""
ssh-keygen -t ed25519 -f "$temp_ssh/persist/etc/ssh/ssh_host_ed25519_key" -C root@"$hostname" -N ""
# Extract luks key from secrets
luks_secret=$(nix-shell -p sops --run "SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt sops -d --extract '[""\"luks_passphrase""\"][""\"$hostname""\"]' ../nix-secrets/secrets.yaml")
echo "$luks_secret" > /tmp/luks_secret.key
chmod 600 "$temp_ssh/persist/etc/ssh/ssh_host_ed25519_key"
chmod 644 "$temp_ssh/persist/etc/ssh/ssh_host_ed25519_key.pub"
# Generate age key from target host and user public ssh key
echo "Generating age key from target host and user ssh key"
HOST_AGE_KEY=$(nix-shell -p ssh-to-age --run "cat $temp/persist/etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age")
HOST_AGE_KEY=$(nix-shell -p ssh-to-age --run "cat $temp_ssh/persist/etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age")
echo -e "Host age key:\n$HOST_AGE_KEY\n"
# Update .sops.yaml with new age key:
@ -63,20 +60,46 @@ sed -i "{
/&hosts:/{n; p; s/\(.*- &\).*/\1$hostname $HOST_AGE_KEY/}
}" $SOPS_FILE
# Commit and push changes to sops file
just update-sops-secrets && just update-flake-secrets && just update-flake
# Copy current nix config over to target
cp -prv . "$temp/persist/etc/nixos"
# Extract luks key from secrets
luks_secret=$(nix-shell -p sops --run "SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt sops -d --extract '[""\"luks_passphrase""\"][""\"sparky""\"]' ../nix-secrets/secrets.yaml")
echo "$luks_secret" > /tmp/luks_secret.key
# Install Nixos to target
SHELL=/bin/sh nix run github:nix-community/nixos-anywhere/242444d228636b1f0e89d3681f04a75254c29f66 -- --extra-files "$temp" --disk-encryption-keys /tmp/luks_secret.key /tmp/luks_secret.key --flake .#"$config" root@"$ip" -i "$HOME/.ssh/id_ed25519"
cd "$HOME/nixos"
git add . && git commit -m "auto: bootstrapping $hostname" && git push
SHELL=/bin/sh nix run github:nix-community/nixos-anywhere/242444d228636b1f0e89d3681f04a75254c29f66 -- --extra-files "$temp_ssh" --disk-encryption-keys /tmp/luks_secret.key /tmp/luks_secret.key --flake .#"$config" root@"$ip" -i "$HOME/.ssh/id_ed25519"
[ $? != 0 ] && echo "Error installing Nixos" && exit 1
## Delete keys from local known_hosts
echo "Deleting host from known_hosts"
sed -i "/$ip/d" ~/.ssh/known_hosts
# Check host OS has booted (and not booted back into live cd)
while true;
do
read -p "Confirm live CD has been removed... (yes|no): " confirm
[ "$confirm" = "yes" ] && break
done
echo "Waiting for $ip to come back online and port 22 to be open..."
while ! ping -c 1 $ip &> /dev/null || ! nc -zvw3 $ip 22 &> /dev/null
do
echo "$ip is still offline or port 22 is not open. Checking again in 5 seconds..."
sleep 5
done
echo "$ip is now online and port 22 is open!"
# Authorise source public key
echo "Copying pubkey to target host"
ssh-copy-id -i "$(readlink -f "$HOME/.ssh/id_ed25519.pub")" "root@$ip"
# Copy deploy_key to target for personal repo authorisation
scp -i "$(readlink -f "$HOME/.ssh/id_ed25519")" "$(readlink -f "$HOME/.ssh/deploy_key-ssh-ed25519")" "root@$ip:/persist/etc/ssh/deploy_key-ssh-ed25519"
ssh -i "$(readlink -f "$HOME/.ssh/id_ed25519")" "root@$ip" "nix-shell -p git --run 'git clone git@git.bitlab21.com:sam/nixos.git /persist/etc/nixos/'"
echo -e "###\nSuccessfully installed Nixos on the target host!\n###"
exit 0