Skip to content

Commit

Permalink
nixos/ssh: use upstream's default cryptographic algorithms
Browse files Browse the repository at this point in the history
Hardening SSH algorithms, which typically means dropping
all-but-the-strongest is of questionable value, given SSH's downgrade
protection[0]. We pay in compatibility, and maintenance.

Further, as noted in
https://github.com/NixOS/nixpkgs/pull/172393/files#r871727289 , both
the guidelines that we follow have not been updated in years.

The costs of having/maintaining these defaults:

* The burden of having a larger module that deviates from
upstream. We've slowly been reducing the upstream diff, to reduce
maintenance burden.
* Difficult for users to opt-out of these defaults. For example, when
using a "no OpenSSL" build of OpenSSH, having these defaults means
having to manually overriding NixOS's defaults. Upstream's defaults,
meanwhile, gracefully only use available algorithms, if OpenSSL is not
linked.
    * For users seeking to reduce attack surfaces that are fortunate
    enough to only have modern clients, they could choose to use
    `pkgs.opensshPackages.openssh.override { linkOpenssl = false; }`,
    which only supports chacha20-poly1305 and curve25519-sha256.
* NixOS#231165 unexpectedly broke some
clients.
* The time in discussing/reviewing these defaults.
* Anecdotally, a friend trying NixOS for the first time with a
ssh_config supporting only ecdh-* key exchanges was unable to SSH in
after install.

There's a certain level of enjoyment that comes from researching and
selecting a favourite suite of ciphers, but as a distro, it's not our
core competancy, and best left for upstream who are active in
advances/attacks/compatibility.

0. https://eprint.iacr.org/2016/072.pdf
  • Loading branch information
tomfitzhenry committed Jun 5, 2024
1 parent 7ebf19a commit d091822
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 55 deletions.
3 changes: 3 additions & 0 deletions nixos/doc/manual/release-notes/rl-2411.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
- `openssh` and `openssh_hpn` are now compiled without Kerberos 5 / GSSAPI support in an effort to reduce the attack surface of the components for the majority of users. Users needing this support can
use the new `opensshWithKerberos` and `openssh_hpnWithKerberos` flavors (e.g. `programs.ssh.package = pkgs.openssh_gssapi`).

- The `openssh` module now uses upstream's default cryptographic algorithms, in an effort to reduce
required maintenance.

- `nvimpager` was updated to version 0.13.0, which changes the order of user and
nvimpager settings: user commands in `-c` and `--cmd` now override the
respective default settings because they are executed later.
Expand Down
49 changes: 6 additions & 43 deletions nixos/modules/services/networking/ssh/sshd.nix
Original file line number Diff line number Diff line change
Expand Up @@ -417,36 +417,13 @@ in
};
KexAlgorithms = mkOption {
type = types.nullOr (types.listOf types.str);
default = [
"[email protected]"
"curve25519-sha256"
"[email protected]"
"diffie-hellman-group-exchange-sha256"
];
description = ''
Allowed key exchange algorithms
Uses the lower bound recommended in both
<https://stribika.github.io/2015/01/04/secure-secure-shell.html>
and
<https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67>
'';
default = null;
description = "Allowed key exchange algorithms. `null` uses upstream's default.";
};
Macs = mkOption {
type = types.nullOr (types.listOf types.str);
default = [
"[email protected]"
"[email protected]"
"[email protected]"
];
description = ''
Allowed MACs
Defaults to recommended settings from both
<https://stribika.github.io/2015/01/04/secure-secure-shell.html>
and
<https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67>
'';
default = null;
description = "Allowed MACs. `null` uses upstream's default.";
};
StrictModes = mkOption {
type = types.nullOr (types.bool);
Expand All @@ -457,22 +434,8 @@ in
};
Ciphers = mkOption {
type = types.nullOr (types.listOf types.str);
default = [
"[email protected]"
"[email protected]"
"[email protected]"
"aes256-ctr"
"aes192-ctr"
"aes128-ctr"
];
description = ''
Allowed ciphers
Defaults to recommended settings from both
<https://stribika.github.io/2015/01/04/secure-secure-shell.html>
and
<https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67>
'';
default = null;
description = "Allowed ciphers. `null` uses upstream's default.";
};
AllowUsers = mkOption {
type = with types; nullOr (listOf str);
Expand Down
10 changes: 7 additions & 3 deletions nixos/modules/system/boot/initrd-ssh.nix
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,13 @@ in
HostKey ${initrdKeyPath path}
'')}
KexAlgorithms ${concatStringsSep "," sshdCfg.settings.KexAlgorithms}
Ciphers ${concatStringsSep "," sshdCfg.settings.Ciphers}
MACs ${concatStringsSep "," sshdCfg.settings.Macs}
'' + lib.optionalString (sshdCfg.settings.KexAlgorithms != null) ''
KexAlgorithms ${concatStringsSep "," sshdCfg.settings.KexAlgorithms}
'' + lib.optionalString (sshdCfg.settings.Ciphers != null) ''
Ciphers ${concatStringsSep "," sshdCfg.settings.Ciphers}
'' + lib.optionalString (sshdCfg.settings.Macs != null) ''
MACs ${concatStringsSep "," sshdCfg.settings.Macs}
'' + ''
LogLevel ${sshdCfg.settings.LogLevel}
Expand Down
8 changes: 0 additions & 8 deletions nixos/tests/openssh.nix
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,6 @@ in {
hostKeys = [
{ type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
];
settings = {
# Must not specify the OpenSSL provided algorithms.
Ciphers = [ "[email protected]" ];
KexAlgorithms = [
"curve25519-sha256"
"[email protected]"
];
};
};
users.users.root.openssh.authorizedKeys.keys = [
snakeOilEd25519PublicKey
Expand Down
16 changes: 15 additions & 1 deletion nixos/tests/ssh-audit.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,21 @@ import ./make-test-python.nix (
networking.firewall.allowedTCPPorts = [
sshAuditPort
];
services.openssh.enable = true;
services.openssh = {
enable = true;
settings = {
# An arbitrary minimum that passes ssh-audit.
KexAlgorithms = [
"curve25519-sha256"
];
Ciphers = [
"[email protected]"
];
Macs = [
"[email protected]"
];
};
};
users.users."${sshUsername}" = {
isNormalUser = true;
openssh.authorizedKeys.keys = [
Expand Down

0 comments on commit d091822

Please sign in to comment.