NixDaemon

NixOS pentest workstation as one flake — IceBreaker's successor
git clone https://git.daemon-sec.xyz/NixDaemon.git
Log | Files | Refs | README

ssh.nix (3066B)


      1 # modules/home/ssh.nix — the SSH key and client config, from the flake.
      2 #
      3 # The private key is a sops secret (secrets/secrets.yaml: ssh_id_ed25519;
      4 # `nix-cheat secrets`). At login sops-nix decrypts it with the age key into
      5 # the runtime secrets dir and ~/.config/sops-nix/secrets/ssh_id_ed25519 points
      6 # there; ~/.ssh/config names that path, so a fresh machine has a working key
      7 # as soon as ~/.config/sops/age/keys.txt is restored. The public half is
      8 # plain text in ~/.ssh/id_ed25519.pub (comment daemonsec@nixos; registered on
      9 # gitlab.com as "nixos", auth and signing, and glab's git_protocol is ssh).
     10 #
     11 # A plain copy from before this module may still sit at ~/.ssh/id_ed25519;
     12 # nothing reads it any more.
     13 #
     14 # The agent: services.gnome.gnome-keyring.enable (configuration.nix, and
     15 # mkDefault in workstation.nix) makes gcr-ssh-agent the $SSH_AUTH_SOCK
     16 # (/run/user/1000/gcr/ssh). It is not gpg-agent and not plain ssh-agent, and
     17 # it refuses signing requests when it cannot prompt. ssh prefers an agent that
     18 # holds the key over reading the file, so that refusal is fatal even though
     19 # the key is readable. Hence IdentityAgent = "none" below, and no
     20 # AddKeysToAgent. Verified: with the agent, `ssh -T git@gitlab.com` fails;
     21 # with SSH_AUTH_SOCK unset it prints "Welcome to GitLab, @DAEMON-404!".
     22 { ... }:
     23 {
     24   flake.homeModules.ssh =
     25   { config, ... }:
     26   let
     27     key = config.sops.secrets.ssh_id_ed25519.path;
     28   in
     29   {
     30     sops.secrets.ssh_id_ed25519 = { }; # → %r/secrets.d/…, mode 0400 (ssh is happy with that)
     31 
     32     home.file.".ssh/id_ed25519.pub".text = ''
     33       ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB8ExB6Gv5T7DwwVeNqVmzbwCcZ/ULuKL2pAXS7zg4NR daemonsec@nixos
     34     '';
     35 
     36     programs.ssh = {
     37       enable = true;
     38       enableDefaultConfig = false;
     39       settings = {
     40         "gitlab.com" = {
     41           User = "git";
     42           IdentityFile = key;
     43           IdentitiesOnly = "yes";
     44           # Read the key from the file, never through an agent. See the note
     45           # below: gnome-keyring's gcr-ssh-agent owns $SSH_AUTH_SOCK on this
     46           # machine and refuses to sign, which breaks `git push` outright.
     47           IdentityAgent = "none";
     48         };
     49         "github.com" = {
     50           User = "git";
     51           IdentityFile = key;
     52           IdentitiesOnly = "yes";
     53           IdentityAgent = "none";
     54         };
     55         "gitea.com" = {
     56           User = "git";
     57           IdentityFile = key;
     58           IdentitiesOnly = "yes";
     59           IdentityAgent = "none";
     60         };
     61         "*" = {
     62           IdentityFile = key;
     63           # NOT AddKeysToAgent = "yes". That is what put this key into
     64           # gcr-ssh-agent in the first place, and once the agent holds a key
     65           # ssh asks IT to sign rather than using the file — so a refusal from
     66           # gcr became `sign_and_send_pubkey: signing failed ... agent refused
     67           # operation` followed by `Permission denied (publickey)`, with a
     68           # perfectly good key sitting on disk.
     69           ServerAliveInterval = 30;
     70           HashKnownHosts = "no";
     71         };
     72       };
     73     };
     74   }
     75   ;
     76 }