diff options
| author | Daiderd Jordan <daiderd@gmail.com> | 2018-03-06 20:42:33 +0100 |
|---|---|---|
| committer | Daiderd Jordan <daiderd@gmail.com> | 2018-03-06 20:42:33 +0100 |
| commit | 2b721afd999a4515327856a8243647fcca826353 (patch) | |
| tree | 03c1ecf606e66eb036b8fe8244a0e902eca87523 /modules/programs/ssh | |
| parent | 84a3fcadd06c35a91eb84a5739452c53be55d8ea (diff) | |
ssh: add option to configure known hosts
Diffstat (limited to 'modules/programs/ssh')
| -rw-r--r-- | modules/programs/ssh/default.nix | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/modules/programs/ssh/default.nix b/modules/programs/ssh/default.nix new file mode 100644 index 0000000..2a15a8b --- /dev/null +++ b/modules/programs/ssh/default.nix @@ -0,0 +1,91 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.programs.ssh; + + knownHosts = map (h: getAttr h cfg.knownHosts) (attrNames cfg.knownHosts); + + host = + { name, ... }: + { + 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 <command>ssh-keyscan</command> + 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 <command>ssh-keyscan</command> command. The content + of the file should follow the same format as described for + the <literal>publicKey</literal> option. + ''; + }; + }; + config = { + hostNames = mkDefault [ name ]; + }; + }; +in + +{ + options = { + + programs.ssh.knownHosts = mkOption { + default = {}; + type = types.loaOf (types.submodule host); + description = '' + The set of system-wide known SSH hosts. + ''; + example = literalExample '' + [ + { + hostNames = [ "myhost" "myhost.mydomain.com" "10.10.1.4" ]; + publicKeyFile = ./pubkeys/myhost_ssh_host_dsa_key.pub; + } + { + hostNames = [ "myhost2" ]; + publicKeyFile = ./pubkeys/myhost2_ssh_host_dsa_key.pub; + } + ] + ''; + }; + }; + + config = { + + assertions = 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"; + }); + + environment.etc."ssh/ssh_known_hosts".text = (flip (concatMapStringsSep "\n") knownHosts + (h: assert h.hostNames != []; + concatStringsSep "," h.hostNames + " " + + (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile) + )) + "\n"; + + }; +} |
