Daaamn NFS is a pain

This commit is contained in:
niten 2021-10-18 21:55:24 -07:00
parent 0a460f3374
commit 409f341fbb
6 changed files with 154 additions and 50 deletions

View File

@ -134,7 +134,7 @@ in {
"L /root/.ssh/known_hosts - - - - /state/root/ssh/known_hosts" "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 ]; networking.firewall.allowedTCPPorts = [ 80 443 ];

View File

@ -19,23 +19,8 @@ in {
}; };
}; };
# fudo = { # Hopefully this'll help with NFS...
# secrets."backplane-client-${hostname}-passwd" = { boot.kernelModules = [ "rpcsec_gss_krb5" ];
# 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;
# };
# };
fudo.hosts.nostromo.encrypted-filesystems.sea-store = { fudo.hosts.nostromo.encrypted-filesystems.sea-store = {
encrypted-device = "/dev/nostromo-store/locked"; encrypted-device = "/dev/nostromo-store/locked";
@ -43,15 +28,42 @@ in {
filesystem-type = "btrfs"; filesystem-type = "btrfs";
options = [ "noatime" "nodiratime" "compress=zstd" "noexec" ]; options = [ "noatime" "nodiratime" "compress=zstd" "noexec" ];
mountpoints = { mountpoints = {
"/export/downloads" = {
options = [ "subvol=@downloads" ];
};
"/export/documents" = { "/export/documents" = {
options = [ "subvol=@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 = { fudo.ipfs = {
enable = true; enable = true;
users = [ "niten" ]; users = [ "niten" ];

View File

@ -2,17 +2,18 @@ let local-domain = "sea.fudo.org";
in { in {
aliases = { aliases = {
deploy = "socrates"; deploy = "socrates";
dns-hole = "limina";
gateway = "limina"; gateway = "limina";
hole = "limina";
ipfs = "nostromo";
# kadmin = "nostromo"; # kadmin = "nostromo";
# kdc = "nostromo"; # kdc = "nostromo";
photo = "doraemon";
music = "doraemon"; music = "doraemon";
panopticon = "lambda"; panopticon = "lambda";
panopticon-od = "lambda"; panopticon-od = "lambda";
ipfs = "nostromo"; photo = "doraemon";
hole = "limina";
pihole = "limina"; pihole = "limina";
dns-hole = "limina"; sea-store = "nostromo";
}; };
srv-records = { srv-records = {

View File

@ -37,6 +37,58 @@ in {
fsType = "nfs4"; fsType = "nfs4";
options = [ "comment=systemd.automount" ]; 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 = { services.printing = {

View File

@ -32,7 +32,7 @@ in {
# Ensure the mountpoints exist # Ensure the mountpoints exist
tmpfiles.rules = let tmpfiles.rules = let
mountpointToPath = mp: mpOpts: mountpointToPath = mp: mpOpts:
"d '${mp}' - root ${optionalOrDefault mpOpts.group "-"} - -"; "d '${mp}' 750 root ${optionalOrDefault mpOpts.group "-"} - -";
filesystemsToMountpointLists = mapAttrsToList filesystemsToMountpointLists = mapAttrsToList
(fs: fsOpts: fsOpts.mountpoints); (fs: fsOpts: fsOpts.mountpoints);
mountpointListsToPaths = concatMap mountpointListsToPaths = concatMap
@ -53,9 +53,10 @@ in {
type = fs.opts.filesystem-type; type = fs.opts.filesystem-type;
where = mp; where = mp;
options = concatStringsSep "," (fs.opts.options ++ mp-opts.options); options = concatStringsSep "," (fs.opts.options ++ mp-opts.options);
wantedBy = [ "default.target" ];
description = "${fs.opts.filesystem-type} filesystem on ${fs.filesystem} mounted to ${mp}"; description = "${fs.opts.filesystem-type} filesystem on ${fs.filesystem} mounted to ${mp}";
requires = [ "${fs.filesystem}-decrypt.service" ]; requires = [ "${fs.filesystem}-decrypt.service" ];
partOf = [ "${fs.filesystem}.target" ];
wantedBy = [ "${fs.filesystem}.target" ];
}) })
fs.opts.mountpoints) fs.opts.mountpoints)
filesystems; filesystems;
@ -65,33 +66,54 @@ in {
services = mapAttrs' (filesystem-name: opts: services = mapAttrs' (filesystem-name: opts:
nameValuePair "${filesystem-name}-decrypt" nameValuePair "${filesystem-name}-decrypt"
{ {
wantedBy = [ "default.target" ];
description = "Decrypt the ${filesystem-name} filesystem when the key is available at ${opts.key-path}"; description = "Decrypt the ${filesystem-name} filesystem when the key is available at ${opts.key-path}";
path = with pkgs; [ cryptsetup ]; path = with pkgs; [ cryptsetup ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = true; RemainAfterExit = true;
ExecStart = pkgs.writeShellScript "decrypt-${filesystem-name}.sh" '' 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" '' ExecStop = pkgs.writeShellScript "close-${filesystem-name}.sh" ''
cryptsetup close /dev/mapper/${filesystem-name} cryptsetup close /dev/mapper/${filesystem-name}
''; '';
}; };
restartIfChanged = true;
}) })
host-filesystems; host-filesystems;
# Watch the path of the key, trigger decrypt when it's available # Watch the path of the key, trigger decrypt when it's available
paths = mapAttrs' (filesystem-name: opts: paths = let
nameValuePair "${filesystem-name}-decrypt" decryption-jobs = mapAttrs' (filesystem-name: opts:
{ nameValuePair "${filesystem-name}-decrypt"
wantedBy = [ "default.target" ]; {
description = "Watch for decryption key, then decrypt the target filesystem."; wantedBy = [ "default.target" ];
pathConfig = { description = "Watch for decryption key, then decrypt the target filesystem.";
PathExists = opts.key-path; pathConfig = {
Service = "${filesystem-name}-decrypt.service"; PathExists = opts.key-path;
}; Unit = "${filesystem-name}-decrypt.service";
}) host-filesystems; };
}) 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;
}; };
}; };
} }

View File

@ -134,18 +134,35 @@ in {
}; };
}; };
home-manager.useGlobalPkgs = true; services.nfs.idmapd.settings = let
# home-manager.useGlobalPkgs = { local-domain = config.instance.local-domain;
# useGlobalPkgs = true; 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 admin-entries =
# home-manager-users = mapAttrs' generate-admin-entry (getAttrs local-admins local-users);
# filterAttrs (username: userOpts: userOpts.home-manager-generator != null) user-entries =
# sys.local-users; mapAttrs' generate-user-entry local-users;
# in mapAttrs (username: userOpts: userOpts.home-manager-generator { in admin-entries // user-entries;
# enable-gui = host-cfg.enable-gui; };
# }) home-manager-users;
# }; # TODO: This is NOT where this should be...
home-manager.useGlobalPkgs = true;
# Group home directories have to exist, otherwise users can't log in # Group home directories have to exist, otherwise users can't log in
systemd.services = let systemd.services = let