mirror of
https://github.com/ilyakooo0/nixpkgs.git
synced 2024-12-27 22:03:54 +03:00
sshd: Support multiple host keys
The option services.openssh.hostKeys now allows specifying multiple host keys. The default value enables both a DSA and ECDSA key. (Clients by default will use the ECDSA key, unless known_hosts already has a DSA key for that host.) To use only an ECDSA key, you can say: services.openssh.hostKeys = [ { path = "/etc/ssh/ssh_host_ecdsa_key"; type = "ecdsa"; bits = 521; } ];
This commit is contained in:
parent
c9b9f7ee1d
commit
9771f0c96c
@ -15,29 +15,6 @@ let
|
||||
v == "forced-commands-only" ||
|
||||
v == "no";
|
||||
|
||||
hostKeyTypeNames = {
|
||||
dsa1024 = "dsa"; # DSA has a key size limitation due to standards
|
||||
rsa3072 = "rsa";
|
||||
ecdsa521 = "ecdsa";
|
||||
};
|
||||
|
||||
hostKeyTypeBits = {
|
||||
dsa1024 = 1024; # =80 bits of security
|
||||
rsa3072 = 3072; # =128 bits of security
|
||||
ecdsa521 = 521; # =256 bits of security
|
||||
};
|
||||
|
||||
# equivalent to 112 bit of security strength. Anything below this is very unsafe.
|
||||
hostKeyTypeSafeBits = {
|
||||
dsa1024 = 2048;
|
||||
rsa3072 = 2048;
|
||||
ecdsa521 = 255;
|
||||
};
|
||||
|
||||
hktn = attrByPath [cfg.hostKeyType] (throw "unknown host key type `${cfg.hostKeyType}'") hostKeyTypeNames;
|
||||
hktb = attrByPath [cfg.hostKeyType] (throw "unknown host key type `${cfg.hostKeyType}'") hostKeyTypeBits;
|
||||
hktsb = attrByPath [cfg.hostKeyType] (throw "unknown host key type `${cfg.hostKeyType}'") hostKeyTypeSafeBits;
|
||||
|
||||
knownHosts = map (h: getAttr h cfg.knownHosts) (attrNames cfg.knownHosts);
|
||||
|
||||
knownHostsFile = pkgs.writeText "ssh_known_hosts" (
|
||||
@ -176,22 +153,23 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
hostKeyType = mkOption {
|
||||
default = "dsa1024";
|
||||
hostKeys = mkOption {
|
||||
default =
|
||||
[ { path = "/etc/ssh/ssh_host_dsa_key";
|
||||
type = "dsa";
|
||||
bits = 1024;
|
||||
}
|
||||
{ path = "/etc/ssh/ssh_host_ecdsa_key";
|
||||
type = "ecdsa";
|
||||
bits = 521;
|
||||
}
|
||||
];
|
||||
description = ''
|
||||
Type of host key to generate (dsa1024/rsa3072/ecdsa521), if
|
||||
the file specified by <literal>hostKeyPath</literal> does not
|
||||
exist when the service starts.
|
||||
'';
|
||||
};
|
||||
|
||||
hostKeyPath = mkOption {
|
||||
default = "/etc/ssh/ssh_host_${hktn}_key";
|
||||
description = ''
|
||||
Path to the server's private key. If there is no key file
|
||||
on this path, it will be generated when the service is
|
||||
started for the first time. Otherwise, the ssh daemon will
|
||||
use the specified key directly in-place.
|
||||
NixOS can automatically generate SSH host keys. This option
|
||||
specifies the path, type and size of each key. See
|
||||
<citerefentry><refentrytitle>ssh-keygen</refentrytitle>
|
||||
<manvolnum>1</manvolnum></citerefentry> for supported types
|
||||
and sizes.
|
||||
'';
|
||||
};
|
||||
|
||||
@ -252,7 +230,7 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.openssh.enable {
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = "sshd";
|
||||
@ -286,21 +264,16 @@ in
|
||||
''
|
||||
mkdir -m 0755 -p /etc/ssh
|
||||
|
||||
if ! test -f ${cfg.hostKeyPath}; then
|
||||
ssh-keygen -t ${hktn} -b ${toString hktb} -f ${cfg.hostKeyPath} -N ""
|
||||
fi
|
||||
|
||||
result=$(ssh-keygen -lf ${cfg.hostKeyPath}|awk '{ print ($1>=${toString hktsb}?1:0)}')
|
||||
if [ "$result" -ne "1" ]; then
|
||||
ERROR="SECURITY ALERT: SSH Host Key is too weak. Generate a strong key NOW."
|
||||
echo "$ERROR"
|
||||
echo "$ERROR" > /dev/console
|
||||
fi
|
||||
${flip concatMapStrings cfg.hostKeys (k: ''
|
||||
if ! [ -f "${k.path}" ]; then
|
||||
ssh-keygen -t "${k.type}" -b "${toString k.bits}" -f "${k.path}" -N ""
|
||||
fi
|
||||
'')}
|
||||
'';
|
||||
|
||||
serviceConfig =
|
||||
{ ExecStart =
|
||||
"${pkgs.openssh}/sbin/sshd -h ${cfg.hostKeyPath} " +
|
||||
"${pkgs.openssh}/sbin/sshd " +
|
||||
"-f ${pkgs.writeText "sshd_config" cfg.extraConfig}";
|
||||
Restart = "always";
|
||||
Type = "forking";
|
||||
@ -351,6 +324,10 @@ in
|
||||
PrintMotd no # handled by pam_motd
|
||||
|
||||
AuthorizedKeysFile ${toString cfg.authorizedKeysFiles}
|
||||
|
||||
${flip concatMapStrings cfg.hostKeys (k: ''
|
||||
HostKey ${k.path}
|
||||
'')}
|
||||
'';
|
||||
|
||||
assertions = [{ assertion = if cfg.forwardX11 then cfgc.setXAuthLocation else true;
|
||||
|
Loading…
Reference in New Issue
Block a user