From 287c08d8a319fc454e3d1ce90510f7a53e9d4e5d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 27 Aug 2015 15:24:14 +0200 Subject: Rename services.openssh.knownHosts -> programs.ssh.knownHosts This option configures the SSH client, not the server. --- nixos/modules/programs/ssh.nix | 74 ++++++++++++++++++++++-- nixos/modules/rename.nix | 1 + nixos/modules/services/networking/ssh/sshd.nix | 79 ++------------------------ 3 files changed, 75 insertions(+), 79 deletions(-) (limited to 'nixos') diff --git a/nixos/modules/programs/ssh.nix b/nixos/modules/programs/ssh.nix index d3183f7d2dc7..e9ad47adec9e 100644 --- a/nixos/modules/programs/ssh.nix +++ b/nixos/modules/programs/ssh.nix @@ -18,6 +18,14 @@ let exec ${askPassword} ''; + knownHosts = map (h: getAttr h cfg.knownHosts) (attrNames cfg.knownHosts); + + knownHostsText = flip (concatMapStringsSep "\n") knownHosts + (h: + concatStringsSep "," h.hostNames + " " + + (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile) + ); + in { ###### interface @@ -92,16 +100,72 @@ in ''; }; + knownHosts = mkOption { + default = {}; + type = types.loaOf types.optionSet; + description = '' + The set of system-wide known SSH hosts. + ''; + example = [ + { + hostNames = [ "myhost" "myhost.mydomain.com" "10.10.1.4" ]; + publicKeyFile = literalExample "./pubkeys/myhost_ssh_host_dsa_key.pub"; + } + { + hostNames = [ "myhost2" ]; + publicKeyFile = literalExample "./pubkeys/myhost2_ssh_host_dsa_key.pub"; + } + ]; + options = { + hostNames = mkOption { + type = types.listOf types.str; + default = []; + description = '' + A list of host names and/or IP numbers used for accessing + the host's ssh service. + ''; + }; + publicKey = mkOption { + default = null; + type = types.nullOr types.str; + example = "ecdsa-sha2-nistp521 AAAAE2VjZHN...UEPg=="; + description = '' + The public key data for the host. You can fetch a public key + from a running SSH server with the ssh-keyscan + command. The public key should not include any host names, only + the key type and the key itself. + ''; + }; + publicKeyFile = mkOption { + default = null; + type = types.nullOr types.path; + description = '' + The path to the public key file for the host. The public + key file is read at build time and saved in the Nix store. + You can fetch a public key file from a running SSH server + with the ssh-keyscan command. The content + of the file should follow the same format as described for + the publicKey option. + ''; + }; + }; + }; + }; }; config = { - assertions = singleton - { assertion = cfg.forwardX11 -> cfg.setXAuthLocation; - message = "cannot enable X11 forwarding without setting XAuth location"; - }; + assertions = + [ { assertion = cfg.forwardX11 -> cfg.setXAuthLocation; + message = "cannot enable X11 forwarding without setting XAuth location"; + } + ] ++ flip mapAttrsToList cfg.knownHosts (name: data: { + assertion = (data.publicKey == null && data.publicKeyFile != null) || + (data.publicKey != null && data.publicKeyFile == null); + message = "knownHost ${name} must contain either a publicKey or publicKeyFile"; + }); # SSH configuration. Slight duplication of the sshd_config # generation in the sshd service. @@ -118,6 +182,8 @@ in ${cfg.extraConfig} ''; + environment.etc."ssh/ssh_known_hosts".text = knownHostsText; + # FIXME: this should really be socket-activated for über-awesomeness. systemd.user.services.ssh-agent = { enable = cfg.startAgent; diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 4db08b7ad3d0..6f7dcb837a07 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -110,6 +110,7 @@ in zipModules ([] ++ obsolete [ "services" "sshd" "permitRootLogin" ] [ "services" "openssh" "permitRootLogin" ] ++ obsolete [ "services" "xserver" "startSSHAgent" ] [ "services" "xserver" "startOpenSSHAgent" ] ++ obsolete [ "services" "xserver" "startOpenSSHAgent" ] [ "programs" "ssh" "startAgent" ] +++ alias [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ] # VirtualBox ++ obsolete [ "services" "virtualbox" "enable" ] [ "virtualisation" "virtualbox" "guest" "enable" ] diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index 1c428ceddfd2..4c7e4d8d088c 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -9,14 +9,6 @@ let nssModulesPath = config.system.nssModules.path; - knownHosts = map (h: getAttr h cfg.knownHosts) (attrNames cfg.knownHosts); - - knownHostsText = flip (concatMapStringsSep "\n") knownHosts - (h: - concatStringsSep "," h.hostNames + " " - + (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile) - ); - userOptions = { openssh.authorizedKeys = { @@ -48,8 +40,7 @@ let }; authKeysFiles = let - mkAuthKeyFile = u: { - target = "ssh/authorized_keys.d/${u.name}"; + mkAuthKeyFile = u: nameValuePair "ssh/authorized_keys.d/${u.name}" { mode = "0444"; source = pkgs.writeText "${u.name}-authorized_keys" '' ${concatStringsSep "\n" u.openssh.authorizedKeys.keys} @@ -59,7 +50,7 @@ let usersWithKeys = attrValues (flip filterAttrs config.users.extraUsers (n: u: length u.openssh.authorizedKeys.keys != 0 || length u.openssh.authorizedKeys.keyFiles != 0 )); - in map mkAuthKeyFile usersWithKeys; + in listToAttrs (map mkAuthKeyFile usersWithKeys); in @@ -211,57 +202,6 @@ in description = "Verbatim contents of sshd_config."; }; - knownHosts = mkOption { - default = {}; - type = types.loaOf types.optionSet; - description = '' - The set of system-wide known SSH hosts. - ''; - example = [ - { - hostNames = [ "myhost" "myhost.mydomain.com" "10.10.1.4" ]; - publicKeyFile = literalExample "./pubkeys/myhost_ssh_host_dsa_key.pub"; - } - { - hostNames = [ "myhost2" ]; - publicKeyFile = literalExample "./pubkeys/myhost2_ssh_host_dsa_key.pub"; - } - ]; - options = { - hostNames = mkOption { - type = types.listOf types.str; - default = []; - description = '' - A list of host names and/or IP numbers used for accessing - the host's ssh service. - ''; - }; - publicKey = mkOption { - default = null; - type = types.nullOr types.str; - example = "ecdsa-sha2-nistp521 AAAAE2VjZHN...UEPg=="; - description = '' - The public key data for the host. You can fetch a public key - from a running SSH server with the ssh-keyscan - command. The public key should not include any host names, only - the key type and the key itself. - ''; - }; - publicKeyFile = mkOption { - default = null; - type = types.nullOr types.path; - description = '' - The path to the public key file for the host. The public - key file is read at build time and saved in the Nix store. - You can fetch a public key file from a running SSH server - with the ssh-keyscan command. The content - of the file should follow the same format as described for - the publicKey option. - ''; - }; - }; - }; - moduliFile = mkOption { example = "services.openssh.moduliFile = /etc/my-local-ssh-moduli;"; type = types.path; @@ -292,14 +232,8 @@ in services.openssh.moduliFile = mkDefault "${cfgc.package}/etc/ssh/moduli"; - environment.etc = authKeysFiles ++ [ - { source = cfg.moduliFile; - target = "ssh/moduli"; - } - { text = knownHostsText; - target = "ssh/ssh_known_hosts"; - } - ]; + environment.etc = authKeysFiles // + { "ssh/moduli".source = cfg.moduliFile; }; systemd = let @@ -417,11 +351,6 @@ in assertions = [{ assertion = if cfg.forwardX11 then cfgc.setXAuthLocation else true; message = "cannot enable X11 forwarding without setting xauth location";}] - ++ flip mapAttrsToList cfg.knownHosts (name: data: { - assertion = (data.publicKey == null && data.publicKeyFile != null) || - (data.publicKey != null && data.publicKeyFile == null); - message = "knownHost ${name} must contain either a publicKey or publicKeyFile"; - }) ++ flip map cfg.listenAddresses ({ addr, port, ... }: { assertion = addr != null; message = "addr must be specified in each listenAddresses entry"; -- cgit 1.4.1