Daaamn NFS is a pain
This commit is contained in:
parent
0a460f3374
commit
409f341fbb
@ -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 ];
|
||||||
|
|
||||||
|
@ -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" ];
|
||||||
|
@ -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 = {
|
||||||
|
@ -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 = {
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user