feat(nixos): ssh Match User blocks

This commit is contained in:
arcnmx 2024-02-21 03:15:00 -08:00
parent 4505d8b340
commit 060517bfa0
2 changed files with 72 additions and 5 deletions

67
modules/nixos/users.nix Normal file
View file

@ -0,0 +1,67 @@
{
config,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkMerge mkAfter mkOptionDefault;
inherit (lib.attrsets) mapAttrsToList attrValues;
inherit (lib.lists) filter;
inherit (lib.strings) concatStringsSep;
opensshMatchUsers = filter (user: user.openssh.matchBlock.enable) (attrValues config.users.users);
toSshdCriteria = key: value: "${key} ${value}";
userMatchBlock = user: let
inherit (user.openssh) matchBlock;
criteria = mapAttrsToList toSshdCriteria matchBlock.criteria;
in mkAfter ''
Match ${concatStringsSep " " criteria}
${matchBlock.settingsConfig}
'';
userModule = { config, ... }: let
toSshdValue = value:
if value == true then "yes"
else if value == false then "no"
else toString value;
toSshdConf = key: value: "${key} ${toSshdValue value}";
in {
options = with lib.types; {
openssh.matchBlock = {
enable = mkEnableOption "match block" // {
default = config.openssh.matchBlock.settings != { };
};
criteria = mkOption {
type = attrsOf str;
};
settings = mkOption {
type = attrsOf (oneOf [ str path bool int ]);
default = { };
};
settingsConfig = mkOption {
type = lines;
default = "";
};
};
};
config = {
openssh.matchBlock = {
criteria = {
User = mkOptionDefault config.name;
};
settingsConfig = mkMerge (
mapAttrsToList toSshdConf config.openssh.matchBlock.settings
);
};
};
};
in {
options = with lib.types; {
users.users = mkOption {
type = attrsOf (submodule userModule);
};
};
config = {
services.openssh.extraConfig = mkMerge (
map userMatchBlock opensshMatchUsers
);
};
}

View file

@ -21,6 +21,11 @@ in {
isNormalUser = true;
autoSubUidGidRange = false;
group = username;
openssh.matchBlock.settings = {
# PasswordAuthentication works too
KbdInteractiveAuthentication = true;
ForceCommand = sshJump;
};
};
users.groups.${username} = {
gid = config.users.users.${username}.uid;
@ -28,11 +33,6 @@ in {
services.openssh = {
ports = mkAfter [ sshPort ];
extraConfig = mkAfter ''
Match User ${username}
KbdInteractiveAuthentication yes
ForceCommand ${sshJump}
'';
};
# required for kbd or password authentication
security.pam.services.sshd.unixAuth = mkForce true;