/ users / vincent / core / ssh.nix
ssh.nix
  1  { config, lib, pkgs, ... }:
  2  
  3  let
  4    gpgRemoteForward = {
  5      bind.address = "/run/user/1000/gnupg/S.gpg-agent";
  6      host.address = "/run/user/1000/gnupg/S.gpg-agent.extra";
  7    };
  8    gpgSSHRemoteForward = {
  9      bind.address = "/run/user/1000/gnupg/S.gpg-agent.ssh";
 10      host.address = "/run/user/1000/gnupg/S.gpg-agent.ssh";
 11    };
 12  
 13    inherit (lib) optionalAttrs importTOML hasAttr attrsets mkIf;
 14    metadata = importTOML ../../../ops/hosts.toml;
 15  
 16    hasWireguard = name: value: hasAttr "wireguard" value;
 17    hasAddrs = name: value: hasAttr "addrs" value;
 18    hasSShAndRemoteForward = v: (hasAttr "ssh" v) && (hasAttr "gpgRemoteForward" v.ssh);
 19    hasCommand = v: hasAttr "command" v;
 20  
 21    hostWireguardIP = v: "${v.wireguard.addrs.v4}";
 22    hostIP = v: "${v.addrs.v4}";
 23    hostRemoteCommand = v: "${v.command}";
 24  
 25    hostToSSHConfigItem = value: ipfn: {
 26      hostname = ipfn value;
 27      remoteForwards = mkIf (hasSShAndRemoteForward value) [ gpgRemoteForward gpgSSHRemoteForward ];
 28      # FIXME: need support for RemoteCommand in home-manager
 29      # RemoteCommand = mkIf (hasCommand value) hostRemoteCommand value;
 30    };
 31    hostToSSHConfig = suffix: ipfn:
 32      name: value: attrsets.nameValuePair
 33        (toString "${name}${suffix}")
 34        (hostToSSHConfigItem value ipfn);
 35  
 36    vpnConfig = attrsets.mapAttrs'
 37      (hostToSSHConfig "\.vpn" hostWireguardIP)
 38      (attrsets.filterAttrs hasWireguard metadata.hosts);
 39    homeConfig = attrsets.mapAttrs'
 40      (hostToSSHConfig "\.home" hostIP)
 41      (attrsets.filterAttrs hasAddrs metadata.hosts);
 42  in
 43  {
 44    home.packages = [
 45      pkgs.openssh
 46      pkgs.sshfs
 47    ];
 48    home.file.".ssh/sockets/.placeholder".text = '''';
 49    xdg.configFile."ssh/.placeholder".text = '''';
 50    programs.ssh = {
 51      enable = true;
 52  
 53      serverAliveInterval = 60;
 54      hashKnownHosts = true;
 55      userKnownHostsFile = "${config.xdg.configHome}/ssh/known_hosts";
 56      controlMaster = "auto";
 57      controlPersist = "10m";
 58      controlPath = "${config.home.homeDirectory}/.ssh/sockets/%u-%l-%r@%h:%p";
 59      matchBlocks = {
 60        "github.com" = {
 61          hostname = "github.com";
 62          user = "git";
 63          extraOptions = {
 64            controlMaster = "auto";
 65            controlPersist = "360";
 66          };
 67        };
 68        "gitlab.com" = {
 69          hostname = "gitlab.com";
 70          user = "git";
 71          extraOptions = {
 72            controlMaster = "auto";
 73            controlPersist = "360";
 74          };
 75        };
 76        "git.sr.ht" = {
 77          hostname = "git.sr.ht";
 78          user = "git";
 79          extraOptions = {
 80            controlMaster = "auto";
 81            controlPersist = "360";
 82          };
 83        };
 84        "*.redhat.com" = {
 85          user = "vdemeest";
 86        };
 87        "bootstrap.ospqa.com" = {
 88          forwardAgent = true;
 89        };
 90        "192.168.1.*" = {
 91          forwardAgent = true;
 92          extraOptions = {
 93            StrictHostKeyChecking = "no";
 94            UserKnownHostsFile = "/dev/null";
 95          };
 96        };
 97        "10.100.0.*" = {
 98          forwardAgent = true;
 99        };
100      } // homeConfig // vpnConfig;
101      extraConfig = ''
102        GlobalKnownHostsFile ~/.config/ssh/ssh_known_hosts ~/.config/ssh/ssh_known_hosts.redhat ~/.config/ssh/ssh_known_hosts.mutable
103        StrictHostKeyChecking yes
104        PreferredAuthentications gssapi-with-mic,publickey,password
105        GSSAPIAuthentication yes
106        GSSAPIDelegateCredentials yes
107        StreamLocalBindUnlink yes
108        IdentityFile ~/.ssh/keys/%h
109        IdentityFile ~/.ssh/id_ed25519
110        IdentityFile ~/.ssh/id_rsa
111      '';
112    };
113    # FIXME generate this file as well
114    xdg.configFile."ssh/ssh_known_hosts".text = ''
115      # Home ()
116      wakasu.home,wakasu.vpn,wakasu.sbr.pm,10.100.0.8,192.168.1.77 wakasu.vpn ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINrAh07USjRnAdS3mMNGdKee1KumjYDLzgXaiZ5LYi2D
117      aomi.home,aomi.sbr.pm,aomi.vpn,10.100.0.17,192.168.1.23 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFQVlSrUKU0xlM9E+sJ8qgdgqCW6ePctEBD2Yf+OnyME
118      sakhalin.home,sakhalin.sbr.pm,sakhalin.vpn,10.100.0.16,192.168.1.70 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN/PMBThi4DhgZR8VywbRDzzMVh2Qp3T6NJAcPubfXz6
119      shikoku.home,shikoku.sbr.pm,shikoku.vpn,10.100.0.2,192.168.1.24 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH18c6kcorVbK2TwCgdewL6nQf29Cd5BVTeq8nRYUigm
120      kerkouane.vpn,kerkouane.sbr.pm,10.100.0.1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJguVoQYObRLyNxELFc3ai2yDJ25+naiM3tKrBGuxwwA
121      synodine.home,synodine.sbr.pm,192.168.1.20 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDWdnPJg0Y4kd4lHPAGE4xgMAK2qvMg3oBxh0t+xO+7O
122      demeter.home,demeter.vpn,demeter.sbr.pm,192.168.1.182 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGqQfEyHyjIGglayB9FtCqL7bnYfNSQlBXks2IuyCPmd
123      athena.home,athena.vpn,athena.sbr.pm,192.168.1.183 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM/4KRP1rzOwyA2zP1Nf1WlLRHqAGutLtOHYWfH732xh
124      aion.home,aion.vpn,aion.sbr.pm,10.100.0.49,192.168.1.49 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMs2o62unBFN/LHRg3q2N4QyZW0+DC/gjw3yzRbWdzx5
125    '';
126    xdg.configFile."ssh/ssh_known_hosts.redhat".text = ''
127      # Red Hat
128      gitlab.cee.redhat.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICBgflBIyju1LV/29PmFDw0GLdB9h0JUXglNrvWjBQ2u
129      code.engineering.redhat.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINYZZXmzm14TUL02Qe5SCMw48OfrphoIzi4qXSEK9Hiq
130    '';
131  }