diff --git a/modules/extern/misc/sssd.nix b/modules/extern/misc/sssd.nix index 1e3eae56..26f5d349 100644 --- a/modules/extern/misc/sssd.nix +++ b/modules/extern/misc/sssd.nix @@ -1,5 +1,6 @@ { ... }: { imports = [ ../../nixos/sssd/sssd.nix + ../../nixos/sssd/pam.nix ]; } diff --git a/modules/extern/nixos/krb5.nix b/modules/extern/nixos/krb5.nix index 93a76474..e21ee898 100644 --- a/modules/extern/nixos/krb5.nix +++ b/modules/extern/nixos/krb5.nix @@ -7,10 +7,10 @@ ... }: let inherit (gensokyo-zone.lib) mkAlmostOptionDefault mapOptionDefaults mapAlmostOptionDefaults; - inherit (lib.options) mkOption mkEnableOption; - inherit (lib.modules) mkIf mkMerge mkBefore mkAfter mkDefault mkOptionDefault; - inherit (lib.lists) optional; - inherit (lib.strings) toUpper; + inherit (lib.options) mkOption mkEnableOption mkPackageOption; + inherit (lib.modules) mkIf mkMerge mkBefore mkAfter mkForce mkDefault mkOptionDefault; + inherit (lib.lists) optional elem; + inherit (lib.strings) toUpper concatStringsSep; inherit (gensokyo-zone.lib) unmerged; cfg = config.gensokyo-zone.krb5; krb5Module = { @@ -127,6 +127,25 @@ }; nfs = { enable = mkEnableOption "nfs"; + package = mkPackageOption pkgs "nfs-utils" { }; + idmapd = { + localDomain = mkOption { + type = bool; + default = enabled.sssd && nixosConfig.services.sssd.services.nss.enable; + }; + localRealms = mkOption { + type = listOf str; + default = [ config.realm ]; + }; + methods = mkOption { + type = listOf str; + default = [ "nsswitch" ]; + }; + authToLocalNames = mkOption { + type = attrsOf str; + default = config.authToLocalNames; + }; + }; debug.enable = mkEnableOption "nfs debug logs"; }; ipa = { @@ -188,6 +207,19 @@ }; }; db.backend = mkIf enabled.ipa (mkAlmostOptionDefault "ipa"); + nfs = { + package = mkIf (elem "umich_ldap" config.nfs.idmapd.methods) (mkAlmostOptionDefault pkgs.nfs-utils-ldap); + idmapd = { + methods = mkMerge [ + (mkIf (config.nfs.idmapd.authToLocalNames != { }) ( + mkOptionDefault (mkBefore [ "static" ]) + )) + (mkIf (!enabled.sssd) ( + mkOptionDefault [ "umich_ldap" ] + )) + ]; + }; + }; set = { krb5Settings = { enable = mkAlmostOptionDefault true; @@ -252,9 +284,10 @@ realm = config.realm; server = config.ipa.server; # TODO: dyndns? - overrideConfigs = { - sssd = mkAlmostOptionDefault false; - krb5 = mkAlmostOptionDefault false; + } // { + overrideConfigs = mapAlmostOptionDefaults { + sssd = false; + krb5 = false; }; }); nfsSettings = mkIf config.nfs.enable { @@ -305,10 +338,32 @@ rpc-verbosity = 3 '') ]; - idmapd.settings = mkIf false { - #General.Domain = mkForce config.domain; - #Local-Realms = concatStringsSep "," [ config.realm nixosConfig.networking.domain ]; - #Translation.Method = mkForce (concatStringsSep "," [ "static" "nsswitch" ]); + # TODO: move this into a more generic /modules/nixos/nfs that gets configured... + idmapd.settings = { + General = mkIf config.nfs.idmapd.localDomain { + Domain = mkForce config.domain; + Local-Realms = concatStringsSep "," config.nfs.idmapd.localRealms; + }; + Translation.Method = mkIf (config.nfs.idmapd.methods != [ "nsswitch" ]) (mkForce ( + concatStringsSep "," config.nfs.idmapd.methods + )); + Static = mkIf (config.nfs.idmapd.authToLocalNames != { }) config.nfs.idmapd.authToLocalNames; + UMICH_SCHEMA = mkIf (elem "umich_ldap" config.nfs.idmapd.methods) (mapOptionDefaults { + LDAP_server = config.ldap.host; + LDAP_use_ssl = true; + LDAP_ca_cert = "/etc/ssl/certs/ca-bundle.crt"; + LDAP_base = config.ldap.baseDn; + LDAP_people_base = "cn=users,cn=accounts,${config.ldap.baseDn}"; + LDAP_group_base = "cn=groups,cn=accounts,${config.ldap.baseDn}"; + NFSv4_person_objectclass = "posixaccount"; # or "person"? + NFSv4_name_attr = "krbCanonicalName"; # uid? cn? gecos? + GSS_principal_attr = "krbPrincipalName"; + NFSv4_group_objectclass = "posixgroup"; + NFSv4_group_attr = "cn"; + #LDAP_use_memberof_for_groups = true; + #NFSv4_member_attr = "member"; + LDAP_canonicalize_name = false; + }); }; }; }; @@ -363,6 +418,18 @@ in { ${freeipa.config.access.address4ForNetwork.local} = mkBefore [ cfg.host ]; }; }; + environment.etc = { + "request-key.conf" = mkIf (cfg.enable && cfg.nfs.enable && cfg.sssd.enable) { + source = let + nfsidmap = pkgs.writeShellScript "nfsidmap" '' + export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${config.system.nssModules.path}" + exec ${cfg.nfs.package}/bin/nfsidmap "$@" + ''; + in mkForce (pkgs.writeText "request-key.conf" '' + create id_resolver * * ${nfsidmap} -t 600 %k %d + ''); + }; + }; ${if options ? sops.secrets then "sops" else null}.secrets = let sopsFile = mkDefault ../secrets/krb5.yaml; in mkIf cfg.enable { diff --git a/modules/extern/nixos/kyuuto.nix b/modules/extern/nixos/kyuuto.nix index beb29487..194d866b 100644 --- a/modules/extern/nixos/kyuuto.nix +++ b/modules/extern/nixos/kyuuto.nix @@ -8,6 +8,7 @@ inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault; inherit (gensokyo-zone.lib) unmerged; cfg = config.gensokyo-zone.kyuuto; + nfsEnabled = config.boot.supportedFilesystems.nfs or config.boot.supportedFilesystems.nfs4 or false; kyuutoModule = { gensokyo-zone, nixosConfig, @@ -112,7 +113,7 @@ setFilesystems = { "/mnt/kyuuto-media" = mkIf config.media.enable { device = mkMerge [ - (mkIf config.nfs.enable "nfs.${config.domain}:/mnt/kyuuto-media") + (mkIf config.nfs.enable "nfs.${config.domain}:/srv/fs/kyuuto/media") (mkIf config.smb.enable ( if config.smb.user != null && access.local.enable then ''\\smb.${config.domain}\kyuuto-media'' @@ -134,7 +135,7 @@ }; "/mnt/kyuuto-transfer" = mkIf config.transfer.enable { device = mkMerge [ - (mkIf config.nfs.enable "nfs.${config.domain}:/mnt/kyuuto-media/transfer") + (mkIf config.nfs.enable "nfs.${config.domain}:/srv/fs/kyuuto/transfer") (mkIf (config.smb.enable && access.local.enable) ''\\smb.${config.domain}\kyuuto-transfer'') ]; fsType = mkMerge [ @@ -177,6 +178,10 @@ in { fileSystems = mkIf cfg.enable ( unmerged.mergeAttrs cfg.setFilesystems ); + systemd.services.rpc-svcgssd = mkIf (!config.services.nfs.server.enable && nfsEnabled) { + enable = false; + }; + lib.gensokyo-zone.kyuuto = { inherit cfg kyuutoModule; }; diff --git a/modules/nixos/ipa.nix b/modules/nixos/ipa.nix index 04d582af..cb8206cc 100644 --- a/modules/nixos/ipa.nix +++ b/modules/nixos/ipa.nix @@ -98,6 +98,7 @@ in { config = mkIf (sssd.configText != null) (mkAlmostForce sssd.configText); }; config.security.krb5 = mkIf cfg.enable { + enable = mkAlmostForce false; package = mkAlmostOptionDefault pkgs.krb5Full; settings = { libdefaults = mapOptionDefaults { diff --git a/modules/nixos/sssd/pam.nix b/modules/nixos/sssd/pam.nix new file mode 100644 index 00000000..94d77fa0 --- /dev/null +++ b/modules/nixos/sssd/pam.nix @@ -0,0 +1,35 @@ +{ + config, + lib, + gensokyo-zone, + ... +}: let + inherit (gensokyo-zone.lib) mkAlmostForce; + inherit (lib.options) mkOption; + inherit (lib.modules) mkIf; + inherit (lib.attrsets) genAttrs; + cfg = config.services.sssd; + pamRulesModule = { ... }: let + rules = [ "account" "auth" "password" "session" ]; + mkRuleConfig = ruleName: { + sss = mkIf cfg.enable { + enable = mkIf (!cfg.services.pam.enable) (mkAlmostForce false); + }; + }; + in { + config = genAttrs rules mkRuleConfig; + }; + pamServiceModule = { ... }: { + options = with lib.types; { + rules = mkOption { + type = submodule pamRulesModule; + }; + }; + }; +in { + options.security.pam = with lib.types; { + services = mkOption { + type = attrsOf (submodule pamServiceModule); + }; + }; +} diff --git a/nixos/nfs.nix b/nixos/nfs.nix index aa7fb5e5..f5228f0a 100644 --- a/nixos/nfs.nix +++ b/nixos/nfs.nix @@ -1,21 +1,51 @@ { - inputs, + gensokyo-zone, config, lib, ... }: let - inherit (inputs.self.lib.lib) mkBaseDn; - inherit (lib.modules) mkIf mkForce mkDefault; + inherit (gensokyo-zone.lib) mkBaseDn mapOptionDefaults; + inherit (lib.modules) mkIf mkMerge mkForce mkDefault mkOptionDefault; inherit (lib.lists) optional optionals; inherit (lib.strings) toUpper concatStringsSep; inherit (config.networking.access) cidrForNetwork; cfg = config.services.nfs; inherit (cfg.export) flagSets; inherit (config.networking) domain; + inherit (config.users) ldap; enableLdap = false; baseDn = mkBaseDn domain; + realm = toUpper domain; + debugLogging = true; in { config.services.nfs = { + settings = mkMerge [ + (mkIf debugLogging { + mountd.debug = mkOptionDefault "all"; + exportfs.debug = mkOptionDefault "all"; + exportd.debug = mkOptionDefault "all"; + gssd = mapOptionDefaults { + verbosity = 2; + rpc-verbosity = 2; + }; + svcgssd = mapOptionDefaults { + verbosity = 2; + rpc-verbosity = 2; + idmap-verbosity = 2; + }; + }) + { + mountd.reverse-lookup = mkOptionDefault false; + gssd = { + preferred-realm = mkOptionDefault realm; + }; + /*svcgssd = { + #principal = system + #principal = nfs/idp.${domain}@${realm} + #principal = nfs/${config.networking.fqdn}@${realm} + };*/ + } + ]; server = { enable = mkDefault true; statdPort = mkDefault 4000; @@ -72,7 +102,7 @@ in { General = { Domain = mkForce domain; Local-Realms = concatStringsSep "," [ - (toUpper domain) + realm #(toString config.networking.fqdn) ]; }; @@ -88,8 +118,8 @@ in { LDAP_use_ssl = true; LDAP_ca_cert = "/etc/ssl/certs/ca-bundle.crt"; LDAP_base = baseDn; - LDAP_people_base = "cn=users,cn=accounts,${baseDn}"; - LDAP_group_base = "cn=groups,cn=accounts,${baseDn}"; + LDAP_people_base = "${ldap.userDnSuffix}${baseDn}"; + LDAP_group_base = "${ldap.groupDnSuffix}${baseDn}"; GSS_principal_attr = "krbPrincipalName"; NFSv4_person_objectclass = "posixaccount"; # or "person"? NFSv4_group_objectclass = "posixgroup";