From 409f341fbb5141af4500255af8dc498c9de42d1b Mon Sep 17 00:00:00 2001 From: niten Date: Mon, 18 Oct 2021 21:55:24 -0700 Subject: [PATCH] Daaamn NFS is a pain --- config/host-config/limina.nix | 2 +- config/host-config/nostromo.nix | 52 ++++++++++++++++++++------------ config/networks/sea.fudo.org.nix | 9 +++--- config/site-config/seattle.nix | 52 ++++++++++++++++++++++++++++++++ lib/fudo/host-filesystems.nix | 50 +++++++++++++++++++++--------- lib/fudo/users.nix | 39 +++++++++++++++++------- 6 files changed, 154 insertions(+), 50 deletions(-) diff --git a/config/host-config/limina.nix b/config/host-config/limina.nix index b343171..6190445 100644 --- a/config/host-config/limina.nix +++ b/config/host-config/limina.nix @@ -134,7 +134,7 @@ in { "L /root/.ssh/known_hosts - - - - /state/root/ssh/known_hosts" ]; - security.acme.certs."sea-camera.fudo.link".email = "niten@fudo.org"; + # security.acme.certs."sea-camera.fudo.link".email = "niten@fudo.org"; networking.firewall.allowedTCPPorts = [ 80 443 ]; diff --git a/config/host-config/nostromo.nix b/config/host-config/nostromo.nix index efc50a0..d28b642 100644 --- a/config/host-config/nostromo.nix +++ b/config/host-config/nostromo.nix @@ -19,23 +19,8 @@ in { }; }; - # fudo = { - # secrets."backplane-client-${hostname}-passwd" = { - # source-file = toPath "/srv/secrets/backplane-client/${hostname}.passwd"; - # target-file = "/srv/backplane/dns/client.passwd"; - # target-host = "${hostname}"; - # user = config.fudo.client.dns.user; - # }; - - # client.dns = { - # enable = true; - # ipv4 = false; - # ipv6 = true; - # user = "fudo-client"; - # external-interface = "extif0"; - # password-file = secrets."backplane-client-${hostname}-passwd".target-file; - # }; - # }; + # Hopefully this'll help with NFS... + boot.kernelModules = [ "rpcsec_gss_krb5" ]; fudo.hosts.nostromo.encrypted-filesystems.sea-store = { encrypted-device = "/dev/nostromo-store/locked"; @@ -43,15 +28,42 @@ in { filesystem-type = "btrfs"; options = [ "noatime" "nodiratime" "compress=zstd" "noexec" ]; mountpoints = { - "/export/downloads" = { - options = [ "subvol=@downloads" ]; - }; "/export/documents" = { options = [ "subvol=@documents" ]; + group = "sea-documents"; + users = [ "niten" ]; + }; + "/export/downloads" = { + options = [ "subvol=@downloads" ]; + group = "sea-downloads"; + users = [ "niten" ]; }; }; }; + services.nfs = { + # See lib/fudo/users.nix for the user@REALM -> user mapping + server = { + enable = true; + createMountPoints = false; + exports = let + exportList = [ + "/export/documents 10.0.0.0/24 (rw,sync,root_squash,no_subtree_check,fsid=10,sec=krb5p)" + "/export/downloads 10.0.0.0/24 (rw,sync,root_squash,no_subtree_check,fsid=11,sec=krb5i)" + ]; + in '' + ${concatStringsSep "\n" exportList} + ''; + }; + }; + + systemd.services.nfs-server = { + # Don't start in on boot + wantedBy = mkForce [ "sea-store.target" ]; + # Only start after filesystem mounts are available + after = [ "export-documents.mount" "export-downloads.mount" ]; + }; + fudo.ipfs = { enable = true; users = [ "niten" ]; diff --git a/config/networks/sea.fudo.org.nix b/config/networks/sea.fudo.org.nix index 9396412..632c7bd 100644 --- a/config/networks/sea.fudo.org.nix +++ b/config/networks/sea.fudo.org.nix @@ -2,17 +2,18 @@ let local-domain = "sea.fudo.org"; in { aliases = { deploy = "socrates"; + dns-hole = "limina"; gateway = "limina"; + hole = "limina"; + ipfs = "nostromo"; # kadmin = "nostromo"; # kdc = "nostromo"; - photo = "doraemon"; music = "doraemon"; panopticon = "lambda"; panopticon-od = "lambda"; - ipfs = "nostromo"; - hole = "limina"; + photo = "doraemon"; pihole = "limina"; - dns-hole = "limina"; + sea-store = "nostromo"; }; srv-records = { diff --git a/config/site-config/seattle.nix b/config/site-config/seattle.nix index bc795c8..e554fda 100644 --- a/config/site-config/seattle.nix +++ b/config/site-config/seattle.nix @@ -37,6 +37,58 @@ in { fsType = "nfs4"; options = [ "comment=systemd.automount" ]; }; + # "/net/documents" = { + # device = "sea-store.${local-domain}:/export/documents"; + # fsType = "nfs"; + # options = [ + # "nfsvers=4.2" + # "comment=systemd.automount" + # "sec=krb5p" + # # "noauto" ? + # ]; + # }; + # "/net/downloads" = { + # device = "sea-store.${local-domain}:/export/downloads"; + # fsType = "nfs"; + # options = [ + # "nfsvers=4.2" + # "comment=systemd.automount" + # "sec=krb5i" + # # "noauto" ? + # ]; + # }; + }; + + systemd.mounts = [ + { + what = "sea-store.sea.fudo.org:/export/documents"; + where = "/net/documents"; + type = "nfs4"; + options = "sec=krb5p"; + description = "sea-store documents on encrypted filesysem."; + } + { + what = "sea-store.sea.fudo.org:/export/downloads"; + where = "/net/downloads"; + type = "nfs4"; + options = "sec=krb5i"; + description = "sea-store downloads on encrypted filesysem."; + } + ]; + + krb5 = { + domain_realm = { + "fudo.org" = "FUDO.ORG"; + ".fudo.org" = "FUDO.ORG"; + "sea.fudo.org" = "FUDO.ORG"; + ".sea.fudo.org" = "FUDO.ORG"; + }; + realms = { + "FUDO.ORG" = { + admin_server = "france.fudo.org"; + kdc = [ "france.fudo.org" ]; + }; + }; }; services.printing = { diff --git a/lib/fudo/host-filesystems.nix b/lib/fudo/host-filesystems.nix index 4746bdd..6a2810d 100644 --- a/lib/fudo/host-filesystems.nix +++ b/lib/fudo/host-filesystems.nix @@ -32,7 +32,7 @@ in { # Ensure the mountpoints exist tmpfiles.rules = let mountpointToPath = mp: mpOpts: - "d '${mp}' - root ${optionalOrDefault mpOpts.group "-"} - -"; + "d '${mp}' 750 root ${optionalOrDefault mpOpts.group "-"} - -"; filesystemsToMountpointLists = mapAttrsToList (fs: fsOpts: fsOpts.mountpoints); mountpointListsToPaths = concatMap @@ -53,9 +53,10 @@ in { type = fs.opts.filesystem-type; where = mp; options = concatStringsSep "," (fs.opts.options ++ mp-opts.options); - wantedBy = [ "default.target" ]; description = "${fs.opts.filesystem-type} filesystem on ${fs.filesystem} mounted to ${mp}"; requires = [ "${fs.filesystem}-decrypt.service" ]; + partOf = [ "${fs.filesystem}.target" ]; + wantedBy = [ "${fs.filesystem}.target" ]; }) fs.opts.mountpoints) filesystems; @@ -65,33 +66,54 @@ in { services = mapAttrs' (filesystem-name: opts: nameValuePair "${filesystem-name}-decrypt" { - wantedBy = [ "default.target" ]; description = "Decrypt the ${filesystem-name} filesystem when the key is available at ${opts.key-path}"; path = with pkgs; [ cryptsetup ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = pkgs.writeShellScript "decrypt-${filesystem-name}.sh" '' - [ ! -d /dev/mapper/${filesystem-name} ] || cryptsetup open --type luks --key-file ${opts.key-path} ${opts.encrypted-device} ${filesystem-name} + [ -e /dev/mapper/${filesystem-name} ] || cryptsetup open --type luks --key-file ${opts.key-path} ${opts.encrypted-device} ${filesystem-name} + ''; + ExecStartPost = pkgs.writeShellScript "remove-${filesystem-name}-key.sh" '' + rm ${opts.key-path} ''; ExecStop = pkgs.writeShellScript "close-${filesystem-name}.sh" '' cryptsetup close /dev/mapper/${filesystem-name} ''; }; + restartIfChanged = true; }) host-filesystems; # Watch the path of the key, trigger decrypt when it's available - paths = mapAttrs' (filesystem-name: opts: - nameValuePair "${filesystem-name}-decrypt" - { - wantedBy = [ "default.target" ]; - description = "Watch for decryption key, then decrypt the target filesystem."; - pathConfig = { - PathExists = opts.key-path; - Service = "${filesystem-name}-decrypt.service"; - }; - }) host-filesystems; + paths = let + decryption-jobs = mapAttrs' (filesystem-name: opts: + nameValuePair "${filesystem-name}-decrypt" + { + wantedBy = [ "default.target" ]; + description = "Watch for decryption key, then decrypt the target filesystem."; + pathConfig = { + PathExists = opts.key-path; + Unit = "${filesystem-name}-decrypt.service"; + }; + }) host-filesystems; + + post-decryption-jobs = mapAttrs' (filesystem-name: opts: + nameValuePair "${filesystem-name}-mount" + { + wantedBy = [ "default.target" ]; + description = "Mount ${filesystem-name} filesystems once the decrypted device is available."; + pathConfig = { + PathExists = "/dev/mapper/${filesystem-name}"; + Unit = "${filesystem-name}.target"; + }; + }) host-filesystems; + in decryption-jobs // post-decryption-jobs; + + targets = mapAttrs (filesystem-name: opts: + { + description = "${filesystem-name} enabled and available."; + }) host-filesystems; }; }; } diff --git a/lib/fudo/users.nix b/lib/fudo/users.nix index a26be81..85c3d27 100644 --- a/lib/fudo/users.nix +++ b/lib/fudo/users.nix @@ -134,18 +134,35 @@ in { }; }; - home-manager.useGlobalPkgs = true; - # home-manager.useGlobalPkgs = { - # useGlobalPkgs = true; + services.nfs.idmapd.settings = let + local-domain = config.instance.local-domain; + local-admins = config.instance.local-admins; + local-users = config.instance.local-users; + local-realm = config.fudo.domains.${local-domain}.gssapi-realm; + in { + General = { + Verbosity = 10; + Domain = local-domain; + "Local-Realms" = local-realm; + }; + Translation = { + GSS-Methods = "static"; + }; + Static = let + generate-admin-entry = admin: userOpts: + nameValuePair "${admin}/root@${local-realm}" "root"; + generate-user-entry = user: userOpts: + nameValuePair "${user}@${local-realm}" user; - # users = let - # home-manager-users = - # filterAttrs (username: userOpts: userOpts.home-manager-generator != null) - # sys.local-users; - # in mapAttrs (username: userOpts: userOpts.home-manager-generator { - # enable-gui = host-cfg.enable-gui; - # }) home-manager-users; - # }; + admin-entries = + mapAttrs' generate-admin-entry (getAttrs local-admins local-users); + user-entries = + mapAttrs' generate-user-entry local-users; + in admin-entries // user-entries; + }; + + # TODO: This is NOT where this should be... + home-manager.useGlobalPkgs = true; # Group home directories have to exist, otherwise users can't log in systemd.services = let