diff --git a/nixos-infra/modules/secrets/default.nix b/nixos-infra/modules/secrets/default.nix new file mode 100644 index 0000000..f12a23a --- /dev/null +++ b/nixos-infra/modules/secrets/default.nix @@ -0,0 +1,22 @@ +{ config, pkgs, lib, ... }: + +{ + options.secrets = { + enable = lib.mkEnableOption "agenix secret management"; + + identity = lib.mkOption { + type = lib.types.path; + default = "/etc/ssh/ssh_host_ed25519_key"; + description = "Path to the SSH host private key used for age decryption."; + }; + }; + + config = lib.mkIf config.secrets.enable { + age = { + identityPaths = [ config.secrets.identity ]; + secrets = { }; + }; + + environment.systemPackages = with pkgs; [ agenix ]; + }; +} \ No newline at end of file diff --git a/nixos-infra/overlays/custom-pkgs.nix b/nixos-infra/overlays/custom-pkgs.nix index e69de29..974bce8 100644 --- a/nixos-infra/overlays/custom-pkgs.nix +++ b/nixos-infra/overlays/custom-pkgs.nix @@ -0,0 +1,4 @@ +self: super: { + # Custom packages and overrides for nixos-infra + # agenix is already available in nixpkgs — no custom overlay needed. +} \ No newline at end of file diff --git a/nixos-infra/scripts/README.md b/nixos-infra/scripts/README.md index 38ce134..7391e17 100644 --- a/nixos-infra/scripts/README.md +++ b/nixos-infra/scripts/README.md @@ -1,4 +1,107 @@ # Scripts + Utility scripts for infrastructure management. -Covers deployment, LXC container creation, and -initial bootstrap of new NixOS machines. +Covers deployment, LXC container creation and bootstrap, +initial configuration of new NixOS machines, and age key generation. + +## Scripts Overview + +### `create-lxc-nixos.sh` — Create and deploy a NixOS LXC container + +Creates a NixOS LXC container on a remote Proxmox VE hypervisor, then +bootstraps it with the initial NixOS configuration and runs `deploy.sh` +to apply the host-specific configuration. + +```bash +# Usage +./create-lxc-nixos.sh [options] + +# Example: create dns01 with static IPv4 and IPv6 token +./create-lxc-nixos.sh dns01 \ + --ip 10.40.0.10/24 \ + --ip6 ::a:b:c:d \ + --pve-host pve01.prod.lagraula.fr + +# Dry run to preview the commands +./create-lxc-nixos.sh dns01 --dry-run +``` + +**Bootstrap process:** +1. `pct create` — create the container from the NixOS template +2. `pct start ` — start the container +3. Wait for the container to be ready (polling `pct exec`) +4. `pct push initial-configuration.nix` → `/etc/nixos/configuration.nix` +5. `pct push deploy.sh` → `/usr/local/bin/deploy-nixos` +6. `pct exec nixos-rebuild switch` — apply initial config (SSH, git, curl) +7. `pct exec deploy-nixos` — clone repo and apply host-specific config + +### `deploy.sh` — Deploy NixOS configuration from Git repository + +Clones or updates the nixos-infra repository, detects the hostname, +finds the corresponding configuration file, and applies it with +`nixos-rebuild switch`. + +```bash +# Usage +./deploy.sh [options] + +# Options +-u, --repo-url URL Git repository URL (default: https://gitea.lagraula.fr/...) +-d, --repo-dir DIR Local directory (default: /etc/nixos-infra) +-b, --branch BRANCH Git branch (default: main) +-n, --dry-run Simulate without making changes +``` + +**Configuration lookup order:** +1. `hosts/servers//configuration.nix` +2. `hosts/workstations//configuration.nix` + +### `initial-configuration.nix` — Bootstrap NixOS configuration + +Minimal NixOS configuration pushed to a new LXC container during the +bootstrap phase. Installs SSH, git, and curl so the container can +clone the repository and apply its specific configuration. + +**Pushed to `/etc/nixos/configuration.nix` by `create-lxc-nixos.sh`.** + +### `gen-secrets-keys.sh` — Generate age public keys for agenix + +Connects to each host in the infrastructure, retrieves its SSH host +key via `ssh-keyscan`, converts it to an age public key with +`ssh-to-age`, and stores it in `secrets/pubkeys/.age`. + +```bash +# Usage +./gen-secrets-keys.sh + +# Prerequisites +# nix-shell -p ssh-to-age +``` + +**After generating keys, encrypt secrets with:** +```bash +age -r $(cat secrets/pubkeys/.age) -o secrets/.age +agenix -e secrets/.age +``` + +### `update-nixpkgs.sh` — Update the nixpkgs pin + +Updates `pkgs/nixpkgs.json` with the latest commit from nixpkgs unstable. + +## Deployment workflow (LXC containers) + +``` +create-lxc-nixos.sh # Step 1: Create + bootstrap + └─ pct create + └─ pct push initial-configuration.nix + └─ pct push deploy.sh + └─ pct exec nixos-rebuild switch + └─ pct exec deploy.sh # Step 2: Clone repo + apply config + └─ git clone + └─ nixos-rebuild switch (host-specific) +``` + +For subsequent updates on an already-deployed container: +```bash +ssh +sudo /usr/local/bin/deploy-nixos \ No newline at end of file diff --git a/nixos-infra/scripts/create-lxc-nixos.sh b/nixos-infra/scripts/create-lxc-nixos.sh index 09332bc..a9889d1 100755 --- a/nixos-infra/scripts/create-lxc-nixos.sh +++ b/nixos-infra/scripts/create-lxc-nixos.sh @@ -10,35 +10,42 @@ if ! command -v docopts &> /dev/null; then fi # --- Usage and Documentation --- -usage="Create and configure an LXC container on a remote Proxmox VE 9 server. +usage="Create, bootstrap and deploy a NixOS LXC container on a remote Proxmox VE 9 server. Usage: $0 [options] $0 -h|--help Options: - -h, --help Show this message. - -t, --template TEMPLATE LXC template (e.g. local:vztmpl/nixos-unstable). - -r, --rootfs-size SIZE Root filesystem size (e.g. 8G). - -c, --cores CORES Number of CPU cores. - -m, --memory MEMORY RAM in MiB. - -s, --swap SWAP Swap in MiB. - -p, --password PASSWORD Root password for the container. - -b, --bridge BRIDGE Network bridge (e.g. vmbr0). - -v, --vlan VLAN VLAN tag (e.g. tag=10). - -d, --domain DOMAIN DNS domain. - -u, --unprivileged UNPRIV Unprivileged container (0 or 1). - -i, --ip IP Static IP (e.g. 192.168.1.100/24). - -C, --cmode CMODE Console mode (console or tty). Default: console. - -T, --tags TAGS Tags for the container (optional). - -k, --ssh-public-keys KEYS SSH public keys for the container. - --pve-host HOST Proxmox host (e.g. pve). - --pve-user USER Proxmox user (default: admin). - --pve-port PORT SSH port for Proxmox (default: 22). - --pve-ssh-key KEY SSH key file for authentication. - --dry-run Simulate container creation without execution. + -h, --help Show this message. + -t, --template TEMPLATE LXC template (e.g. local:vztmpl/nixos-unstable). + -r, --rootfs-size SIZE Root filesystem size (e.g. 8G). + -c, --cores CORES Number of CPU cores. + -m, --memory MEMORY RAM in MiB. + -s, --swap SWAP Swap in MiB. + -p, --password PASSWORD Root password for the container. + -b, --bridge BRIDGE Network bridge (e.g. vmbr0). + -v, --vlan VLAN VLAN tag (e.g. tag=10). + -d, --domain DOMAIN DNS domain. + -u, --unprivileged UNPRIV Unprivileged container (0 or 1). + -i, --ip IP Static IPv4 address (e.g. 192.168.1.100/24). + --ip6 TOKEN IPv6 token for SLAAC (e.g. ::1:2:3:4). + -C, --cmode CMODE Console mode (console or tty). Default: console. + -T, --tags TAGS Tags for the container (optional). + -k, --ssh-public-keys KEYS SSH public keys for the container. + --pve-host HOST Proxmox host (e.g. pve). + --pve-user USER Proxmox user (default: admin). + --pve-port PORT SSH port for Proxmox (default: 22). + --pve-ssh-key KEY SSH key file for authentication. + --initial-config FILE Initial NixOS configuration file to push + [default: ./initial-configuration.nix]. + --repo-url URL Git repository URL for deploy.sh + [default: https://gitea.lagraula.fr/xavier/nixos-infra.git]. + --branch BRANCH Git branch for deploy.sh [default: main]. + --skip-deploy Skip the post-creation bootstrap (push + nixos-rebuild). + --dry-run Simulate container creation without execution. -Optional configuration files: +Optional configuration files (loaded in order, later overrides earlier): /etc/nixos-infra/hosts/config \${XDG_CONFIG_HOME}/nixos-infra/hosts/config ./config @@ -64,10 +71,17 @@ VLAN="${VLAN:-}" DOMAIN="${DOMAIN:-lagraula.fr}" UNPRIVILEGED="${UNPRIVILEGED:-0}" IP="${IP:-}" +IP6="${IP6:-}" CMODE="${CMODE:-console}" TAGS="${TAGS:-}" SSH_PUBLIC_KEYS="${SSH_PUBLIC_KEYS:-}" +# Bootstrap +INITIAL_CONFIG="${INITIAL_CONFIG:-./initial-configuration.nix}" +REPO_URL="${REPO_URL:-https://gitea.lagraula.fr/xavier/nixos-infra.git}" +BRANCH="${BRANCH:-main}" +SKIP_DEPLOY="${SKIP_DEPLOY:-false}" + # --- Parse Arguments with docopts (Highest priority) --- # set +e is to prevent set -e from eating the error message from docopts. # This code is up here to prevent useless error messages to be printed @@ -90,18 +104,17 @@ for conffile in ${CONFIG_FILES[*]}; do source "$conffile" set +a else - echo "❌ $conffile not found." + echo "ℹ️ $conffile not found (optional)." fi done -# Proxmox Server +# Override with CLI arguments (have priority over config files) PVE_HOST="${pve_host:-$PVE_HOST}" PVE_USER="${pve_user:-$PVE_USER}" PVE_PORT="${pve_port:-$PVE_PORT}" PVE_SSH_KEY="${pve_ssh_key:-$PVE_SSH_KEY}" DRY_RUN="${dry_run:-$DRY_RUN}" -# LXC Container TEMPLATE="${template:-$TEMPLATE}" ROOTFS_SIZE="${rootfs_size:-$ROOTFS_SIZE}" CORES="${cores:-$CORES}" @@ -113,10 +126,16 @@ VLAN="${vlan:-$VLAN}" DOMAIN="${domain:-$DOMAIN}" UNPRIVILEGED="${unprivileged:-$UNPRIVILEGED}" IP="${ip:-$IP}" +IP6="${ip6:-$IP6}" CMODE="${cmode:-$CMODE}" TAGS="${tags:-$TAGS}" SSH_PUBLIC_KEYS="${ssh_public_keys:-$SSH_PUBLIC_KEYS}" +INITIAL_CONFIG="${initial_config:-$INITIAL_CONFIG}" +REPO_URL="${repo_url:-$REPO_URL}" +BRANCH="${branch:-$BRANCH}" +SKIP_DEPLOY="${skip_deploy:-$SKIP_DEPLOY}" + # --- SSH Key Default Logic --- if [ "$PVE_SSH_KEY" = "default" ]; then PVE_SSH_KEY="${HOME}/.ssh/id_${PVE_USER}" @@ -124,19 +143,19 @@ fi # --- Critical Parameters Validation --- mandatory_params=( - "TEMPLATE" \ - "ROOTFS_SIZE" \ - "CORES" \ - "MEMORY" \ - "SWAP" \ - "PASSWORD" \ - "BRIDGE" \ - "DOMAIN" \ - "UNPRIVILEGED" \ - "CMODE" \ - "SSH_PUBLIC_KEYS" \ - "PVE_HOST" \ - "PVE_USER" \ + "TEMPLATE" + "ROOTFS_SIZE" + "CORES" + "MEMORY" + "SWAP" + "PASSWORD" + "BRIDGE" + "DOMAIN" + "UNPRIVILEGED" + "CMODE" + "SSH_PUBLIC_KEYS" + "PVE_HOST" + "PVE_USER" "PVE_PORT" ) missing_params=() @@ -145,7 +164,7 @@ for param in ${mandatory_params[*]}; do done if [ ${#missing_params[@]} -gt 0 ]; then echo "❌ Error: The following necessary parameters are missing: ${missing_params[*]}" >&2 - echo "❌ Error: Plesase provide them through one the proposed config file or the command line." >&2 + echo "❌ Error: Please provide them through a config file or the command line." >&2 exit 1 fi @@ -155,6 +174,22 @@ if [ ! -f "$PVE_SSH_KEY" ]; then exit 1 fi +# Validate initial-config.nix exists (unless --skip-deploy) +if [ "$SKIP_DEPLOY" != "true" ] && [ ! -f "$INITIAL_CONFIG" ]; then + echo "❌ Error: Initial NixOS configuration '$INITIAL_CONFIG' not found." >&2 + echo " Provide a valid path with --initial-config or use --skip-deploy." >&2 + exit 1 +fi + +# Validate deploy.sh exists (unless --skip-deploy) +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DEPLOY_SCRIPT="${SCRIPT_DIR}/deploy.sh" +if [ "$SKIP_DEPLOY" != "true" ] && [ ! -f "$DEPLOY_SCRIPT" ]; then + echo "❌ Error: deploy.sh not found at '$DEPLOY_SCRIPT'." >&2 + echo " The bootstrap phase requires deploy.sh to be present." >&2 + exit 1 +fi + # --- SSH Connection to Proxmox Server --- run_proxmox() { local ssh_cmd="ssh -p $PVE_PORT" @@ -174,9 +209,15 @@ fi if [ -n "$IP" ]; then NET_OPTS="$NET_OPTS,ip=$IP" fi -set -x +# IPv6: use SLAAC with a token if provided, otherwise DHCP +if [ -n "$IP6" ]; then + NET_OPTS="$NET_OPTS,ip6=auto,token6=${IP6}" +else + NET_OPTS="$NET_OPTS,ip6=dhcp" +fi + # --- Container Creation --- -echo "🚀 Creating LXC container $short_name on $PVE_HOST..." +echo "🚀 Creating LXC container $short_name on $PVE_HOST (domain: $DOMAIN)..." CREATE_CMD="pct create $ROOTFS_SIZE $TEMPLATE --cores $CORES \ --memory $MEMORY --swap $SWAP --hostname $short_name.$DOMAIN \ --password $PASSWORD --unprivileged $UNPRIVILEGED --net0 $NET_OPTS \ @@ -192,12 +233,89 @@ echo "🔧 Command to execute on $PVE_HOST: $DISPLAY_CMD" # Execute or simulate if [ "$DRY_RUN" = "true" ]; then - echo "🧪 Dry run: Skipping actual execution." -else - LXC_ID=$(run_proxmox "$CREATE_CMD" | grep -oP '\d+') - if [ -z "$LXC_ID" ]; then - echo "❌ Error: Failed to create the container." >&2 + echo "🧪 Dry run mode:" + echo " - Container creation skipped" + echo " - Bootstrap phase skipped" + exit 0 +fi + +LXC_ID=$(run_proxmox "$CREATE_CMD" | grep -oP '\d+') +if [ -z "$LXC_ID" ]; then + echo "❌ Error: Failed to create the container." >&2 + exit 1 +fi +echo "✅ LXC container $short_name created successfully (ID: $LXC_ID)." + +# --- Bootstrap Phase (unless --skip-deploy) --- +if [ "$SKIP_DEPLOY" = "true" ]; then + echo "⏭️ --skip-deploy set. Container created but not bootstrapped." + echo " Start it manually with: pct start $LXC_ID" + echo " Then apply a configuration manually." + exit 0 +fi + +echo "" +echo "🚀 Starting bootstrap phase for CT $LXC_ID..." + +# 1. Start the container +echo "▶️ Starting container $LXC_ID..." +run_proxmox "pct start $LXC_ID" || { + echo "❌ Error: Failed to start container $LXC_ID." >&2 + exit 1 +} + +# 2. Wait for the container to be ready (SSH or pct exec available) +echo "⏳ Waiting for container to be ready..." +for i in $(seq 1 30); do + if run_proxmox "pct exec $LXC_ID -- true" 2>/dev/null; then + echo "✅ Container $LXC_ID is ready." + break + fi + if [ "$i" -eq 30 ]; then + echo "❌ Error: Container $LXC_ID did not become ready in time." >&2 + echo " You can retry bootstrap manually." >&2 exit 1 fi - echo "✅ LXC container $short_name created successfully (ID: $LXC_ID)." -fi \ No newline at end of file + sleep 2 +done + +# 3. Push initial-configuration.nix +echo "📄 Pushing initial NixOS configuration..." +run_proxmox "pct push $LXC_ID '$INITIAL_CONFIG' /etc/nixos/configuration.nix" || { + echo "❌ Error: Failed to push initial configuration." >&2 + exit 1 +} + +# 4. Push deploy.sh +echo "📄 Pushing deploy script..." +run_proxmox "pct push $LXC_ID '$DEPLOY_SCRIPT' /usr/local/bin/deploy-nixos" || { + echo "❌ Error: Failed to push deploy script." >&2 + exit 1 +} +run_proxmox "pct exec $LXC_ID -- chmod +x /usr/local/bin/deploy-nixos" || { + echo "❌ Error: Failed to make deploy script executable." >&2 + exit 1 +} + +# 5. Apply initial configuration (nixos-rebuild switch) +echo "⚙️ Applying initial NixOS configuration (this may take a while)..." +if ! run_proxmox "pct exec $LXC_ID -- nixos-rebuild switch" 2>&1; then + echo "⚠️ Warning: Initial nixos-rebuild may have issues." >&2 + echo " Check the container manually: pct exec $LXC_ID -- nixos-rebuild switch" >&2 + # Continue anyway — deploy.sh might still work +fi +echo "✅ Initial configuration applied." + +# 6. Run deploy.sh to clone the repo and apply the specific configuration +echo "🌐 Running deploy.sh to clone repo and apply specific configuration..." +# Pass REPO_URL and BRANCH as environment variables to deploy.sh inside the container +DEPLOY_CMD="REPO_URL='$REPO_URL' BRANCH='$BRANCH' /usr/local/bin/deploy-nixos" +if ! run_proxmox "pct exec $LXC_ID -- bash -c '$DEPLOY_CMD'" 2>&1; then + echo "⚠️ Warning: deploy.sh encountered issues." >&2 + echo " You can retry manually: pct exec $LXC_ID -- /usr/local/bin/deploy-nixos" >&2 + exit 1 +fi + +echo "" +echo "🎉 Container $short_name (CT $LXC_ID) successfully created and deployed!" +echo " Connect with: ssh root@${IP%%/*} (or use pct exec $LXC_ID)" \ No newline at end of file diff --git a/nixos-infra/scripts/deploy.sh b/nixos-infra/scripts/deploy.sh index 69d1717..a654c79 100644 --- a/nixos-infra/scripts/deploy.sh +++ b/nixos-infra/scripts/deploy.sh @@ -1,42 +1,99 @@ #!/usr/bin/env bash set -euo pipefail -REPO_URL="https://gitea.lagraula.fr/xavier/nixos-infra.git" -REPO_DIR="/etc/nixos-infra" -BRANCH="main" +# --- Default values (can be overridden by environment variables) --- +REPO_URL="${REPO_URL:-https://gitea.lagraula.fr/xavier/nixos-infra.git}" +REPO_DIR="${REPO_DIR:-/etc/nixos-infra}" +BRANCH="${BRANCH:-main}" +DRY_RUN="${DRY_RUN:-false}" + +# --- Usage --- +usage() { + cat <&2; usage ;; + esac +done + HOSTNAME=$(hostname) if [ "$(id -u)" -ne 0 ]; then - echo "Ce script doit être exécuté en tant que root." >&2 + echo "❌ This script must be run as root." >&2 exit 1 fi -# Cloner ou mettre à jour le dépôt +# --- Dry run mode --- +if [ "$DRY_RUN" = "true" ]; then + echo "🧪 Dry run mode:" + echo " - Repository URL: $REPO_URL" + echo " - Repository dir: $REPO_DIR" + echo " - Branch: $BRANCH" + echo " - Hostname: $HOSTNAME" + echo " - Expected config: $REPO_DIR/hosts/servers/$HOSTNAME/configuration.nix" + echo "" + echo " Would execute:" + echo " git clone --branch $BRANCH $REPO_URL $REPO_DIR" + echo " nixos-rebuild switch -I nixos-config=...$HOSTNAME/configuration.nix" + exit 0 +fi + +# --- Clone or update the repository --- if [ -d "$REPO_DIR/.git" ]; then - echo "Mise à jour du dépôt dans $REPO_DIR..." + echo "🔄 Mise à jour du dépôt dans $REPO_DIR..." cd "$REPO_DIR" git fetch origin git checkout "$BRANCH" git pull origin "$BRANCH" else - echo "Clonage du dépôt dans $REPO_DIR..." + echo "📥 Clonage du dépôt dans $REPO_DIR..." mkdir -p "$REPO_DIR" git clone --branch "$BRANCH" "$REPO_URL" "$REPO_DIR" fi -# Trouver la configuration pour cette machine +# --- Find the configuration for this machine --- CONFIG_PATH="$REPO_DIR/hosts/servers/$HOSTNAME/configuration.nix" if [ ! -f "$CONFIG_PATH" ]; then CONFIG_PATH="$REPO_DIR/hosts/workstations/$HOSTNAME/configuration.nix" fi if [ ! -f "$CONFIG_PATH" ]; then - echo "Erreur : Aucune configuration trouvée pour $HOSTNAME dans $REPO_DIR" >&2 + echo "❌ Error : No configuration found for $HOSTNAME in $REPO_DIR" >&2 + echo " Checked paths :" >&2 + echo " - $REPO_DIR/hosts/servers/$HOSTNAME/configuration.nix" >&2 + echo " - $REPO_DIR/hosts/workstations/$HOSTNAME/configuration.nix" >&2 exit 1 fi -# Appliquer la configuration -echo "Déploiement de la configuration pour $HOSTNAME..." +# --- Apply the configuration --- +echo "🚀 Deploying the configuration for $HOSTNAME..." nixos-rebuild switch -I nixos-config="$CONFIG_PATH" -echo "Déploiement terminé avec succès !" \ No newline at end of file +echo "✅ Deployment was successful !" \ No newline at end of file diff --git a/nixos-infra/scripts/gen-secrets-keys.sh b/nixos-infra/scripts/gen-secrets-keys.sh new file mode 100644 index 0000000..f8a603e --- /dev/null +++ b/nixos-infra/scripts/gen-secrets-keys.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +set -euo pipefail + +# --- gen-secrets-keys.sh --- +# Generate age public keys from SSH host keys for all known hosts. +# +# This script retrieves each host's SSH host key, converts it to an +# age public key using ssh-to-age, and stores it in +# secrets/pubkeys/.age for use with agenix. + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +PUBKEYS_DIR="${PROJECT_DIR}/secrets/pubkeys" + +# Ensure ssh-to-age is available +if ! command -v ssh-to-age &> /dev/null; then + echo "❌ Error: 'ssh-to-age' is required." + echo " Install it with: nix-shell -p ssh-to-age" + exit 1 +fi + +mkdir -p "$PUBKEYS_DIR" + +echo "🔑 Generating age public keys from SSH host keys..." +echo " Output directory: $PUBKEYS_DIR" +echo "" + +# Known hosts (hostname, user@host, ssh port) +# Add entries as hosts are deployed in the infrastructure +HOSTS=( + # Hypervisors + # "pve01:root@pve01.prod.lagraula.fr:22" + # "pve02:root@pve02.prod.lagraula.fr:22" + # LXC containers (once deployed) + # "dns01:root@dns01.lagraula.fr:22" + # "gitea01:root@gitea01.lagraula.fr:22" + # "vault01:root@vault01.lagraula.fr:22" + # "rp01:root@rp01.lagraula.fr:22" + # Workstations + # "sting:root@sting.lagraula.fr:22" +) + +if [ ${#HOSTS[@]} -eq 0 ]; then + echo "⚠️ No hosts configured. Edit the HOSTS array in this script first." + echo "" + echo "For a single host, you can also run manually:" + echo " ssh-keyscan 2>/dev/null | grep ed25519 | awk '{print \$3}' | ssh-to-age > $PUBKEYS_DIR/.age" + exit 0 +fi + +for entry in "${HOSTS[@]}"; do + IFS=':' read -r hostname ssh_user_port <<< "$entry" + IFS='@' read -r ssh_user ssh_host <<< "$ssh_user_port" + + echo "🖥️ Processing $hostname ($ssh_user@$ssh_host)..." + + age_key=$(ssh-keyscan -t ed25519 "$ssh_host" 2>/dev/null | \ + grep "ed25519" | \ + awk '{print $3}' | \ + ssh-to-age 2>/dev/null || true) + + if [ -z "$age_key" ]; then + echo " ⚠️ Could not retrieve age key for $hostname. Skipping." + continue + fi + + echo "$age_key" > "$PUBKEYS_DIR/$hostname.age" + echo " ✅ Saved age public key: $age_key" +done + +echo "" +echo "🎉 Done! Generated $(ls -1 "$PUBKEYS_DIR"/*.age 2>/dev/null | wc -l) key(s)." +echo "" +echo "To encrypt a secret for specific hosts:" +echo " age -r \$(cat $PUBKEYS_DIR/.age) -o secrets/.age" +echo "" +echo "Or with agenix:" +echo " agenix -e secrets/.age" \ No newline at end of file diff --git a/nixos-infra/scripts/initial-configuration.nix b/nixos-infra/scripts/initial-configuration.nix index 96d3624..82ce6af 100644 --- a/nixos-infra/scripts/initial-configuration.nix +++ b/nixos-infra/scripts/initial-configuration.nix @@ -4,29 +4,24 @@ # Install Git, curl, and other required tools environment.systemPackages = with pkgs; [ git curl ]; - # Enable unsecured SSH for initial deployment + # Enable SSH for initial deployment services.openssh = { enable = true; permitRootLogin = "yes"; passwordAuthentication = true; }; - # Deployment script + # Clone the repository so deploy.sh can use it system.activationScripts.setup-deploy = '' #!${pkgs.bash}/bin/bash set -euo pipefail - # Télécharger le script de déploiement depuis Gitea - curl -o /usr/local/bin/deploy-nixos https://gitea.lagraula.fr/xavier/nixos-infra/raw/main/scripts/deploy.sh - chmod +x /usr/local/bin/deploy-nixos - - # Cloner le dépôt (si ce n'est pas déjà fait) + # Create the target directory mkdir -p /etc/nixos-infra - if [ ! -d "/etc/nixos-infra/.git" ]; then - git clone https://gitea.lagraula.fr/xavier/nixos-infra.git /etc/nixos-infra - fi + + # The deploy script has already been pushed to /usr/local/bin/deploy-nixos + # by create-lxc-nixos.sh; it will clone the repo and apply the config. ''; system.stateVersion = "25.11"; - } \ No newline at end of file diff --git a/nixos-infra/secrets/.gitignore b/nixos-infra/secrets/.gitignore index e69de29..b81e60d 100644 --- a/nixos-infra/secrets/.gitignore +++ b/nixos-infra/secrets/.gitignore @@ -0,0 +1,5 @@ +# Ignore all age-encrypted secret files +*.age + +# But keep the pubkeys directory (for tracked .age pubkey files) +!pubkeys/ \ No newline at end of file diff --git a/nixos-infra/secrets/pubkeys/.gitkeep b/nixos-infra/secrets/pubkeys/.gitkeep new file mode 100644 index 0000000..e69de29