sane.fs: remove public access to the "unit" fields
fs entries soon won't correspond to systemd units, and hence that option's a bit nonsensical
This commit is contained in:
@@ -68,10 +68,6 @@ let
|
|||||||
if this unit fails, it will not block the targets in this list.
|
if this unit fails, it will not block the targets in this list.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
unit = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "name of the systemd unit which ensures this entry";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
config = let
|
config = let
|
||||||
default-acl = {
|
default-acl = {
|
||||||
@@ -80,10 +76,6 @@ let
|
|||||||
mode = lib.mkDefault (parent-acl.mode or "0755");
|
mode = lib.mkDefault (parent-acl.mode or "0755");
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
# we put this here instead of as a `default` to ensure that users who specify additional
|
|
||||||
# dependencies still get a dep on the parent (unless they assign with `mkForce`).
|
|
||||||
generated.depends = if has-parent then [ parent-cfg.unit ] else [];
|
|
||||||
|
|
||||||
# populate generated items from `dir` or `symlink` shorthands
|
# populate generated items from `dir` or `symlink` shorthands
|
||||||
generated.acl = lib.mkMerge [
|
generated.acl = lib.mkMerge [
|
||||||
default-acl
|
default-acl
|
||||||
@@ -102,21 +94,8 @@ let
|
|||||||
(lib.mkIf (config.symlink != null) (lib.escapeShellArgs [ "${ensure-symlink}/bin/ensure-symlink" name config.symlink.target ]))
|
(lib.mkIf (config.symlink != null) (lib.escapeShellArgs [ "${ensure-symlink}/bin/ensure-symlink" name config.symlink.target ]))
|
||||||
];
|
];
|
||||||
|
|
||||||
# make the unit file which generates the underlying thing available so that `mount` can use it.
|
|
||||||
generated.unit = (serviceNameFor name) + ".service";
|
|
||||||
|
|
||||||
# if we were asked to mount, make sure we create the dir that we mount over
|
# if we were asked to mount, make sure we create the dir that we mount over
|
||||||
dir = lib.mkIf (config.mount != null) {};
|
dir = lib.mkIf (config.mount != null) {};
|
||||||
|
|
||||||
# if defaulted, this module is responsible for finalizing the entry.
|
|
||||||
# the user could override this if, say, they finalize some aspect of the entry
|
|
||||||
# with a custom service.
|
|
||||||
unit = lib.mkDefault (
|
|
||||||
if config.mount != null then
|
|
||||||
config.mount.unit
|
|
||||||
else
|
|
||||||
config.generated.unit
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -207,10 +186,6 @@ let
|
|||||||
or a string, in which case it's passed onto the CLI unescaped.
|
or a string, in which case it's passed onto the CLI unescaped.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
unit = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "name of the systemd unit which ensures this directory";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -229,11 +204,6 @@ let
|
|||||||
'';
|
'';
|
||||||
default = [];
|
default = [];
|
||||||
};
|
};
|
||||||
unit = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "name of the systemd unit which mounts this path";
|
|
||||||
default = mountNameFor path;
|
|
||||||
};
|
|
||||||
mountConfig = mkOption {
|
mountConfig = mkOption {
|
||||||
type = types.attrs;
|
type = types.attrs;
|
||||||
description = ''
|
description = ''
|
||||||
@@ -284,16 +254,13 @@ let
|
|||||||
# given a mountEntry definition, evaluate its toplevel `config` output.
|
# given a mountEntry definition, evaluate its toplevel `config` output.
|
||||||
mkMountConfig = path: opt: let
|
mkMountConfig = path: opt: let
|
||||||
fsEntry = config.fileSystems."${path}";
|
fsEntry = config.fileSystems."${path}";
|
||||||
underlying = cfg."${fsEntry.device}";
|
|
||||||
isBind = opt.mount.bind != null;
|
isBind = opt.mount.bind != null;
|
||||||
ifBind = lib.mkIf isBind;
|
ifBind = lib.mkIf isBind;
|
||||||
# before mounting:
|
# before mounting:
|
||||||
# - create the target directory
|
# - create the target directory
|
||||||
# - prepare the source directory -- assuming it's not an external device
|
# - prepare the source directory -- assuming it's not an external device
|
||||||
# - satisfy any user-specified prerequisites ("depends")
|
# - satisfy any user-specified prerequisites ("depends")
|
||||||
requires = [ opt.generated.unit ]
|
requires = opt.mount.depends;
|
||||||
++ (if lib.hasPrefix "/dev/disk/" fsEntry.device || lib.hasPrefix "fuse" (fsEntry.fsType or "unknown") then [] else [ underlying.unit ])
|
|
||||||
++ opt.mount.depends;
|
|
||||||
in {
|
in {
|
||||||
fileSystems."${path}" = {
|
fileSystems."${path}" = {
|
||||||
device = ifBind opt.mount.bind;
|
device = ifBind opt.mount.bind;
|
||||||
|
@@ -231,7 +231,6 @@ in
|
|||||||
(lib.optionalAttrs (opt.type == "dir") {
|
(lib.optionalAttrs (opt.type == "dir") {
|
||||||
# create the backing path as a dir
|
# create the backing path as a dir
|
||||||
sane.fs."${fsPathToBackingPath fspath}" = {
|
sane.fs."${fsPathToBackingPath fspath}" = {
|
||||||
wantedBeforeBy = [ config.sane.fs."${fspath}".unit ];
|
|
||||||
dir.acl = config.sane.fs."${fspath}".generated.acl;
|
dir.acl = config.sane.fs."${fspath}".generated.acl;
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@@ -240,7 +239,6 @@ in
|
|||||||
# the old way was to create the parent directory and leave the file empty, expecting the program to create it.
|
# the old way was to create the parent directory and leave the file empty, expecting the program to create it.
|
||||||
# that doesn't work well with sandboxing, where the fs handles we want to give the program have to exist before launch.
|
# that doesn't work well with sandboxing, where the fs handles we want to give the program have to exist before launch.
|
||||||
sane.fs."${fsPathToBackingPath fspath}" = {
|
sane.fs."${fsPathToBackingPath fspath}" = {
|
||||||
wantedBeforeBy = [ config.sane.fs."${fspath}".unit ];
|
|
||||||
file.acl = config.sane.fs."${fspath}".generated.acl;
|
file.acl = config.sane.fs."${fspath}".generated.acl;
|
||||||
file.text = lib.mkDefault "";
|
file.text = lib.mkDefault "";
|
||||||
};
|
};
|
||||||
|
@@ -4,6 +4,17 @@ let
|
|||||||
persist-base = "/nix/persist";
|
persist-base = "/nix/persist";
|
||||||
origin = config.sane.persist.stores."ephemeral".origin;
|
origin = config.sane.persist.stores."ephemeral".origin;
|
||||||
backing = sane-lib.path.concat [ persist-base "ephemeral" ];
|
backing = sane-lib.path.concat [ persist-base "ephemeral" ];
|
||||||
|
|
||||||
|
# fileSystems.* options
|
||||||
|
device = "gocryptfs-ephemeral#${backing}";
|
||||||
|
fsType = "fuse3.sane";
|
||||||
|
options = [
|
||||||
|
"nodev" # only works via mount.fuse; gocryptfs requires this be passed as `-ko nodev`
|
||||||
|
"nosuid" # only works via mount.fuse; gocryptfs requires this be passed as `-ko nosuid` (also, nosuid is default)
|
||||||
|
"allow_other" # root ends up being the user that mounts this, so need to make it visible to other users.
|
||||||
|
# "defaults" # "unknown flag: --defaults. Try 'gocryptfs -help'"
|
||||||
|
"pass_fuse_fd"
|
||||||
|
];
|
||||||
in
|
in
|
||||||
lib.mkIf config.sane.persist.enable
|
lib.mkIf config.sane.persist.enable
|
||||||
{
|
{
|
||||||
@@ -44,55 +55,53 @@ lib.mkIf config.sane.persist.enable
|
|||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."${origin}" = {
|
fileSystems."${origin}" = {
|
||||||
device = "gocryptfs-ephemeral#${backing}";
|
inherit device fsType options;
|
||||||
fsType = "fuse3.sane";
|
|
||||||
options = [
|
|
||||||
"nodev" # only works via mount.fuse; gocryptfs requires this be passed as `-ko nodev`
|
|
||||||
"nosuid" # only works via mount.fuse; gocryptfs requires this be passed as `-ko nosuid` (also, nosuid is default)
|
|
||||||
"allow_other" # root ends up being the user that mounts this, so need to make it visible to other users.
|
|
||||||
# "defaults" # "unknown flag: --defaults. Try 'gocryptfs -help'"
|
|
||||||
"pass_fuse_fd"
|
|
||||||
];
|
|
||||||
noCheck = true;
|
noCheck = true;
|
||||||
};
|
};
|
||||||
# let sane.fs know about our fileSystem and automatically add the appropriate dependencies
|
# tell systemd about the mount so that i can sandbox it
|
||||||
sane.fs."${origin}" = {
|
systemd.mounts = [{
|
||||||
wantedBeforeBy = [ "local-fs.target" ];
|
where = origin;
|
||||||
mount.depends = [
|
what = device;
|
||||||
config.sane.fs."${backing}".unit
|
type = fsType;
|
||||||
];
|
options = lib.concatStringsSep "," options;
|
||||||
|
wantedBy = [ "local-fs.target" ];
|
||||||
|
before = [ "local-fs.target" ];
|
||||||
|
unitConfig.RequiresMountsFor = [ backing ];
|
||||||
|
|
||||||
# hardening (systemd-analyze security mnt-persist-ephemeral.mount)
|
# hardening (systemd-analyze security mnt-persist-ephemeral.mount)
|
||||||
mount.mountConfig.AmbientCapabilities = "CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_CHOWN CAP_MKNOD CAP_LEASE CAP_SETGID CAP_SETUID CAP_FOWNER";
|
mountConfig.AmbientCapabilities = "CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_CHOWN CAP_MKNOD CAP_LEASE CAP_SETGID CAP_SETUID CAP_FOWNER";
|
||||||
# CAP_LEASE is probably not necessary -- does any fs user use leases?
|
# CAP_LEASE is probably not necessary -- does any fs user use leases?
|
||||||
mount.mountConfig.CapabilityBoundingSet = "CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_CHOWN CAP_MKNOD CAP_LEASE CAP_SETGID CAP_SETUID CAP_FOWNER";
|
mountConfig.CapabilityBoundingSet = "CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_CHOWN CAP_MKNOD CAP_LEASE CAP_SETGID CAP_SETUID CAP_FOWNER";
|
||||||
mount.mountConfig.LockPersonality = true;
|
mountConfig.LockPersonality = true;
|
||||||
mount.mountConfig.MemoryDenyWriteExecute = true;
|
mountConfig.MemoryDenyWriteExecute = true;
|
||||||
mount.mountConfig.NoNewPrivileges = true;
|
mountConfig.NoNewPrivileges = true;
|
||||||
mount.mountConfig.ProtectClock = true;
|
mountConfig.ProtectClock = true;
|
||||||
mount.mountConfig.ProtectHostname = true;
|
mountConfig.ProtectHostname = true;
|
||||||
mount.mountConfig.RemoveIPC = true;
|
mountConfig.RemoveIPC = true;
|
||||||
mount.mountConfig.RestrictAddressFamilies = "AF_UNIX"; # "none" works, but then it can't connect to the logger
|
mountConfig.RestrictAddressFamilies = "AF_UNIX"; # "none" works, but then it can't connect to the logger
|
||||||
#VVV this includes anything it reads from, e.g. /bin/sh; /nix/store/...
|
#VVV this includes anything it reads from, e.g. /bin/sh; /nix/store/...
|
||||||
# see `systemd-analyze filesystems` for a full list
|
# see `systemd-analyze filesystems` for a full list
|
||||||
mount.mountConfig.RestrictFileSystems = "@common-block @basic-api fuse pipefs";
|
mountConfig.RestrictFileSystems = "@common-block @basic-api fuse pipefs";
|
||||||
# mount.mountConfig.RestrictNamespaces = true;
|
# mountConfig.RestrictNamespaces = true;
|
||||||
mount.mountConfig.RestrictNetworkInterfaces = "";
|
mountConfig.RestrictNetworkInterfaces = "";
|
||||||
mount.mountConfig.RestrictRealtime = true;
|
mountConfig.RestrictRealtime = true;
|
||||||
mount.mountConfig.RestrictSUIDSGID = true;
|
mountConfig.RestrictSUIDSGID = true;
|
||||||
mount.mountConfig.SystemCallArchitectures = "native";
|
mountConfig.SystemCallArchitectures = "native";
|
||||||
mount.mountConfig.SystemCallFilter = [
|
mountConfig.SystemCallFilter = [
|
||||||
# unfortunately, i need to keep @network-io (accept, bind, connect, listen, recv, send, socket, ...). not sure why (daemon control socket?).
|
# unfortunately, i need to keep @network-io (accept, bind, connect, listen, recv, send, socket, ...). not sure why (daemon control socket?).
|
||||||
"@system-service" "@mount" "@sandbox" "~@cpu-emulation" "~@keyring"
|
"@system-service" "@mount" "@sandbox" "~@cpu-emulation" "~@keyring"
|
||||||
];
|
];
|
||||||
mount.mountConfig.IPAddressDeny = "any";
|
mountConfig.IPAddressDeny = "any";
|
||||||
mount.mountConfig.DevicePolicy = "closed"; # only allow /dev/{null,zero,full,random,urandom}
|
mountConfig.DevicePolicy = "closed"; # only allow /dev/{null,zero,full,random,urandom}
|
||||||
mount.mountConfig.DeviceAllow = "/dev/fuse";
|
mountConfig.DeviceAllow = "/dev/fuse";
|
||||||
mount.mountConfig.SocketBindDeny = "any";
|
mountConfig.SocketBindDeny = "any";
|
||||||
# note that anything which requires mount namespaces (ProtectHome, ReadWritePaths, ...) does NOT work.
|
# note that anything which requires mount namespaces (ProtectHome, ReadWritePaths, ...) does NOT work.
|
||||||
# it's in theory possible, via mount propagation, but systemd provides no way for that.
|
# it's in theory possible, via mount propagation, but systemd provides no way for that.
|
||||||
# PrivateNetwork = true BREAKS the mount action; i think systemd or udev needs that internally to communicate with the service manager?
|
# mountConfig.PrivateNetwork = true BREAKS the mount action; i think systemd or udev needs that internally to communicate with the service manager?
|
||||||
};
|
}];
|
||||||
|
|
||||||
|
# let sane.fs know about our fileSystem and automatically add the appropriate dependencies
|
||||||
|
sane.fs."${origin}".dir = {};
|
||||||
sane.fs."${backing}".dir = {};
|
sane.fs."${backing}".dir = {};
|
||||||
|
|
||||||
sane.programs.gocryptfs-ephemeral.enableFor.system = true;
|
sane.programs.gocryptfs-ephemeral.enableFor.system = true;
|
||||||
|
@@ -4,6 +4,27 @@ let
|
|||||||
persist-base = "/nix/persist";
|
persist-base = "/nix/persist";
|
||||||
origin = config.sane.persist.stores."private".origin;
|
origin = config.sane.persist.stores."private".origin;
|
||||||
backing = sane-lib.path.concat [ persist-base "private" ];
|
backing = sane-lib.path.concat [ persist-base "private" ];
|
||||||
|
|
||||||
|
# fileSystems.* options
|
||||||
|
device = "gocryptfs-private#${backing}";
|
||||||
|
fsType = "fuse3.sane";
|
||||||
|
options = [
|
||||||
|
# "auto"
|
||||||
|
"nofail"
|
||||||
|
# "noexec" # handful of scripts in ~/knowledge that are executable
|
||||||
|
"nodev" # only works via mount.fuse; gocryptfs requires this be passed as `-ko nodev`
|
||||||
|
"nosuid" # only works via mount.fuse; gocryptfs requires this be passed as `-ko nosuid` (also, nosuid is default)
|
||||||
|
"allow_other" # root ends up being the user that mounts this, so need to make it visible to other users.
|
||||||
|
# "quiet"
|
||||||
|
# "defaults" # "unknown flag: --defaults. Try 'gocryptfs -help'"
|
||||||
|
# "passfile=/run/gocryptfs/private.key"
|
||||||
|
# options so that we can block for the password file *without* systemd killing us.
|
||||||
|
# see: <https://bbs.archlinux.org/viewtopic.php?pid=1906174#p1906174>
|
||||||
|
# "x-systemd.mount-timeout=infinity"
|
||||||
|
# "retry=10000"
|
||||||
|
# "fg"
|
||||||
|
"pass_fuse_fd"
|
||||||
|
];
|
||||||
in
|
in
|
||||||
lib.mkIf config.sane.persist.enable
|
lib.mkIf config.sane.persist.enable
|
||||||
{
|
{
|
||||||
@@ -56,76 +77,55 @@ lib.mkIf config.sane.persist.enable
|
|||||||
can be auto-unlocked at login.
|
can be auto-unlocked at login.
|
||||||
'';
|
'';
|
||||||
origin = lib.mkDefault "/mnt/persist/private";
|
origin = lib.mkDefault "/mnt/persist/private";
|
||||||
defaultOrdering = let
|
|
||||||
private-unit = config.sane.fs."${origin}".unit;
|
|
||||||
in {
|
|
||||||
# auto create only after the store is mounted
|
|
||||||
wantedBy = [ private-unit ];
|
|
||||||
# we can't create things in private before local-fs.target
|
|
||||||
wantedBeforeBy = [ ];
|
|
||||||
};
|
|
||||||
defaultMethod = "symlink";
|
defaultMethod = "symlink";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."${origin}" = {
|
fileSystems."${origin}" = {
|
||||||
device = "gocryptfs-private#${backing}";
|
inherit device fsType options;
|
||||||
fsType = "fuse3.sane";
|
|
||||||
options = [
|
|
||||||
# "auto"
|
|
||||||
"nofail"
|
|
||||||
# "noexec" # handful of scripts in ~/knowledge that are executable
|
|
||||||
"nodev" # only works via mount.fuse; gocryptfs requires this be passed as `-ko nodev`
|
|
||||||
"nosuid" # only works via mount.fuse; gocryptfs requires this be passed as `-ko nosuid` (also, nosuid is default)
|
|
||||||
"allow_other" # root ends up being the user that mounts this, so need to make it visible to other users.
|
|
||||||
# "quiet"
|
|
||||||
# "defaults" # "unknown flag: --defaults. Try 'gocryptfs -help'"
|
|
||||||
# "passfile=/run/gocryptfs/private.key"
|
|
||||||
# options so that we can block for the password file *without* systemd killing us.
|
|
||||||
# see: <https://bbs.archlinux.org/viewtopic.php?pid=1906174#p1906174>
|
|
||||||
# "x-systemd.mount-timeout=infinity"
|
|
||||||
# "retry=10000"
|
|
||||||
# "fg"
|
|
||||||
"pass_fuse_fd"
|
|
||||||
];
|
|
||||||
noCheck = true;
|
noCheck = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# let sane.fs know about the mount
|
# tell systemd about the mount so that i can sandbox it
|
||||||
sane.fs."${origin}" = {
|
systemd.mounts = [{
|
||||||
wantedBy = [ "local-fs.target" ];
|
where = origin;
|
||||||
mount.depends = [
|
what = device;
|
||||||
config.sane.fs."${backing}".unit
|
type = fsType;
|
||||||
"gocryptfs-private-key.service"
|
options = lib.concatStringsSep "," options;
|
||||||
];
|
after = [ "gocryptfs-private-key.service" ];
|
||||||
|
wants = [ "gocryptfs-private-key.service" ];
|
||||||
|
|
||||||
|
unitConfig.RequiresMountsFor = [ backing ];
|
||||||
# unitConfig.DefaultDependencies = "no";
|
# unitConfig.DefaultDependencies = "no";
|
||||||
# mount.mountConfig.TimeoutSec = "infinity";
|
# mountConfig.TimeoutSec = "infinity";
|
||||||
|
|
||||||
# hardening (systemd-analyze security mnt-persist-private.mount)
|
# hardening (systemd-analyze security mnt-persist-private.mount)
|
||||||
mount.mountConfig.AmbientCapabilities = "CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_CHOWN CAP_MKNOD CAP_LEASE CAP_SETGID CAP_SETUID CAP_FOWNER";
|
mountConfig.AmbientCapabilities = "CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_CHOWN CAP_MKNOD CAP_LEASE CAP_SETGID CAP_SETUID CAP_FOWNER";
|
||||||
# CAP_LEASE is probably not necessary -- does any fs user use leases?
|
# CAP_LEASE is probably not necessary -- does any fs user use leases?
|
||||||
mount.mountConfig.CapabilityBoundingSet = "CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_CHOWN CAP_MKNOD CAP_LEASE CAP_SETGID CAP_SETUID CAP_FOWNER";
|
mountConfig.CapabilityBoundingSet = "CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_CHOWN CAP_MKNOD CAP_LEASE CAP_SETGID CAP_SETUID CAP_FOWNER";
|
||||||
mount.mountConfig.LockPersonality = true;
|
mountConfig.LockPersonality = true;
|
||||||
mount.mountConfig.MemoryDenyWriteExecute = true;
|
mountConfig.MemoryDenyWriteExecute = true;
|
||||||
mount.mountConfig.NoNewPrivileges = true;
|
mountConfig.NoNewPrivileges = true;
|
||||||
mount.mountConfig.ProtectClock = true;
|
mountConfig.ProtectClock = true;
|
||||||
mount.mountConfig.ProtectHostname = true;
|
mountConfig.ProtectHostname = true;
|
||||||
mount.mountConfig.RemoveIPC = true;
|
mountConfig.RemoveIPC = true;
|
||||||
mount.mountConfig.RestrictAddressFamilies = "AF_UNIX"; # "none" works, but then it can't connect to the logger
|
mountConfig.RestrictAddressFamilies = "AF_UNIX"; # "none" works, but then it can't connect to the logger
|
||||||
mount.mountConfig.RestrictFileSystems = "@common-block @basic-api fuse pipefs";
|
mountConfig.RestrictFileSystems = "@common-block @basic-api fuse pipefs";
|
||||||
# mount.mountConfig.RestrictNamespaces = true;
|
# mountConfig.RestrictNamespaces = true;
|
||||||
mount.mountConfig.RestrictNetworkInterfaces = "";
|
mountConfig.RestrictNetworkInterfaces = "";
|
||||||
mount.mountConfig.RestrictRealtime = true;
|
mountConfig.RestrictRealtime = true;
|
||||||
mount.mountConfig.RestrictSUIDSGID = true;
|
mountConfig.RestrictSUIDSGID = true;
|
||||||
mount.mountConfig.SystemCallArchitectures = "native";
|
mountConfig.SystemCallArchitectures = "native";
|
||||||
mount.mountConfig.SystemCallFilter = [
|
mountConfig.SystemCallFilter = [
|
||||||
# unfortunately, i need to keep @network-io (accept, bind, connect, listen, recv, send, socket, ...). not sure why (daemon control socket?).
|
# unfortunately, i need to keep @network-io (accept, bind, connect, listen, recv, send, socket, ...). not sure why (daemon control socket?).
|
||||||
"@system-service" "@mount" "@sandbox" "~@cpu-emulation" "~@keyring"
|
"@system-service" "@mount" "@sandbox" "~@cpu-emulation" "~@keyring"
|
||||||
];
|
];
|
||||||
mount.mountConfig.IPAddressDeny = "any";
|
mountConfig.IPAddressDeny = "any";
|
||||||
mount.mountConfig.DevicePolicy = "closed"; # only allow /dev/{null,zero,full,random,urandom}
|
mountConfig.DevicePolicy = "closed"; # only allow /dev/{null,zero,full,random,urandom}
|
||||||
mount.mountConfig.DeviceAllow = "/dev/fuse";
|
mountConfig.DeviceAllow = "/dev/fuse";
|
||||||
mount.mountConfig.SocketBindDeny = "any";
|
mountConfig.SocketBindDeny = "any";
|
||||||
};
|
}];
|
||||||
|
# let sane.fs know about the mount
|
||||||
|
sane.fs."${origin}" = { };
|
||||||
# it also needs to know that the underlying device is an ordinary folder
|
# it also needs to know that the underlying device is an ordinary folder
|
||||||
sane.fs."${backing}".dir = {};
|
sane.fs."${backing}".dir = {};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user