mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-05 21:03:40 +00:00
nixos/sshd: add enableRecommendedAlgorithms option
Prior to this commit, NixOS enabled a set of curated algorithms. This commit allows users to opt-out of this curation, and instead use the upstream algorithms. This also allows users to set Ciphers/KexAlgorithms/Macs themselves without lib.mkForce (and thus wield NixOS modules to build the list). Tests have been added to ensure test this new option works.
This commit is contained in:
@@ -342,6 +342,8 @@ See <https://github.com/NixOS/nixpkgs/issues/481673>.
|
||||
|
||||
- `services.openssh` now supports generating host SSH keys by setting `services.openssh.generateHostKeys = true` while leaving `services.openssh.enable` disabled. This is particularly useful for systems that have no need of an SSH daemon but want SSH host keys for other purposes such as using agenix or sops-nix.
|
||||
|
||||
- `services.openssh.enableRecommendedAlgorithms` has been added to allow users to opt out of NixOS's curated set of recommended algorithms. This set to true by default, and thus is not a breaking change. Users may want to set this to false if they prefer upstream's default algorithms. See <https://github.com/NixOS/nixpkgs/pull/471330>.
|
||||
|
||||
- IPVLAN interfaces can now be configured through the `networking.ipvlans` option in the networking module.
|
||||
|
||||
- `services.caddy` now supports setting `httpPort` and `httpsPort` and opening them in the firewall via `openFirewall`.
|
||||
|
||||
@@ -412,6 +412,16 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
enableRecommendedAlgorithms = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Use algorithms curated and recommended by NixOS.
|
||||
|
||||
Set to false to use upstream's default algorithms.
|
||||
'';
|
||||
};
|
||||
|
||||
authorizedKeysFiles = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
@@ -571,37 +581,64 @@ in
|
||||
};
|
||||
KexAlgorithms = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = [
|
||||
"mlkem768x25519-sha256"
|
||||
"sntrup761x25519-sha512"
|
||||
"sntrup761x25519-sha512@openssh.com"
|
||||
"curve25519-sha256"
|
||||
"curve25519-sha256@libssh.org"
|
||||
"diffie-hellman-group-exchange-sha256"
|
||||
];
|
||||
default =
|
||||
if config.services.openssh.enableRecommendedAlgorithms then
|
||||
[
|
||||
"mlkem768x25519-sha256"
|
||||
"sntrup761x25519-sha512"
|
||||
"sntrup761x25519-sha512@openssh.com"
|
||||
"curve25519-sha256"
|
||||
"curve25519-sha256@libssh.org"
|
||||
"diffie-hellman-group-exchange-sha256"
|
||||
]
|
||||
else
|
||||
null;
|
||||
defaultText = ''
|
||||
if config.services.openssh.enableRecommendedAlgorithms then
|
||||
[
|
||||
"mlkem768x25519-sha256"
|
||||
"sntrup761x25519-sha512"
|
||||
"sntrup761x25519-sha512@openssh.com"
|
||||
"curve25519-sha256"
|
||||
"curve25519-sha256@libssh.org"
|
||||
"diffie-hellman-group-exchange-sha256"
|
||||
]
|
||||
else
|
||||
null;
|
||||
'';
|
||||
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>
|
||||
Defaults to a curated set of algorithms.
|
||||
Set enableRecommendedAlgorithms to false to use upstream's defaults.
|
||||
'';
|
||||
};
|
||||
Macs = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = [
|
||||
"hmac-sha2-512-etm@openssh.com"
|
||||
"hmac-sha2-256-etm@openssh.com"
|
||||
"umac-128-etm@openssh.com"
|
||||
];
|
||||
default =
|
||||
if config.services.openssh.enableRecommendedAlgorithms then
|
||||
[
|
||||
"hmac-sha2-512-etm@openssh.com"
|
||||
"hmac-sha2-256-etm@openssh.com"
|
||||
"umac-128-etm@openssh.com"
|
||||
]
|
||||
else
|
||||
null;
|
||||
defaultText = ''
|
||||
if config.services.openssh.enableRecommendedAlgorithms then
|
||||
[
|
||||
"hmac-sha2-512-etm@openssh.com"
|
||||
"hmac-sha2-256-etm@openssh.com"
|
||||
"umac-128-etm@openssh.com"
|
||||
]
|
||||
else
|
||||
null;
|
||||
'';
|
||||
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>
|
||||
Defaults to a curated set of algorithms.
|
||||
Set enableRecommendedAlgorithms to false to use upstream's defaults.
|
||||
'';
|
||||
};
|
||||
StrictModes = lib.mkOption {
|
||||
@@ -613,21 +650,36 @@ in
|
||||
};
|
||||
Ciphers = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = [
|
||||
"chacha20-poly1305@openssh.com"
|
||||
"aes256-gcm@openssh.com"
|
||||
"aes128-gcm@openssh.com"
|
||||
"aes256-ctr"
|
||||
"aes192-ctr"
|
||||
"aes128-ctr"
|
||||
];
|
||||
default =
|
||||
if config.services.openssh.enableRecommendedAlgorithms then
|
||||
[
|
||||
"chacha20-poly1305@openssh.com"
|
||||
"aes256-gcm@openssh.com"
|
||||
"aes128-gcm@openssh.com"
|
||||
"aes256-ctr"
|
||||
"aes192-ctr"
|
||||
"aes128-ctr"
|
||||
]
|
||||
else
|
||||
null;
|
||||
defaultText = ''
|
||||
if config.services.openssh.enableRecommendedAlgorithms then
|
||||
[
|
||||
"chacha20-poly1305@openssh.com"
|
||||
"aes256-gcm@openssh.com"
|
||||
"aes128-gcm@openssh.com"
|
||||
"aes256-ctr"
|
||||
"aes192-ctr"
|
||||
"aes128-ctr"
|
||||
]
|
||||
else
|
||||
null;
|
||||
'';
|
||||
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>
|
||||
Defaults to a curated set of algorithms.
|
||||
Set enableRecommendedAlgorithms to false to use upstream's defaults.
|
||||
'';
|
||||
};
|
||||
AllowUsers = lib.mkOption {
|
||||
|
||||
@@ -193,12 +193,32 @@ in
|
||||
path = "/etc/ssh/ssh_host_ed25519_key";
|
||||
}
|
||||
];
|
||||
# The NixOS-curated algorithms require OpenSSL, and so since this test is against an OpenSSH-without-OpenSSL, we have to use the default algorithms, which adapt to not having OpenSSL.
|
||||
enableRecommendedAlgorithms = false;
|
||||
};
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
snakeOilEd25519PublicKey
|
||||
];
|
||||
};
|
||||
|
||||
server-default-algorithms =
|
||||
{ ... }:
|
||||
{
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
enableRecommendedAlgorithms = false;
|
||||
};
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
snakeOilEd25519PublicKey
|
||||
];
|
||||
};
|
||||
|
||||
server-null-algorithms =
|
||||
{ ... }:
|
||||
{
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
# Since this test is against an OpenSSH-without-OpenSSL,
|
||||
# we have to override NixOS's defaults ciphers (which require OpenSSL)
|
||||
# and instead set these to null, which will mean OpenSSH uses its defaults.
|
||||
# Expectedly, OpenSSH's defaults don't require OpenSSL when it's compiled
|
||||
# without OpenSSL.
|
||||
Ciphers = null;
|
||||
KexAlgorithms = null;
|
||||
Macs = null;
|
||||
@@ -294,10 +314,12 @@ in
|
||||
|
||||
server.wait_for_unit("sshd", timeout=60)
|
||||
server_allowed_users.wait_for_unit("sshd", timeout=60)
|
||||
server_default_algorithms.wait_for_unit("sshd", timeout=60)
|
||||
server_localhost_only.wait_for_unit("sshd", timeout=60)
|
||||
server_match_rule.wait_for_unit("sshd", timeout=60)
|
||||
server_no_openssl.wait_for_unit("sshd", timeout=60)
|
||||
server_no_pam.wait_for_unit("sshd", timeout=60)
|
||||
server_null_algorithms.wait_for_unit("sshd", timeout=60)
|
||||
server_null_pam.wait_for_unit("sshd", timeout=60)
|
||||
server_null_pam.fail("journalctl -u sshd.service | grep 'Unsupported option UsePAM'")
|
||||
server_sftp.wait_for_unit("sshd", timeout=60)
|
||||
@@ -402,6 +424,26 @@ in
|
||||
timeout=30
|
||||
)
|
||||
|
||||
with subtest("null-algorithms"):
|
||||
client.succeed(
|
||||
"cat ${snakeOilEd25519PrivateKey} > privkey.snakeoil"
|
||||
)
|
||||
client.succeed("chmod 600 privkey.snakeoil")
|
||||
client.succeed(
|
||||
"ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server-null-algorithms true",
|
||||
timeout=30
|
||||
)
|
||||
|
||||
with subtest("no-openssl"):
|
||||
client.succeed(
|
||||
"cat ${snakeOilEd25519PrivateKey} > privkey.snakeoil"
|
||||
)
|
||||
client.succeed("chmod 600 privkey.snakeoil")
|
||||
client.succeed(
|
||||
"ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server-default-algorithms true",
|
||||
timeout=30
|
||||
)
|
||||
|
||||
with subtest("no-pam"):
|
||||
client.succeed(
|
||||
"cat ${snakeOilPrivateKey} > privkey.snakeoil"
|
||||
|
||||
Reference in New Issue
Block a user