parametised disk formatting and fixed secrets issue in bootstrapping

This commit is contained in:
Sam 2024-05-28 14:06:33 +01:00
parent 2910b2d267
commit 805f9ace72
10 changed files with 41 additions and 64 deletions

View File

@ -182,11 +182,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1716736760, "lastModified": 1716847642,
"narHash": "sha256-h3RmnNknKYtVA+EvUSra6QAwfZjC2q1G8YA7W0gat8Y=", "narHash": "sha256-rjEswRV0o23eBBils8lJXyIGha+l/VjV73IPg+ztxgk=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "5d151429e1e79107acf6d06dcc5ace4e642ec239", "rev": "10c7c219b7dae5795fb67f465a0d86cbe29f25fa",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -255,11 +255,11 @@
"nix-secrets": { "nix-secrets": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1716823135, "lastModified": 1716900655,
"narHash": "sha256-2+nqAgrQ11TRNKsMR3eTRrBWfRKBSxEl500g8fL5WgI=", "narHash": "sha256-YQBKCTcP+CKP0LWSjVlP+qQ4kbk8ZWjir/nTPIl4+Bs=",
"ref": "refs/heads/master", "ref": "refs/heads/master",
"rev": "3685717aaa6091e50eb2018b9375b07cf33780a6", "rev": "c000be534d2c23315a746555e82a30b512c42f65",
"revCount": 64, "revCount": 69,
"type": "git", "type": "git",
"url": "ssh://git@git.bitlab21.com/sam/nix-secrets.git" "url": "ssh://git@git.bitlab21.com/sam/nix-secrets.git"
}, },
@ -327,11 +327,11 @@
"treefmt-nix": "treefmt-nix" "treefmt-nix": "treefmt-nix"
}, },
"locked": { "locked": {
"lastModified": 1716814660, "lastModified": 1716833970,
"narHash": "sha256-lDy4PXkwQs3qBxVCdwOcNDJbWBCMJcoGfsHnr3U3Okg=", "narHash": "sha256-K3tVrTna4EN86GW9IeOQJkbj57zT2xNGJg1hh26xy5c=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixvim", "repo": "nixvim",
"rev": "4175fac0ea144679b9818bfc3c7becfbd68e25a4", "rev": "a2afa5634495ee739e682e5ccb743c5c6dd90ec1",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

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

View File

@ -3,6 +3,8 @@ let
pubKeys = lib.filesystem.listFilesRecursive (../common/users/keys); pubKeys = lib.filesystem.listFilesRecursive (../common/users/keys);
secretsDirectory = builtins.toString inputs.nix-secrets; secretsDirectory = builtins.toString inputs.nix-secrets;
secretsFile = "${secretsDirectory}/secrets.yaml"; 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 # Disko setup
fsType = "btrfs"; fsType = "btrfs";
@ -48,7 +50,6 @@ in
files = [ files = [
"/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/deploy_key-ssh-ed25519"
]; ];
}; };
@ -72,7 +73,7 @@ in
mutableUsers = true; mutableUsers = true;
extraUsers = { extraUsers = {
root = { root = {
initialPassword = "1234"; hashedPasswordFile = sopsHashedPasswordFile;
openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key); openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key);
}; };
}; };
@ -89,7 +90,7 @@ in
validateSopsFiles = false; validateSopsFiles = false;
age = { age = {
sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; sshKeyPaths = [ "${lib.optionalString hasOptinPersistence "/persist"}/etc/ssh/ssh_host_ed25519_key" ];
}; };
secrets = { secrets = {
"passwords/root".neededForUsers = true; "passwords/root".neededForUsers = true;
@ -112,7 +113,7 @@ in
ports = [22]; ports = [22];
authorizedKeysFiles = lib.mkForce ["/etc/ssh/authorized_keys.d/%u"]; authorizedKeysFiles = lib.mkForce ["/etc/ssh/authorized_keys.d/%u"];
hostKeys = [{ hostKeys = [{
path = "/persist/etc/ssh/ssh_host_ed25519_key"; path = "${lib.optionalString hasOptinPersistence "/persist"}/persist/etc/ssh/ssh_host_ed25519_key";
type = "ed25519"; type = "ed25519";
}]; }];
settings = { settings = {

View File

@ -43,4 +43,5 @@ in
pkgs.vim pkgs.vim
]; ];
system.stateVersion = "23.11";
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -54,5 +54,4 @@ in
cinnamon.enable = true; cinnamon.enable = true;
}; };
}; };
} }

View File

@ -4,9 +4,10 @@ echo -e "
Before using this tool, ensure that the host has been setup correctly. 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. 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 Use 'ip a' to get the ip address, then 'sudo su' to change to root. Finally Run
Run 'passwd' and set a temporary password (something simple like '1234') 'passwd' and set a temporary password for the root user.
for the root user.
Also, ensure secrets for the new host and users have been set in secrets.yaml
" "
read -p "Confirm host had been setup using the above steps...(yes|no): " confirm read -p "Confirm host had been setup using the above steps...(yes|no): " confirm
@ -15,6 +16,7 @@ read -p "Confirm host had been setup using the above steps...(yes|no): " confirm
read -p "Enter hostname of target: " hostname read -p "Enter hostname of target: " hostname
read -p "Enter IP of target: " ip read -p "Enter IP of target: " ip
read -p "Enter config to install on target: " config read -p "Enter config to install on target: " config
read -p "Enter username (if none, use 'root'): " username
# Delete key in known hosts if exists # Delete key in known hosts if exists
sed -i "/$ip/d" ~/.ssh/known_hosts sed -i "/$ip/d" ~/.ssh/known_hosts
@ -24,28 +26,29 @@ echo "Copying pubkey to target host"
ssh-copy-id -i "$(readlink -f "$HOME/.ssh/id_ed25519.pub")" "root@$ip" 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: # Create temp directory for ssh and luks keys to be copied to host:
temp_ssh=$(mktemp -d) temp=$(mktemp -d)
touch /tmp/luks_secret.key touch /tmp/luks_secret.key
# Function to cleanup temporary directory on exit # Function to cleanup temporary directory on exit
cleanup() { cleanup() {
rm -rf "$temp_ssh" /tmp/luks_secret.key rm -rf "$temp" /tmp/luks_secret.key
} }
trap cleanup EXIT trap cleanup EXIT
# Create the directory where sshd expects to find the host keys # Create the directory for target host keys
install -d -m755 "$temp_ssh/persist/etc/ssh" install -d -m755 "$temp/persist/etc/ssh"
# Create ssh keys if not exists # Create ssh keys
echo "Creating '$hostname' ssh keys" echo "Creating '$hostname' ssh keys"
ssh-keygen -t ed25519 -f "$temp_ssh/persist/etc/ssh/ssh_host_ed25519_key" -C root@"$hostname" -N "" ssh-keygen -t ed25519 -f "$temp/persist/etc/ssh/ssh_host_ed25519_key" -C root@"$hostname" -N ""
chmod 600 "$temp_ssh/persist/etc/ssh/ssh_host_ed25519_key" # Extract luks key from secrets
chmod 644 "$temp_ssh/persist/etc/ssh/ssh_host_ed25519_key.pub" 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
# Generate age key from target host and user public ssh key # Generate age key from target host and user public ssh key
echo "Generating age key from target host and user 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_ssh/persist/etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age") HOST_AGE_KEY=$(nix-shell -p ssh-to-age --run "cat $temp/persist/etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age")
echo -e "Host age key:\n$HOST_AGE_KEY\n" echo -e "Host age key:\n$HOST_AGE_KEY\n"
# Update .sops.yaml with new age key: # Update .sops.yaml with new age key:
@ -60,45 +63,20 @@ sed -i "{
/&hosts:/{n; p; s/\(.*- &\).*/\1$hostname $HOST_AGE_KEY/} /&hosts:/{n; p; s/\(.*- &\).*/\1$hostname $HOST_AGE_KEY/}
}" $SOPS_FILE }" $SOPS_FILE
# Extract luks key from secrets # Commit and push changes to sops file
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") just update-sops-secrets && just update-flake-secrets && just update-flake
echo "$luks_secret" > /tmp/luks_secret.key
# Copy current nix config over to target
cp -prv . "$temp/persist/etc/nixos"
# Install Nixos to target # Install Nixos to target
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" 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"
[ $? != 0 ] && echo "Error installing Nixos" && exit 1 [ $? != 0 ] && echo "Error installing Nixos" && exit 1
## Delete keys from local known_hosts ## Delete keys from local known_hosts
echo "Deleting host from known_hosts" echo "Deleting host from known_hosts"
sed -i "/$ip/d" ~/.ssh/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!"
# Commit and push changes
just update-sops-secrets && just update-flake-secrets && just update-flake
git add . && git commit -m "auto: bootstrapping $hostname" && git push
# 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###" echo -e "###\nSuccessfully installed Nixos on the target host!\n###"
exit 0 exit 0