{ config, lib, pkgs, ... }: with lib; let cfg = config.myOptions.services.ssh; in { options.myOptions.services.ssh = { daemon = mkOption { description = "sshd options"; type = with types; submodule { options = { enable = mkEnableOption "sshd"; passwordAuth = mkOption { description = "allow password auth"; default = false; type = bool; }; allowRoot = mkOption { description = "allow root login"; default = false; type = bool; }; }; }; }; agent = mkOption { description = "ssh agent options"; type = with types; submodule { options = { enable = mkEnableOption "ssh-agent"; hostAliases = mkOption { description = "host aliases"; type = with types; attrsOf (submodule { options = { hostName = mkOption { description = "hostname to ssh into"; type = types.str; }; port = mkOption { description = "port to ssh into"; type = with types; nullOr number; default = null; }; user = mkOption { description = "ssh user"; type = types.str; default = "git"; }; publicKey = mkOption { description = "public key used for picking the correct key from the ssh-agent"; type = with types; nullOr str; default = null; }; }; }); default = {}; }; }; }; }; }; config = mkMerge [ (mkIf cfg.daemon.enable { services.openssh = { enable = true; settings = { PasswordAuthentication = false; PermitRootLogin = "no"; }; }; }) (mkIf cfg.agent.enable { programs.ssh = { enableAskPassword = true; askPassword = "${pkgs.libsForQt5.ksshaskpass}/bin/ksshaskpass"; extraConfig = '' AddKeysToAgent yes ${concatStrings (mapAttrsToList (name: value: '' Host ${name} HostName ${value.hostName} User ${value.user} ${ if value.port != null then "Port ${toString value.port}" else "" } ${ if value.publicKey != null then "IdentityFile ${pkgs.writeText "${name}.pub" value.publicKey}" else "" } '') cfg.agent.hostAliases)} ''; }; systemd.user.services.ssh-agent = { enable = true; description = "SSH key agent"; serviceConfig = { Type = "simple"; ExecStart = "${pkgs.openssh}/bin/ssh-agent -D -a $SSH_AUTH_SOCK"; }; environment = { SSH_AUTH_SOCK = "%t/ssh-agent.socket"; DISPLAY = ":0"; }; wantedBy = [ "default.target" ]; }; environment.sessionVariables = { SSH_AUTH_SOCK = "\$XDG_RUNTIME_DIR/ssh-agent.socket"; }; }) ]; }