#!/usr/bin/env bash 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 (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 # Delete key in known hosts if exists sed -i "/$ip/d" ~/.ssh/known_hosts # Authorise source public key 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_ssh=$(mktemp -d) touch /tmp/luks_secret.key # Function to cleanup temporary directory on exit cleanup() { rm -rf "$temp_ssh" /tmp/luks_secret.key } trap cleanup EXIT # Create the directory where sshd expects to find the host keys install -d -m755 "$temp_ssh/persist/etc/ssh" # Create ssh keys if not exists echo "Creating '$hostname' ssh keys" ssh-keygen -t ed25519 -f "$temp_ssh/persist/etc/ssh/ssh_host_ed25519_key" -C root@"$hostname" -N "" 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_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: SOPS_FILE="../nix-secrets/.sops.yaml" sed -i "{ # Remove any * and & entries for this host /[*&]$hostname/ d; # Inject a new age: entry # n matches the first line following age: and p prints it, then we transform it while reusing the spacing /age:/{n; p; s/\(.*- \*\).*/\1$hostname/}; # Inject a new hosts: entry /&hosts:/{n; p; s/\(.*- &\).*/\1$hostname $HOST_AGE_KEY/} }" $SOPS_FILE # 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 # 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" [ $? != 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!" # 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###" exit 0