diff options
Diffstat (limited to 'nixos/modules/programs/ssh.nix')
-rw-r--r-- | nixos/modules/programs/ssh.nix | 59 |
1 files changed, 47 insertions, 12 deletions
diff --git a/nixos/modules/programs/ssh.nix b/nixos/modules/programs/ssh.nix index c680063a47c34..b31fce9152404 100644 --- a/nixos/modules/programs/ssh.nix +++ b/nixos/modules/programs/ssh.nix @@ -17,7 +17,7 @@ let exec ${askPassword} "$@" ''; - knownHosts = map (h: getAttr h cfg.knownHosts) (attrNames cfg.knownHosts); + knownHosts = attrValues cfg.knownHosts; knownHostsText = (flip (concatMapStringsSep "\n") knownHosts (h: assert h.hostNames != []; @@ -25,6 +25,9 @@ let + (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile) )) + "\n"; + knownHostsFiles = [ "/etc/ssh/ssh_known_hosts" "/etc/ssh/ssh_known_hosts2" ] + ++ map pkgs.copyPathToStore cfg.knownHostsFiles; + in { ###### interface @@ -139,7 +142,7 @@ in knownHosts = mkOption { default = {}; - type = types.attrsOf (types.submodule ({ name, ... }: { + type = types.attrsOf (types.submodule ({ name, config, options, ... }: { options = { certAuthority = mkOption { type = types.bool; @@ -151,12 +154,22 @@ in }; hostNames = mkOption { type = types.listOf types.str; - default = []; + default = [ name ] ++ config.extraHostNames; + defaultText = literalExpression "[ ${name} ] ++ config.${options.extraHostNames}"; description = '' + DEPRECATED, please use <literal>extraHostNames</literal>. A list of host names and/or IP numbers used for accessing the host's ssh service. ''; }; + extraHostNames = mkOption { + type = types.listOf types.str; + default = []; + description = '' + A list of additional host names and/or IP numbers used for + accessing the host's ssh service. + ''; + }; publicKey = mkOption { default = null; type = types.nullOr types.str; @@ -177,13 +190,12 @@ in You can fetch a public key file from a running SSH server with the <command>ssh-keyscan</command> command. The content of the file should follow the same format as described for - the <literal>publicKey</literal> option. + the <literal>publicKey</literal> option. Only a single key + is supported. If a host has multiple keys, use + <option>programs.ssh.knownHostsFiles</option> instead. ''; }; }; - config = { - hostNames = mkDefault [ name ]; - }; })); description = '' The set of system-wide known SSH hosts. @@ -191,17 +203,36 @@ in example = literalExpression '' { myhost = { - hostNames = [ "myhost" "myhost.mydomain.com" "10.10.1.4" ]; + extraHostNames = [ "myhost.mydomain.com" "10.10.1.4" ]; publicKeyFile = ./pubkeys/myhost_ssh_host_dsa_key.pub; }; - myhost2 = { - hostNames = [ "myhost2" ]; - publicKeyFile = ./pubkeys/myhost2_ssh_host_dsa_key.pub; - }; + "myhost2.net".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILIRuJ8p1Fi+m6WkHV0KWnRfpM1WxoW8XAS+XvsSKsTK"; } ''; }; + knownHostsFiles = mkOption { + default = []; + type = with types; listOf path; + description = '' + Files containing SSH host keys to set as global known hosts. + <literal>/etc/ssh/ssh_known_hosts</literal> (which is + generated by <option>programs.ssh.knownHosts</option>) and + <literal>/etc/ssh/ssh_known_hosts2</literal> are always + included. + ''; + example = literalExpression '' + [ + ./known_hosts + (writeText "github.keys" ''' + github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== + github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + ''') + ] + ''; + }; + kexAlgorithms = mkOption { type = types.nullOr (types.listOf types.str); default = null; @@ -248,6 +279,9 @@ in message = "knownHost ${name} must contain either a publicKey or publicKeyFile"; }); + warnings = mapAttrsToList (name: _: ''programs.ssh.knownHosts.${name}.hostNames is deprecated, use programs.ssh.knownHosts.${name}.extraHostNames'') + (filterAttrs (name: {hostNames, extraHostNames, ...}: hostNames != [ name ] ++ extraHostNames) cfg.knownHosts); + # SSH configuration. Slight duplication of the sshd_config # generation in the sshd service. environment.etc."ssh/ssh_config".text = @@ -258,6 +292,7 @@ in # Generated options from other settings Host * AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"} + GlobalKnownHostsFile ${concatStringsSep " " knownHostsFiles} ${optionalString cfg.setXAuthLocation '' XAuthLocation ${pkgs.xorg.xauth}/bin/xauth |