diff --git a/home-manager/programs/ssh/default.nix b/home-manager/programs/ssh/default.nix index 3b5ad7f82..912eec47b 100644 --- a/home-manager/programs/ssh/default.nix +++ b/home-manager/programs/ssh/default.nix @@ -20,6 +20,14 @@ extraOptions = { IgnoreUnknown = "UseKeychain"; UseKeyChain = "yes"; + # Enable post-quantum key exchange algorithms + # sntrup761x25519 is a hybrid post-quantum algorithm combining + # Streamlined NTRU Prime (sntrup761) with X25519 + KexAlgorithms = "sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256"; + # Prefer modern host key algorithms + HostKeyAlgorithms = "ssh-ed25519-cert-v01@openssh.com,ssh-ed25519,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-256"; + # Prefer modern public key algorithms + PubkeyAcceptedAlgorithms = "ssh-ed25519-cert-v01@openssh.com,ssh-ed25519,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-256"; }; }; "localhost" = { @@ -30,6 +38,7 @@ }; "github.com" = { serverAliveInterval = 0; + identityFile = "~/.ssh/id_ed25519_github"; extraOptions = { ControlMaster = "auto"; ControlPath = "~/.ssh/github.sock"; diff --git a/named-hosts/galactica/secrets.nix b/named-hosts/galactica/secrets.nix index 29e25935a..4503371ca 100644 --- a/named-hosts/galactica/secrets.nix +++ b/named-hosts/galactica/secrets.nix @@ -1,14 +1,23 @@ +let + # Galactica's SSH public key + galactica = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEKze2jlpV7SyTKA2ezqbumpCiDn+5Sj4z5SxrqfzesX shunkakinoki@gmail.com"; + # Kyber's SSH public key + kyber = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO0IZtP3KSzY6GVSZ+R+VQYYfu3sEOVaQGDblQxAtwNM ubuntu@kyber"; + # All machines that can decrypt shared secrets + allMachines = [ + galactica + kyber + ]; +in { + # Shared SSH key for GitHub authentication (accessible on all machines) "keys/id_ed25519.age" = { file = ./keys/id_ed25519.age; - publicKeys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEKze2jlpV7SyTKA2ezqbumpCiDn+5Sj4z5SxrqfzesX shunkakinoki@gmail.com" - ]; + publicKeys = allMachines; }; + # GPG key (galactica only) "keys/gpg.age" = { file = ./keys/gpg.age; - publicKeys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEKze2jlpV7SyTKA2ezqbumpCiDn+5Sj4z5SxrqfzesX shunkakinoki@gmail.com" - ]; + publicKeys = [ galactica ]; }; } diff --git a/named-hosts/kyber/README.md b/named-hosts/kyber/README.md index 7e31cd332..34f0a3755 100644 --- a/named-hosts/kyber/README.md +++ b/named-hosts/kyber/README.md @@ -48,3 +48,31 @@ Once Tailscale is set up: ```bash kyber # Fish abbreviation that runs: ssh ubuntu@kyber ``` + +## Syncing SSH Keys from Galactica + +To sync the GitHub SSH key from galactica to kyber: + +### On Galactica + +```bash +cd ~/dotfiles +git pull +make rekey-galactica +git add named-hosts/galactica/keys/ +git commit -m "chore(agenix): rekey secrets for kyber access" +git push +``` + +### On Kyber + +```bash +cd ~/dotfiles +git pull +make switch + +# Test GitHub access +ssh -T git@github.com +``` + +The SSH key will be automatically decrypted and deployed to `~/.ssh/id_ed25519_github`. diff --git a/named-hosts/kyber/default.nix b/named-hosts/kyber/default.nix index 7d719f76d..8c9584974 100644 --- a/named-hosts/kyber/default.nix +++ b/named-hosts/kyber/default.nix @@ -45,7 +45,22 @@ home-manager.lib.homeManagerConfiguration { # Agenix configuration age.identityPaths = [ "/home/${username}/.ssh/id_ed25519" ]; - age.secrets = builtins.mapAttrs (name: value: { file = value.file; }) (import ./secrets.nix); + age.secrets = builtins.mapAttrs ( + name: value: + { + file = value.file; + # Deploy GitHub SSH key to ~/.ssh/ with correct permissions + } + // ( + if name == "keys/id_ed25519.age" then + { + path = "/home/${username}/.ssh/id_ed25519_github"; + mode = "0600"; + } + else + { } + ) + ) (import ./secrets.nix); programs.home-manager.enable = true; diff --git a/named-hosts/kyber/rekey-galactica.sh b/named-hosts/kyber/rekey-galactica.sh new file mode 100755 index 000000000..d3e2ea825 --- /dev/null +++ b/named-hosts/kyber/rekey-galactica.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Remotely rekey galactica secrets to include kyber's public key +# This script should be run from kyber to trigger the rekey on galactica + +set -e + +echo "🔑 Rekeying galactica secrets to include kyber..." +echo "" +echo "This will:" +echo "1. Connect to galactica via Tailscale SSH" +echo "2. Run the rekey command to re-encrypt secrets with both keys" +echo "3. Commit and push the changes" +echo "" + +# Try Tailscale SSH first +if tailscale ssh shunkakinoki@galactica "cd ~/dotfiles && make rekey-galactica" 2>/dev/null; then + echo "✅ Rekey completed via Tailscale SSH" +else + echo "❌ Tailscale SSH failed. Please run this manually on galactica:" + echo "" + echo " cd ~/dotfiles" + echo " git pull" + echo " make rekey-galactica" + echo " git add named-hosts/galactica/keys/" + echo " git commit -m 'chore(agenix): rekey secrets for kyber access'" + echo " git push" + echo "" + exit 1 +fi + +# Pull the changes +echo "" +echo "📥 Pulling re-encrypted secrets..." +cd ~/dotfiles +git pull + +echo "" +echo "✅ Done! Now run: make switch" diff --git a/named-hosts/kyber/secrets.nix b/named-hosts/kyber/secrets.nix index 980660cf5..6f04e77e6 100644 --- a/named-hosts/kyber/secrets.nix +++ b/named-hosts/kyber/secrets.nix @@ -2,21 +2,27 @@ # To add a new secret: # 1. Add the secret definition here # 2. Run: make encrypt-key-kyber KEY_FILE=/path/to/secret +let + # Galactica's SSH public key + galactica = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEKze2jlpV7SyTKA2ezqbumpCiDn+5Sj4z5SxrqfzesX shunkakinoki@gmail.com"; + # Kyber's SSH public key + kyber = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO0IZtP3KSzY6GVSZ+R+VQYYfu3sEOVaQGDblQxAtwNM ubuntu@kyber"; + # All machines that can decrypt shared secrets + allMachines = [ + galactica + kyber + ]; +in { # Tailscale auth key - generate from https://login.tailscale.com/admin/settings/keys - # "keys/tailscale-auth.age" = { - # file = ./keys/tailscale-auth.age; - # publicKeys = [ - # # Kyber's SSH public key (run: ssh ubuntu@kyber "cat ~/.ssh/id_ed25519.pub") - # "ssh-ed25519 AAAA..." - # ]; - # }; + "keys/tailscale-auth.age" = { + file = ./keys/tailscale-auth.age; + publicKeys = [ kyber ]; + }; - # SSH key sync (your local key encrypted for kyber) - # "keys/id_ed25519.age" = { - # file = ./keys/id_ed25519.age; - # publicKeys = [ - # "ssh-ed25519 AAAA..." - # ]; - # }; + # Shared SSH key for GitHub authentication (synced from galactica) + "keys/id_ed25519.age" = { + file = ../galactica/keys/id_ed25519.age; + publicKeys = allMachines; + }; }