mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 12:29:19 -08:00
fix(nfs): sec=krb5
This commit is contained in:
parent
7cbdb4c231
commit
88477df521
6 changed files with 336 additions and 64 deletions
89
modules/nixos/network/netgroups.nix
Normal file
89
modules/nixos/network/netgroups.nix
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.options) mkOption;
|
||||||
|
inherit (lib.modules) mkIf mkMerge mkBefore mkAfter mkOptionDefault;
|
||||||
|
inherit (lib.attrsets) mapAttrsToList;
|
||||||
|
inherit (lib.strings) concatStringsSep;
|
||||||
|
inherit (config.system) nssDatabases;
|
||||||
|
inherit (config) networking;
|
||||||
|
netgroupMemberModule = { config, name, ... }: {
|
||||||
|
options = with lib.types; {
|
||||||
|
hostname = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = name;
|
||||||
|
};
|
||||||
|
user = mkOption {
|
||||||
|
type = either (enum [ null "-" ]) str;
|
||||||
|
default = "-";
|
||||||
|
};
|
||||||
|
domain = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = networking.domain;
|
||||||
|
description = "NIS domain";
|
||||||
|
};
|
||||||
|
triple = mkOption {
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
triple = mkOptionDefault "(${config.hostname},${toString config.user},${config.domain})";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
netgroupModule = { config, name, ... }: {
|
||||||
|
options = with lib.types; {
|
||||||
|
name = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = name;
|
||||||
|
};
|
||||||
|
members = mkOption {
|
||||||
|
type = attrsOf (submodule netgroupMemberModule);
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
fileLine = mkOption {
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
fileLine = mkOptionDefault (concatStringsSep " " ([ config.name ] ++ mapAttrsToList (_: member: member.triple) config.members));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options = with lib.types; {
|
||||||
|
system.nssDatabases = {
|
||||||
|
netgroup = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
networking = {
|
||||||
|
netgroups = mkOption {
|
||||||
|
type = attrsOf (submodule netgroupModule);
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
extraNetgroups = mkOption {
|
||||||
|
type = lines;
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
system.nssDatabases = {
|
||||||
|
netgroup = mkMerge [
|
||||||
|
(mkBefore [ "files" ])
|
||||||
|
(mkAfter [ "nis" ])
|
||||||
|
(mkIf config.services.sssd.enable [ "sss" ])
|
||||||
|
];
|
||||||
|
};
|
||||||
|
environment.etc."nssswitch.conf".text = mkIf (nssDatabases.netgroup != [ ]) (mkAfter ''
|
||||||
|
netgroup: ${concatStringsSep " " nssDatabases.netgroup}
|
||||||
|
'');
|
||||||
|
environment.etc."netgroup" = mkIf (networking.netgroups != { } || networking.extraNetgroups != "") {
|
||||||
|
text = mkMerge (
|
||||||
|
mapAttrsToList (_: ng: ng.fileLine) networking.netgroups
|
||||||
|
++ [ networking.extraNetgroups ]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
139
modules/nixos/nfs.nix
Normal file
139
modules/nixos/nfs.nix
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.options) mkOption;
|
||||||
|
inherit (lib.modules) mkMerge mkIf mkBefore mkForce mkOptionDefault;
|
||||||
|
inherit (lib.lists) optional;
|
||||||
|
inherit (lib.attrsets) mapAttrsToList;
|
||||||
|
inherit (lib.lists) toList;
|
||||||
|
inherit (lib.strings) optionalString concatStringsSep concatMapStringsSep;
|
||||||
|
cfg = config.services.nfs;
|
||||||
|
clientEnabled = config.boot.supportedFilesystems.nfs or config.boot.supportedFilesystems.nfs4 or false;
|
||||||
|
enabled = cfg.server.enable || clientEnabled;
|
||||||
|
openPorts = [
|
||||||
|
(mkIf cfg.server.enable 2049)
|
||||||
|
(mkIf config.services.rpcbind.enable 111)
|
||||||
|
(mkIf (cfg.server.statdPort != null) cfg.server.statdPort)
|
||||||
|
(mkIf (cfg.server.lockdPort != null) cfg.server.lockdPort)
|
||||||
|
(mkIf (cfg.server.mountdPort != null) cfg.server.mountdPort)
|
||||||
|
];
|
||||||
|
concatFlags = concatStringsSep ",";
|
||||||
|
clientModule = { config, name, ... }: {
|
||||||
|
options = with lib.types; {
|
||||||
|
machine = mkOption {
|
||||||
|
type = oneOf [ str (listOf str) ];
|
||||||
|
default = name;
|
||||||
|
example = "*";
|
||||||
|
};
|
||||||
|
flags = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
entry = mkOption {
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
entry = let
|
||||||
|
flags = optionalString (config.flags != [ ]) "(${concatFlags config.flags})";
|
||||||
|
machines = toList config.machine;
|
||||||
|
in mkOptionDefault (concatMapStringsSep " " (machine: machine + flags) machines);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
exportModule = { config, name, ... }: {
|
||||||
|
options = with lib.types; {
|
||||||
|
path = mkOption {
|
||||||
|
type = path;
|
||||||
|
default = name;
|
||||||
|
};
|
||||||
|
flags = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
};
|
||||||
|
clients = mkOption {
|
||||||
|
type = attrsOf (submodule clientModule);
|
||||||
|
};
|
||||||
|
fileLine = mkOption {
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
flags = mkOptionDefault (cfg.export.flagSets.common or [ ]);
|
||||||
|
fileLine = let
|
||||||
|
parts = [ config.path ]
|
||||||
|
++ optional (config.flags != [ ]) "-${concatFlags config.flags}"
|
||||||
|
++ mapAttrsToList (_: client: client.entry) config.clients;
|
||||||
|
in mkOptionDefault (concatStringsSep " " parts);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options.services.nfs = with lib.types; {
|
||||||
|
export = {
|
||||||
|
flagSets = mkOption {
|
||||||
|
type = lazyAttrsOf (listOf str);
|
||||||
|
default = {
|
||||||
|
common = [ "no_subtree_check" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
root = mkOption {
|
||||||
|
type = nullOr (submodule [
|
||||||
|
exportModule
|
||||||
|
({ ... }: {
|
||||||
|
flags = mkMerge [
|
||||||
|
(cfg.export.flagSets.common or [ ])
|
||||||
|
];
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
paths = mkOption {
|
||||||
|
type = attrsOf (submodule exportModule);
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
services.nfs = {
|
||||||
|
server.exports = mkMerge (
|
||||||
|
optional (cfg.export.root != null) (mkBefore cfg.export.root.fileLine)
|
||||||
|
++ mapAttrsToList (_: export: export.fileLine) cfg.export.paths
|
||||||
|
);
|
||||||
|
};
|
||||||
|
networking.firewall.interfaces.local = mkIf enabled {
|
||||||
|
allowedTCPPorts = openPorts;
|
||||||
|
allowedUDPPorts = openPorts;
|
||||||
|
};
|
||||||
|
systemd.services = {
|
||||||
|
auth-rpcgss-module = mkIf (enabled && !config.boot.modprobeConfig.enable) {
|
||||||
|
serviceConfig.ExecStart = mkForce [
|
||||||
|
""
|
||||||
|
"${pkgs.coreutils}/bin/true"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
rpc-svcgssd = mkIf enabled {
|
||||||
|
enable = mkIf (!cfg.server.enable) false;
|
||||||
|
wantedBy = mkIf (cfg.server.enable && (config.security.krb5.enable || config.security.ipa.enable)) [
|
||||||
|
"nfs-server.service"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
nfs-mountd = mkIf cfg.server.enable {
|
||||||
|
environment.LD_LIBRARY_PATH = config.system.nssModules.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.mounts = mkIf (cfg.server.enable && cfg.export.root != null) [
|
||||||
|
rec {
|
||||||
|
type = "tmpfs";
|
||||||
|
options = "rw,size=256k";
|
||||||
|
what = "none";
|
||||||
|
where = cfg.export.root.path;
|
||||||
|
requiredBy = [
|
||||||
|
"nfs-server.service"
|
||||||
|
"nfs-mountd.service"
|
||||||
|
];
|
||||||
|
before = requiredBy;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -195,8 +195,7 @@ in {
|
||||||
|
|
||||||
map $ssl_preread_server_name $ldap_upstream {
|
map $ssl_preread_server_name $ldap_upstream {
|
||||||
hostnames;
|
hostnames;
|
||||||
# TODO: ${access.domain} ${upstreams.ldap_freeipa};
|
${access.domain} ${upstreams.ldap_freeipa};
|
||||||
${access.globalDomain} ${upstreams.ldap_freeipa};
|
|
||||||
default ${upstreams.ldap};
|
default ${upstreams.ldap};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{ inputs, pkgs, config, lib, ... }: let
|
{ inputs, pkgs, config, lib, ... }: let
|
||||||
inherit (inputs.self.lib.lib) mkBaseDn;
|
inherit (inputs.self.lib.lib) mkBaseDn;
|
||||||
inherit (lib.modules) mkIf mkForce mkDefault;
|
inherit (lib.modules) mkIf mkBefore mkForce mkDefault;
|
||||||
inherit (lib.strings) toUpper splitString concatMapStringsSep;
|
inherit (lib.strings) toUpper;
|
||||||
inherit (config.networking) domain;
|
inherit (config.networking) domain;
|
||||||
cfg = config.security.ipa;
|
cfg = config.security.ipa;
|
||||||
baseDn = mkBaseDn domain;
|
baseDn = mkBaseDn domain;
|
||||||
|
|
@ -32,14 +32,8 @@ in {
|
||||||
] ++ config.users.groups.wheel.members;
|
] ++ config.users.groups.wheel.members;
|
||||||
dyndns.enable = mkDefault false;
|
dyndns.enable = mkDefault false;
|
||||||
};
|
};
|
||||||
networking.extraHosts = mkIf cfg.enable ''
|
networking.hosts = mkIf cfg.enable {
|
||||||
10.1.1.46 idp.${domain}
|
"10.1.1.46" = mkBefore [ "idp.${domain}" ];
|
||||||
'';
|
|
||||||
systemd.services.auth-rpcgss-module = mkIf (cfg.enable && !config.boot.modprobeConfig.enable) {
|
|
||||||
serviceConfig.ExecStart = mkForce [
|
|
||||||
""
|
|
||||||
"${pkgs.coreutils}/bin/true"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
sops.secrets = {
|
sops.secrets = {
|
||||||
krb5-keytab = mkIf cfg.enable {
|
krb5-keytab = mkIf cfg.enable {
|
||||||
|
|
|
||||||
|
|
@ -3,48 +3,60 @@
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
|
inherit (lib.modules) mkIf;
|
||||||
inherit (lib.lists) optionals;
|
inherit (lib.lists) optionals;
|
||||||
inherit (lib.strings) concatStringsSep;
|
inherit (lib.strings) concatStringsSep;
|
||||||
inherit (config.networking.access) cidrForNetwork;
|
inherit (config.networking.access) cidrForNetwork;
|
||||||
inherit (config) kyuuto;
|
inherit (config) kyuuto;
|
||||||
|
inherit (config.services.nfs.export) flagSets;
|
||||||
|
nfsRoot = {
|
||||||
|
__toString = _: config.services.nfs.export.root.path;
|
||||||
|
transfer = "${nfsRoot}/kyuuto/transfer";
|
||||||
|
media = "${nfsRoot}/kyuuto/media";
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
services.nfs.server.exports = let
|
services.nfs = {
|
||||||
mapPerm = perm: map (addr: "${addr}(${concatStringsSep "," perm})");
|
export = {
|
||||||
toPerms = concatStringsSep " ";
|
paths = {
|
||||||
localAddrs = cidrForNetwork.loopback.all ++ cidrForNetwork.local.all;
|
${nfsRoot.media} = {
|
||||||
tailAddrs = optionals config.services.tailscale.enable cidrForNetwork.tail.all;
|
flags = flagSets.common ++ [ "fsid=128" ] ++ flagSets.secip ++ [ "rw" ] ++ flagSets.anon_ro;
|
||||||
allAddrs = localAddrs ++ tailAddrs;
|
clients = {
|
||||||
globalAddrs = [
|
local = {
|
||||||
"@peeps"
|
machine = flagSets.allClients;
|
||||||
|
flags = flagSets.seclocal ++ [ "rw" "no_all_squash" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
${nfsRoot.transfer} = {
|
||||||
|
flags = flagSets.common ++ [ "fsid=129" ] ++ [ "rw" "async" ];
|
||||||
|
clients = {
|
||||||
|
local = {
|
||||||
|
machine = flagSets.allClients;
|
||||||
|
flags = flagSets.secanon;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.mounts = let
|
||||||
|
type = "none";
|
||||||
|
options = "bind";
|
||||||
|
wantedBy = [
|
||||||
|
"nfs-server.service"
|
||||||
|
"nfs-mountd.service"
|
||||||
];
|
];
|
||||||
common = [
|
before = wantedBy;
|
||||||
"no_subtree_check"
|
in mkIf config.services.nfs.server.enable [
|
||||||
];
|
{
|
||||||
sec = [
|
inherit type options wantedBy before;
|
||||||
"sec=${concatStringsSep ":" [ "krb5i" "krb5" "krb5p" ]}"
|
what = kyuuto.mountDir;
|
||||||
# TODO: no_root_squash..?
|
where = nfsRoot.media;
|
||||||
];
|
}
|
||||||
anon = [
|
{
|
||||||
"sec=sys"
|
inherit type options wantedBy before;
|
||||||
"all_squash"
|
what = kyuuto.transferDir;
|
||||||
"anonuid=${toString config.users.users.guest.uid}"
|
where = nfsRoot.transfer;
|
||||||
"anongid=${toString config.users.groups.${config.users.users.guest.group}.gid}"
|
}
|
||||||
];
|
];
|
||||||
# TODO: this can be simplified by specifying `sec=` multiple times, with restrictive options following sec=sys,all_squash,ro,etc
|
|
||||||
kyuutoOpts = common;
|
|
||||||
kyuutoPerms =
|
|
||||||
mapPerm (kyuutoOpts ++ [ "rw" ] ++ sec) globalAddrs
|
|
||||||
++ mapPerm (kyuutoOpts ++ [ "ro" ] ++ anon) localAddrs
|
|
||||||
# XXX: remove me once kerberos is set up!
|
|
||||||
++ mapPerm (kyuutoOpts ++ [ "rw" "sec=sys" ]) tailAddrs
|
|
||||||
;
|
|
||||||
transferOpts = common ++ [ "rw" "async" ];
|
|
||||||
transferPerms =
|
|
||||||
mapPerm (transferOpts ++ sec) globalAddrs
|
|
||||||
++ mapPerm (transferOpts ++ anon) allAddrs
|
|
||||||
;
|
|
||||||
in ''
|
|
||||||
${kyuuto.mountDir} ${toPerms kyuutoPerms}
|
|
||||||
${kyuuto.transferDir} ${toPerms transferPerms}
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,27 +6,70 @@
|
||||||
}: let
|
}: let
|
||||||
inherit (inputs.self.lib.lib) mkBaseDn;
|
inherit (inputs.self.lib.lib) mkBaseDn;
|
||||||
inherit (lib.modules) mkIf mkForce mkDefault;
|
inherit (lib.modules) mkIf mkForce mkDefault;
|
||||||
inherit (lib.lists) optional;
|
inherit (lib.lists) optional optionals;
|
||||||
inherit (lib.strings) toUpper concatStringsSep concatMapStringsSep splitString;
|
inherit (lib.strings) toUpper concatStringsSep;
|
||||||
|
inherit (config.networking.access) cidrForNetwork;
|
||||||
cfg = config.services.nfs;
|
cfg = config.services.nfs;
|
||||||
|
inherit (cfg.export) flagSets;
|
||||||
inherit (config.networking) domain;
|
inherit (config.networking) domain;
|
||||||
openPorts = [
|
|
||||||
(mkIf cfg.server.enable 2049)
|
|
||||||
(mkIf config.services.rpcbind.enable 111)
|
|
||||||
(mkIf (cfg.server.statdPort != null) cfg.server.statdPort)
|
|
||||||
(mkIf (cfg.server.lockdPort != null) cfg.server.lockdPort)
|
|
||||||
(mkIf (cfg.server.mountdPort != null) cfg.server.mountdPort)
|
|
||||||
];
|
|
||||||
enableLdap = false;
|
enableLdap = false;
|
||||||
baseDn = mkBaseDn domain;
|
baseDn = mkBaseDn domain;
|
||||||
in {
|
in {
|
||||||
services.nfs = {
|
config.services.nfs = {
|
||||||
server = {
|
server = {
|
||||||
enable = mkDefault true;
|
enable = mkDefault true;
|
||||||
statdPort = mkDefault 4000;
|
statdPort = mkDefault 4000;
|
||||||
lockdPort = mkDefault 4001;
|
lockdPort = mkDefault 4001;
|
||||||
mountdPort = mkDefault 4002;
|
mountdPort = mkDefault 4002;
|
||||||
};
|
};
|
||||||
|
export = {
|
||||||
|
flagSets = let
|
||||||
|
localAddrs = cidrForNetwork.loopback.all ++ cidrForNetwork.local.all;
|
||||||
|
in {
|
||||||
|
common = [
|
||||||
|
"no_subtree_check"
|
||||||
|
"anonuid=${toString config.users.users.guest.uid}"
|
||||||
|
"anongid=${toString config.users.groups.${config.users.users.guest.group}.gid}"
|
||||||
|
];
|
||||||
|
sec = [
|
||||||
|
"sec=${concatStringsSep ":" [ "krb5i" "krb5" "krb5p" ]}"
|
||||||
|
];
|
||||||
|
seclocal = [
|
||||||
|
"sec=${concatStringsSep ":" [ "krb5" ]}"
|
||||||
|
];
|
||||||
|
secip = [
|
||||||
|
"sec=${concatStringsSep ":" [ "krb5i" "krb5p" ]}"
|
||||||
|
];
|
||||||
|
secanon = [
|
||||||
|
"sec=${concatStringsSep ":" [ "krb5i" "krb5" "krb5p" "sys" ]}"
|
||||||
|
];
|
||||||
|
anon_ro = [
|
||||||
|
"sec=sys"
|
||||||
|
"all_squash"
|
||||||
|
"ro"
|
||||||
|
];
|
||||||
|
# client machines
|
||||||
|
clientGroups = [
|
||||||
|
"@peeps"
|
||||||
|
"@infra"
|
||||||
|
];
|
||||||
|
trustedClients = [
|
||||||
|
"@trusted"
|
||||||
|
];
|
||||||
|
tailClients = optionals config.services.tailscale.enable cidrForNetwork.tail.all;
|
||||||
|
localClients = localAddrs ++ flagSets.tailClients;
|
||||||
|
allClients = flagSets.clientGroups ++ flagSets.trustedClients ++ flagSets.localClients;
|
||||||
|
};
|
||||||
|
root = {
|
||||||
|
path = "/srv/fs";
|
||||||
|
clients = {
|
||||||
|
trusted = {
|
||||||
|
machine = flagSets.trustedClients;
|
||||||
|
flags = flagSets.secip ++ [ "rw" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
idmapd.settings = {
|
idmapd.settings = {
|
||||||
General = {
|
General = {
|
||||||
Domain = mkForce domain;
|
Domain = mkForce domain;
|
||||||
|
|
@ -61,8 +104,4 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
networking.firewall.interfaces.local = {
|
|
||||||
allowedTCPPorts = openPorts;
|
|
||||||
allowedUDPPorts = openPorts;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue