From 3fe773a17452ecb0d5ca7379e33cfbd6924a52b5 Mon Sep 17 00:00:00 2001 From: DavHau Date: Sun, 26 May 2024 18:46:22 +0200 Subject: [PATCH] nixos/openssh: allow removing settings # Motivation So far it was not possible to configure sshd to allow password authentication only for a specific user. This is because in the generated config a `Match User xxx` section would be required before the global `PasswordAuthentication` is defined, as otherwise the global option always takes precedence. The same problem occurs with multiple other options under `settings`. # Done This PR fixes that issue for all settings by simply allowing them to be overridden with `null`, which leads to a removal of that setting from the config. The user can then correctly configure user specific settings using extraConfig, like this: ``` Match User user1 PasswordAuthentication yes Match all PasswordAuthentication no ``` --- .../modules/services/networking/ssh/sshd.nix | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index 0fdb708bf052..98ffde9e821e 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -342,7 +342,7 @@ in freeformType = settingsFormat.type; options = { AuthorizedPrincipalsFile = mkOption { - type = types.str; + type = types.nullOr types.str; default = "none"; # upstream default description = '' Specifies a file that lists principal names that are accepted for certificate authentication. The default @@ -350,16 +350,18 @@ in ''; }; LogLevel = mkOption { - type = types.enum [ "QUIET" "FATAL" "ERROR" "INFO" "VERBOSE" "DEBUG" "DEBUG1" "DEBUG2" "DEBUG3" ]; + type = types.nullOr (types.enum [ "QUIET" "FATAL" "ERROR" "INFO" "VERBOSE" "DEBUG" "DEBUG1" "DEBUG2" "DEBUG3" ]); default = "INFO"; # upstream default description = '' Gives the verbosity level that is used when logging messages from sshd(8). Logging with a DEBUG level violates the privacy of users and is not recommended. ''; }; - UsePAM = mkEnableOption "PAM authentication" // { default = true; }; + UsePAM = + mkEnableOption "PAM authentication" + // { default = true; type = types.nullOr types.bool; }; UseDns = mkOption { - type = types.bool; + type = types.nullOr types.bool; # apply if cfg.useDns then "yes" else "no" default = false; description = '' @@ -370,14 +372,14 @@ in ''; }; X11Forwarding = mkOption { - type = types.bool; + type = types.nullOr types.bool; default = false; description = '' Whether to allow X11 connections to be forwarded. ''; }; PasswordAuthentication = mkOption { - type = types.bool; + type = types.nullOr types.bool; default = true; description = '' Specifies whether password authentication is allowed. @@ -385,20 +387,20 @@ in }; PermitRootLogin = mkOption { default = "prohibit-password"; - type = types.enum ["yes" "without-password" "prohibit-password" "forced-commands-only" "no"]; + type = types.nullOr (types.enum ["yes" "without-password" "prohibit-password" "forced-commands-only" "no"]); description = '' Whether the root user can login using ssh. ''; }; KbdInteractiveAuthentication = mkOption { - type = types.bool; + type = types.nullOr types.bool; default = true; description = '' Specifies whether keyboard-interactive authentication is allowed. ''; }; GatewayPorts = mkOption { - type = types.str; + type = types.nullOr types.str; default = "no"; description = '' Specifies whether remote hosts are allowed to connect to @@ -407,7 +409,7 @@ in ''; }; KexAlgorithms = mkOption { - type = types.listOf types.str; + type = types.nullOr (types.listOf types.str); default = [ "sntrup761x25519-sha512@openssh.com" "curve25519-sha256" @@ -424,7 +426,7 @@ in ''; }; Macs = mkOption { - type = types.listOf types.str; + type = types.nullOr (types.listOf types.str); default = [ "hmac-sha2-512-etm@openssh.com" "hmac-sha2-256-etm@openssh.com" @@ -440,14 +442,14 @@ in ''; }; StrictModes = mkOption { - type = types.bool; + type = types.nullOr (types.bool); default = true; description = '' Whether sshd should check file modes and ownership of directories ''; }; Ciphers = mkOption { - type = types.listOf types.str; + type = types.nullOr (types.listOf types.str); default = [ "chacha20-poly1305@openssh.com" "aes256-gcm@openssh.com" @@ -502,7 +504,9 @@ in ''; }; # Disabled by default, since pam_motd handles this. - PrintMotd = mkEnableOption "printing /etc/motd when a user logs in interactively"; + PrintMotd = + mkEnableOption "printing /etc/motd when a user logs in interactively" + // { type = types.nullOr types.bool; }; }; }); }; @@ -639,7 +643,10 @@ in security.pam.services.sshd = lib.mkIf cfg.settings.UsePAM { startSession = true; showMotd = true; - unixAuth = cfg.settings.PasswordAuthentication; + unixAuth = + if cfg.settings.PasswordAuthentication == true + then true + else false; }; # These values are merged with the ones defined externally, see: