Unverified Commit a077b7fa authored by Christoph Heiss's avatar Christoph Heiss
Browse files

openssh: add {Allow,Deny}{Users,Groups} settings



`settingsFormat` unfortunaly needed a bit of a rework, see also
discussion in #227442.

Signed-off-by: default avatarChristoph Heiss <christoph@c8h4.io>
parent 8fd3a158
Loading
Loading
Loading
Loading
+66 −14
Original line number Diff line number Diff line
@@ -12,22 +12,38 @@ let
    then cfgc.package
    else pkgs.buildPackages.openssh;

  # dont use the "=" operator
  settingsFormat =
    let
      # reports boolean as yes / no
  mkValueStringSshd = with lib; v:
      mkValueString = with lib; v:
            if isInt           v then toString v
            else if isString   v then v
            else if true  ==   v then "yes"
            else if false ==   v then "no"
        else if isList     v then concatStringsSep "," v
            else throw "unsupported type ${builtins.typeOf v}: ${(lib.generators.toPretty {}) v}";

  # dont use the "=" operator
  settingsFormat = (pkgs.formats.keyValue {
      mkKeyValue = lib.generators.mkKeyValueDefault {
      mkValueString = mkValueStringSshd;
    } " ";});
      base = pkgs.formats.keyValue {
        mkKeyValue = lib.generators.mkKeyValueDefault { inherit mkValueString; } " ";
      };
      commaSeparated = [ "Ciphers" "KexAlgorithms" "Macs" ];
      spaceSeparated = [ "AuthorizedKeysFile" "AllowGroups" "AllowUsers" "DenyGroups" "DenyUsers" ];
    in {
      inherit (base) type;
      generate = name: value:
        let transformedValue = mapAttrs (key: val:
          if isList val then
            if elem key commaSeparated then concatStringsSep "," val
            else if elem key spaceSeparated then concatStringsSep " " val
            else throw "list value for unknown key ${key}: ${(lib.generators.toPretty {}) val}"
          else
            val
          ) value;
        in
          base.generate name transformedValue;
    };

  configFile = settingsFormat.generate "sshd.conf-settings" cfg.settings;
  configFile = settingsFormat.generate "sshd.conf-settings" (filterAttrs (n: v: v != null) cfg.settings);
  sshconf = pkgs.runCommand "sshd.conf-final" { } ''
    cat ${configFile} - >$out <<EOL
    ${cfg.extraConfig}
@@ -431,6 +447,42 @@ in
                <https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67>
              '';
            };
            AllowUsers = mkOption {
              type = with types; nullOr (listOf str);
              default = null;
              description = lib.mdDoc ''
                If specified, login is allowed only for the listed users.
                See {manpage}`sshd_config(5)` for details.
              '';
            };
            DenyUsers = mkOption {
              type = with types; nullOr (listOf str);
              default = null;
              description = lib.mdDoc ''
                If specified, login is denied for all listed users. Takes
                precedence over [](#opt-services.openssh.settings.AllowUsers).
                See {manpage}`sshd_config(5)` for details.
              '';
            };
            AllowGroups = mkOption {
              type = with types; nullOr (listOf str);
              default = null;
              description = lib.mdDoc ''
                If specified, login is allowed only for users part of the
                listed groups.
                See {manpage}`sshd_config(5)` for details.
              '';
            };
            DenyGroups = mkOption {
              type = with types; nullOr (listOf str);
              default = null;
              description = lib.mdDoc ''
                If specified, login is denied for all users part of the listed
                groups. Takes precedence over
                [](#opt-services.openssh.settings.AllowGroups). See
                {manpage}`sshd_config(5)` for details.
              '';
            };
          };
        });
      };