feat(idp): samba ldap attributes

This commit is contained in:
arcnmx 2024-03-17 16:36:06 -07:00
parent 4ad8e34fa4
commit 81bd1a1a15
12 changed files with 670 additions and 3 deletions

View file

@ -123,7 +123,7 @@
(mkWrapper rec {
name = "ldapsearch";
attr = "pkgs.openldap";
exe = "${name} -H ${ldapHostArg} -b ${ldapBaseDn} -o ldif_wrap=no";
exe = ''${name} -H ${ldapHostArg} -b "''${LDAPSEARCH_BASE_DN-${ldapBaseDn}}" -o ldif_wrap=no'';
})
(mkWrapper rec {
name = "ldapadd";

View file

@ -0,0 +1,164 @@
{
config,
lib,
inputs,
pkgs,
...
}: let
inherit (inputs.self.lib.lib) mapOptionDefaults;
inherit (lib.options) mkEnableOption;
inherit (lib.modules) mkIf mkOptionDefault;
inherit (lib.attrsets) attrValues;
inherit (lib.lists) filter;
inherit (lib.strings) concatStringsSep concatMapStringsSep escapeShellArgs;
inherit (config.users) ldap;
cfg = config.users.ldap.management;
enabledObjects = filter (object: object.enable) (attrValues cfg.objects);
smbSyncUsers = filter (user: user.samba.sync.enable) (attrValues cfg.users);
smbSyncGroups = filter (group: group.samba.sync.enable) (attrValues cfg.groups);
modifyObjects = filter (object: object.changeType == "modify") enabledObjects;
addObjects = filter (object: object.changeType == "add") enabledObjects;
deleteObjects = filter (object: object.changeType == "delete") enabledObjects;
additions = pkgs.writeText "ldap-management-add.ldap" (
concatMapStringsSep "\n" (object: object.changeText) addObjects
);
# TODO: split up adds and replaces so this can be done without `ldapmodify -c`
modifications = pkgs.writeText "ldap-management-modify.ldap" (
concatMapStringsSep "\n" (object: object.changeText) modifyObjects
);
deletions = pkgs.writeText "ldap-management-delete.ldap" (
concatMapStringsSep "\n" (object: object.changeText) deleteObjects
);
objectClassAttr = "objectClass";
sidAttr = "ipaNTSecurityIdentifier";
ntHashAttr = "ipaNTHash";
authTypeAttr = "ipaUserAuthType";
userSearchAttrs = [ objectClassAttr sidAttr authTypeAttr ntHashAttr ];
groupSearchAttrs = [ objectClassAttr sidAttr ];
managementScript = pkgs.writeShellScript "ldap-management.sh" ''
set -eu
ldapsearch() {
command ldapsearch -QLLL -o ldif_wrap=no "$@"
}
ldapmodify() {
command ldapmodify -Q "$@"
}
ldap_parse() {
local LDAP_ATTR=$1 LDAP_LIMIT LDAP_LINE LDAP_COUNT=0
shift 1
local LDAP_LIMIT=''${1-1}
while read -r LDAP_LINE; do
if [[ $LDAP_LIMIT -eq 0 ]]; then
break
fi
if [[ $LDAP_LINE = "$LDAP_ATTR:: "* ]]; then
printf '%s\n' "$LDAP_LINE" | cut -d ' ' -f 2- | base64 -d
elif [[ $LDAP_LINE = "$LDAP_ATTR: "* ]]; then
printf '%s\n' "$LDAP_LINE" | cut -d ' ' -f 2-
else
continue
fi
LDAP_COUNT=$((LDAP_COUNT+1))
LDAP_LIMIT=$((LDAP_LIMIT-1))
done
if [[ $LDAP_COUNT -eq 0 ]]; then
echo "$LDAP_ATTR not found" >&2
return 1
fi
}
smbsync_group() {
local LDAP_GROUP_CN=$1 SMB_GROUP_DATA SMB_GROUP_SID
shift 1
echo "updating cn=''${LDAP_GROUP_CN},${ldap.groupDnSuffix} ..." >&2
SMB_GROUP_DATA=$(ldapsearch -z1 \
-b "${ldap.groupDnSuffix}${ldap.base}" \
"(&(cn=$LDAP_GROUP_CN)(${objectClassAttr}=posixgroup))" \
${escapeShellArgs groupSearchAttrs}
)
SMB_GROUP_SID=$(ldap_parse ${sidAttr} <<< "$SMB_GROUP_DATA")
ldapmodify <<EOF
dn: cn=$LDAP_GROUP_CN,${ldap.groupDnSuffix}${ldap.base}
changetype: modify
replace: sambaSID
sambaSID: $SMB_GROUP_SID
-
EOF
}
smbsync_user() {
local LDAP_USER_UID=$1 SMB_USER_DATA SMB_USER_SID SMB_USER_NTPASS
shift 1
echo "updating uid=''${LDAP_USER_UID},${ldap.userDnSuffix} ..." >&2
SMB_USER_DATA=$(ldapsearch -z1 \
-b "${ldap.userDnSuffix}${ldap.base}" \
"(&(uid=$LDAP_USER_UID)(${objectClassAttr}=posixaccount))" \
${escapeShellArgs userSearchAttrs}
)
SMB_USER_SID=$(ldap_parse ${sidAttr} <<< "$SMB_USER_DATA")
SMB_USER_NTPASS=$(ldap_parse ${ntHashAttr} <<< "$SMB_USER_DATA" | xxd -p)
SMB_USER_NTPASS=''${SMB_USER_NTPASS^^}
ldapmodify <<EOF
dn: uid=$LDAP_USER_UID,${ldap.userDnSuffix}${ldap.base}
changetype: modify
replace: sambaSID
sambaSID: $SMB_USER_SID
-
replace: sambaNTPassword
sambaNTPassword: $SMB_USER_NTPASS
-
EOF
}
ldapwhoami
ldapmodify -cf "$MAN_LDAP_ADD"
ldapmodify -c -f "$MAN_LDAP_MODIFY" || true
ldapmodify -f "$MAN_LDAP_DELETE"
IFS=',' declare -a 'SMB_SYNC_GROUPS=($SMB_SYNC_GROUPS)'
for SMB_GROUP_CN in "''${SMB_SYNC_GROUPS[@]}"; do
smbsync_group "$SMB_GROUP_CN"
done
IFS=',' declare -a 'SMB_SYNC_USERS=($SMB_SYNC_USERS)'
for SMB_USER_UID in "''${SMB_SYNC_USERS[@]}"; do
smbsync_user "$SMB_USER_UID"
done
'';
in {
options.users.ldap.management = with lib.types; {
enable = mkEnableOption "LDAP object management";
};
config = mkIf cfg.enable {
systemd.services.ldap-management = rec {
wantedBy = [ "multi-user.target" ];
wants = [ "krb5-host.service" ];
after = wants;
path = [ config.services.openldap.package pkgs.coreutils pkgs.xxd ];
environment = mapOptionDefaults {
LDAPBASE = ldap.base;
LDAPURI = "ldaps://ldap.int.${config.networking.domain}";
LDAPSASL_MECH = "GSSAPI";
LDAPSASL_AUTHCID = "dn:krbprincipalname=host/${config.networking.fqdn}@${config.security.ipa.realm},cn=services,cn=accounts,${ldap.base}";
# LDAPBINDDN?
SMB_SYNC_GROUPS = concatStringsSep "," (map (group: group.name) smbSyncGroups);
SMB_SYNC_USERS = concatStringsSep "," (map (user: user.uid) smbSyncUsers);
MAN_LDAP_ADD = "${additions}";
MAN_LDAP_MODIFY = "${modifications}";
MAN_LDAP_DELETE = "${deletions}";
};
serviceConfig = {
Type = mkOptionDefault "oneshot";
ExecStart = [ "${managementScript}" ];
};
};
};
}

View file

@ -0,0 +1,175 @@
{
config,
lib,
inputs,
...
}: let
inherit (inputs.self.lib.lib) unmerged mkAlmostOptionDefault;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkOptionDefault;
inherit (lib.attrsets) filterAttrs mapAttrsToList nameValuePair;
inherit (lib.lists) optional toList;
inherit (lib.strings) toLower removeSuffix concatMapStrings concatStringsSep optionalString;
ldap'lib = {
specialArgs = {
nixosConfig = config;
ldap = config.users.ldap // {
lib = config.lib.ldap;
};
};
objectModule = ldapObjectModule;
objectType = lib.types.submoduleWith {
modules = [ ldapObjectModule ];
inherit (ldap'lib) specialArgs;
};
objectSettingType' = lib.types.submoduleWith {
modules = [ ldapObjectSettingModule ];
inherit (ldap'lib) specialArgs;
};
objectSettingType = let
mapToObjectSetting = value: {
inherit value;
};
in lib.types.coercedTo ldapValueType mapToObjectSetting ldap'lib.objectSettingType';
objectSettingsModule = ldapObjectSettingsModule;
objectSettingsType = lib.types.submoduleWith {
modules = [ ldapObjectSettingsModule ];
inherit (ldap'lib) specialArgs;
};
mapObjectSettingsToPair = settings: nameValuePair
(removeSuffix ",${config.users.ldap.base}" settings.dn)
(unmerged.mergeAttrs settings.settings);
mapObjectSettingsToAttr = settings: let
pair = ldap'lib.mapObjectSettingsToPair settings;
in {
${pair.name} = pair.value;
};
mkLdapModifyObjectSettingValues = let
mkLdapModifyValues = setting: concatMapStrings (value: ''
${setting.key}: ${toString value}
'') (toList setting.value);
in mkLdapModifyValues;
mkLdapModifyObjectSettings = let
mkLdapModifySetting = setting: ''
${setting.modifyType}: ${setting.key}
'' + ldap'lib.mkLdapModifyObjectSettingValues setting;
in settings: mapAttrsToList (_: mkLdapModifySetting) settings;
mkLdapAddObjectSettings = settings: mapAttrsToList (_: ldap'lib.mkLdapModifyObjectSettingValues) settings;
mkLdapModifyObject = let
mkHeader = changeType: object: ''
dn: ${object.dn}
changetype: ${changeType}
'';
in {
modify = object: let
enabledSettings' = filterAttrs (_: setting: setting.enable) object.settings;
enabledSettings = ldap'lib.mkLdapModifyObjectSettings enabledSettings';
replaceSettings' = filterAttrs (_: setting: setting.modifyType == "replace") enabledSettings';
replaceSettings = ldap'lib.mkLdapModifyObjectSettings replaceSettings';
addSettings' = filterAttrs (_: setting: setting.modifyType == "add") enabledSettings';
replaceText = mkHeader "modify" object + concatStringsSep "-\n" replaceSettings;
text = mkHeader "modify" object + concatStringsSep "-\n" enabledSettings;
in concatStringsSep "-\n\n" (
[ text ]
++ optional (addSettings' != { }) replaceText
);
add = object: let
enabledSettings = filterAttrs (_: setting: setting.enable) object.settings;
addSettings = ldap'lib.mkLdapAddObjectSettings enabledSettings;
in mkHeader "add" object + concatStringsSep "-\n" addSettings;
delete = object: mkHeader "delete" object;
modrdn = object: { newrdn, deleteoldrdn, newsuperior }: let
modifySettings = ''
newrdn: ${newrdn}
deleteoldrdn: ${if deleteoldrdn == true then "1" else if deleteoldrdn == "false" then "0" else toString deleteoldrdn}
'' + optionalString (newsuperior != null) ''
newsuperior: ${newsuperior}
'';
in mkHeader "modrdn" + modifySettings;
moddn = object: { deleteoldrdn, newsuperior }: let
modifySettings = ''
deleteoldrdn: ${if deleteoldrdn == true then "1" else if deleteoldrdn == "false" then "0" else toString deleteoldrdn}
newsuperior: ${newsuperior}
'';
in mkHeader "moddn" + modifySettings;
};
};
ldapPrimitiveType = with lib.types; oneOf [ str int ];
ldapValueType = with lib.types; oneOf [ ldapPrimitiveType (listOf ldapPrimitiveType) ];
ldapObjectSettingModule = {config, name, ...}: {
options = with lib.types; {
enable = mkEnableOption "setting" // {
default = true;
};
key = mkOption {
type = str;
default = name;
};
value = mkOption {
type = ldapValueType;
};
modifyType = mkOption {
type = enum [ "replace" "add" "delete" ];
default = if toLower config.key == "objectclass" then "add" else "replace";
};
};
};
ldapObjectSettingsModule = {config, ...}: {
options = with lib.types; {
enable = mkEnableOption "object" // {
default = true;
};
dn = mkOption {
type = str;
};
settings = mkOption {
type = unmerged.types.attrs;
};
};
config = {
settings = {
dn = mkAlmostOptionDefault config.dn;
};
};
};
ldapObjectModule = {config, name, ldap, ...}: {
options = with lib.types; {
enable = mkEnableOption "object creation" // {
default = true;
};
dn = mkOption {
type = str;
default = "${name},${ldap.base}";
};
changeType = mkOption {
type = enum [ "modify" "add" "delete" "modrdn" "moddn" ];
default = "modify";
};
changeText = mkOption {
type = lines;
};
objectClasses = mkOption {
type = listOf str;
default = [ ];
};
settings = mkOption {
type = attrsOf ldap.lib.objectSettingType;
default = { };
};
};
config = {
settings = {
objectClass = mkIf (config.objectClasses != [ ]) (mkOptionDefault config.objectClasses);
};
changeText = mkOptionDefault (ldap'lib.mkLdapModifyObject.${config.changeType} config);
};
};
in {
options.users.ldap = with lib.types; {
management.objects = mkOption {
type = attrsOf ldap'lib.objectType;
default = { };
};
};
config.lib.ldap = ldap'lib;
}

View file

@ -0,0 +1,201 @@
{
config,
lib,
inputs,
...
}: let
inherit (inputs.self.lib.lib) mkAlmostOptionDefault mapListToAttrs;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
inherit (lib.attrsets) mapAttrs mapAttrsToList;
inherit (lib.lists) filter;
inherit (lib.strings) concatStrings;
cfg = config.users.ldap;
ldap'lib = config.lib.ldap;
userModule = {config, nixosConfig, name, ldap, ...}: let
user = nixosConfig.users.users.${config.user.name};
sambaAccountFlags = {
normalUser = "U";
disabled = "D";
homeRequired = "H";
temporaryDuplicate = "T";
mnsLogon = "M";
workstationTrust = "W";
serverTrust = "S";
domainTrust = "I";
autoLock = "L";
noPasswordExpiry = "X";
noPasswordRequired = "N";
};
mkSambaAccountFlags = flags: let
empty = " ";
flagChar = char: flag: if flag then char else empty;
flagChars = mapAttrsToList (name: flagChar sambaAccountFlags.${name}) flags;
in "[${concatStrings flagChars}]";
in {
options = with lib.types; {
user = {
enable = mkEnableOption "system user";
name = mkOption {
type = nullOr str;
default = null;
};
uid = mkOption {
type = nullOr int;
default = null;
};
};
uid = mkOption {
type = str;
default = name;
};
samba = {
enable = mkEnableOption "SMB user";
sync.enable = mkEnableOption "IPA data sync";
sid = mkOption {
type = nullOr str;
default = null;
};
accountFlags = mapAttrs (_: _: mkOption {
type = bool;
default = false;
}) sambaAccountFlags;
};
object = mkOption {
type = ldap.lib.objectSettingsType;
};
};
config = {
user = {
name = mkIf config.user.enable (mkAlmostOptionDefault name);
uid = mkIf (config.user.name != null) (mkAlmostOptionDefault user.uid);
};
samba = {
sid = mkIf (ldap.samba.domainSID != null && config.user.uid != null) (
mkAlmostOptionDefault "${ldap.samba.domainSID}-${toString (ldap.samba.sidUserOffset + config.user.uid)}"
);
accountFlags = {
normalUser = mkIf (config.user.name != null) (mkAlmostOptionDefault user.isNormalUser);
};
};
object = {
enable = mkAlmostOptionDefault config.samba.enable;
dn = mkOptionDefault "uid=${config.uid},${ldap.userDnSuffix}${ldap.base}";
settings = {
objectClasses = mkIf config.samba.enable [ "sambaSamAccount" ];
settings = mkIf config.samba.enable {
sambaSID = mkIf (config.samba.sid != null) (mkOptionDefault config.samba.sid);
sambaAcctFlags = mkOptionDefault (mkSambaAccountFlags config.samba.accountFlags);
};
};
};
};
};
groupModule = {config, nixosConfig, name, ldap, ...}: let
group = nixosConfig.users.groups.${config.group.name};
in {
options = with lib.types; {
group = {
enable = mkEnableOption "system group";
name = mkOption {
type = nullOr str;
default = null;
};
gid = mkOption {
type = nullOr int;
default = null;
};
};
name = mkOption {
type = str;
default = name;
};
samba = {
enable = mkEnableOption "SMB group";
sync.enable = mkEnableOption "IPA data sync";
sid = mkOption {
type = nullOr str;
default = null;
};
groupType = mkOption {
type = int;
default = 2;
description = "http://pig.made-it.com/samba-accounts.html#22762";
};
};
object = mkOption {
type = ldap.lib.objectSettingsType;
};
};
config = {
group = {
name = mkIf config.group.enable (mkAlmostOptionDefault name);
gid = mkIf (config.group.name != null) (mkAlmostOptionDefault group.gid);
};
samba = {
sid = mkIf (ldap.samba.domainSID != null && config.group.gid != null) (
mkAlmostOptionDefault "${ldap.samba.domainSID}-${toString (ldap.samba.sidGroupOffset + config.group.gid)}"
);
};
object = {
enable = mkAlmostOptionDefault config.samba.enable;
dn = mkOptionDefault "cn=${config.name},${ldap.groupDnSuffix}${ldap.base}";
settings = {
objectClasses = mkIf config.samba.enable [ "sambaGroupMapping" ];
settings = mkIf config.samba.enable {
sambaSID = mkIf (config.samba.sid != null) (mkOptionDefault config.samba.sid);
sambaGroupType = mkOptionDefault config.samba.groupType;
};
};
};
};
};
in {
options.users.ldap = with lib.types; {
management = {
users = mkOption {
type = attrsOf (submoduleWith {
modules = [ userModule ];
inherit (config.lib.ldap) specialArgs;
});
default = { };
};
groups = mkOption {
type = attrsOf (submoduleWith {
modules = [ groupModule ];
inherit (config.lib.ldap) specialArgs;
});
default = { };
};
};
samba = {
domainSID = mkOption {
type = nullOr str;
default = null;
};
sidUserOffset = mkOption {
type = int;
default = -7999;
};
sidGroupOffset = mkOption {
type = int;
default = 256 + 1;
};
};
userDnSuffix = mkOption {
type = str;
default = "";
};
groupDnSuffix = mkOption {
type = str;
default = "";
};
};
config.users.ldap = {
management.objects = let
userObjects = mapAttrsToList (_: user: user.object) cfg.management.users;
groupObjects = mapAttrsToList (_: group: group.object) cfg.management.groups;
enabledObjects = filter (object: object.enable) (userObjects ++ groupObjects);
in mapListToAttrs ldap'lib.mapObjectSettingsToPair enabledObjects;
};
}

View file

@ -154,6 +154,7 @@ in {
${virtualHosts.freeipa'ca.serverName} ${upstreams.freeipa};
${nginx.access.ldap.domain} ${upstreams.ldap};
${nginx.access.ldap.localDomain} ${upstreams.ldap};
${nginx.access.ldap.intDomain} ${upstreams.ldap};
${nginx.access.ldap.tailDomain} ${upstreams.ldap};
default ${upstreams.nginx};
}
@ -244,6 +245,7 @@ in {
};
freeipa'ldap'local = {
serverName = mkDefault ldap.localDomain;
serverAliases = [ ldap.intDomain ];
ssl.cert.copyFromVhost = "freeipa'ldap";
globalRedirect = virtualHosts.freeipa'web'local.serverName;
local.enable = true;

View file

@ -35,6 +35,10 @@ in {
type = str;
default = "ldap.local.${config.networking.domain}";
};
intDomain = mkOption {
type = str;
default = "ldap.int.${config.networking.domain}";
};
tailDomain = mkOption {
type = str;
default = "ldap.tail.${config.networking.domain}";

View file

@ -1,6 +1,6 @@
{ inputs, pkgs, config, lib, ... }: let
inherit (inputs.self.lib.lib) mkBaseDn;
inherit (lib.modules) mkIf mkBefore mkDefault;
inherit (lib.modules) mkIf mkBefore mkDefault mkOptionDefault;
inherit (lib.strings) toUpper;
inherit (config.networking) domain;
cfg = config.security.ipa;
@ -19,6 +19,14 @@ in {
# once the sops secret has been updated with keytab...
# :; systemctl restart sssd
config = {
users.ldap = {
base = mkDefault baseDn;
server = mkDefault "ldaps://ldap.local.${domain}";
samba.domainSID = mkDefault "S-1-5-21-1535650373-1457993706-2355445124";
#samba.domainSID = mkDefault "S-1-5-21-208293719-3143191303-229982100"; # HAKUREI
userDnSuffix = mkDefault "cn=users,cn=accounts,";
groupDnSuffix = mkDefault "cn=groups,cn=accounts,";
};
security.ipa = {
enable = mkDefault true;
certificate = mkDefault caPem;
@ -41,5 +49,18 @@ in {
path = "/etc/krb5.keytab";
};
};
systemd.services.krb5-host = let
krb5-host = pkgs.writeShellScript "krb5-host" ''
set -eu
kinit -k host/${config.networking.fqdn}
'';
in mkIf cfg.enable {
path = [ config.security.krb5.package ];
serviceConfig = {
Type = mkOptionDefault "oneshot";
ExecStart = [ "${krb5-host}" ];
};
};
};
}

View file

@ -19,7 +19,7 @@ in {
securityType = mkDefault "user";
ldap = {
enable = mkDefault true;
url = mkDefault "ldaps://ldap.local.${domain}";
url = mkDefault "ldaps://ldap.int.${domain}";
baseDn = mkDefault (mkBaseDn domain);
adminDn = mkDefault "uid=samba,cn=sysaccounts,cn=etc,${cfg.ldap.baseDn}";
adminPasswordPath = mkIf cfg.ldap.enable (
@ -56,6 +56,7 @@ in {
"winbind scan trusted domains" = false;
"winbind use default domain" = true;
"domain master" = false;
"domain logons" = true;
"remote announce" = mkIf hasIpv4 [
"10.1.1.255/${cfg.settings.workgroup}"
];

95
nixos/users/ldap.nix Normal file
View file

@ -0,0 +1,95 @@
{config, lib, inputs, ...}: let
inherit (inputs.self.lib.lib) userIs mkAlmostOptionDefault;
inherit (lib.modules) mkMerge mkDefault;
inherit (lib.attrsets) mapAttrs filterAttrs;
ldapUsers = filterAttrs (_: userIs "peeps") config.users.users;
ldapGroups = filterAttrs (_: group: group.gid != null && group.gid >= 8000 && group.gid < 8256) config.users.groups;
management = {
users = mapAttrs (name: user: {
user.name = mkAlmostOptionDefault name;
samba = {
enable = mkDefault true;
sync.enable = mkDefault true;
accountFlags = {
noPasswordExpiry = mkDefault true;
};
};
}) ldapUsers;
groups = mapAttrs (name: group: {
group.name = mkAlmostOptionDefault name;
samba.enable = mkDefault true;
}) ldapGroups;
};
in {
config.users.ldap = {
management = mkMerge [ management {
users = {
guest.user.enable = true;
admin = {
user.enable = true;
samba.enable = true;
};
opl = {
user.enable = true;
samba = {
enable = true;
#sync.enable = true;
accountFlags = {
noPasswordExpiry = mkDefault true;
normalUser = true;
};
};
object.settings.settings = {
sambaNTPassword = "F7C2C5D78C24EACB73550B02BF5888E3";
sambaLMPassword = "A5C96CDE7660B20BAAD3B435B51404EE";
};
};
};
groups = {
nogroup = {
group.enable = true;
samba.enable = true;
};
guest = {
samba = {
enable = true;
groupType = 4;
sid = "S-1-5-32-546";
};
};
admin = {
group.enable = true;
samba.enable = true;
};
kyuuto-peeps = {
group.enable = true;
samba.enable = true;
};
kyuuto = {
group.enable = true;
samba.enable = true;
};
peeps = {
group.enable = true;
samba.enable = true;
};
admins = {
samba = {
enable = true;
#sync.enable = true;
groupType = 4;
sid = "S-1-5-32-544";
};
};
smb = {
name = "Default SMB Group";
samba = {
#sync.enable = true;
groupType = 4;
sid = "S-1-5-32-545";
};
};
};
} ];
};
}

View file

@ -52,6 +52,8 @@ in {
./reisen-ssh.nix
];
users.ldap.management.enable = true;
sops.secrets.cloudflared-tunnel-hakurei = {
owner = config.services.cloudflared.user;
};

View file

@ -55,9 +55,11 @@
];
};
};
"modules/nixos/ldap".functor.enable = true;
"modules/nixos/network".functor.enable = true;
"modules/nixos/nginx".functor.enable = true;
"modules/nixos/steam".functor.enable = true;
"modules/nixos/users".functor.enable = true;
"modules/meta".functor.enable = true;
"modules/system".functor.enable = true;
"modules/system/proxmox".functor.enable = true;