mirror of
https://github.com/foo-dogsquared/nixos-config.git
synced 2025-02-07 12:19:07 +00:00
wrapper-manager/sandboxing/bubblewrap: revise filesystem submodule
This commit is contained in:
parent
50e7d29620
commit
34f086a6a5
@ -45,54 +45,6 @@ let
|
|||||||
enableIsolation = lib.mkEnableOption "unsharing most of the system" // {
|
enableIsolation = lib.mkEnableOption "unsharing most of the system" // {
|
||||||
default = if isGlobal then true else cfg.enableIsolation;
|
default = if isGlobal then true else cfg.enableIsolation;
|
||||||
};
|
};
|
||||||
|
|
||||||
binds = {
|
|
||||||
ro = lib.mkOption {
|
|
||||||
type = with lib.types; listOf path;
|
|
||||||
default = if isGlobal then [ ] else cfg.binds.ro;
|
|
||||||
description =
|
|
||||||
if isGlobal
|
|
||||||
then ''
|
|
||||||
Global list of read-only mounts to be given to all Bubblewrap-enabled
|
|
||||||
wrappers.
|
|
||||||
''
|
|
||||||
else ''
|
|
||||||
List of read-only mounts to the Bubblewrap environment.
|
|
||||||
'';
|
|
||||||
example = [
|
|
||||||
"/etc/resolv.conf"
|
|
||||||
"/etc/ssh"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
rw = lib.mkOption {
|
|
||||||
type = with lib.types; listOf path;
|
|
||||||
default = if isGlobal then [ ] else cfg.binds.rw;
|
|
||||||
description =
|
|
||||||
if isGlobal
|
|
||||||
then ''
|
|
||||||
Global list of read-write mounts to be given to all
|
|
||||||
Bubblewrap-enabled wrappers.
|
|
||||||
''
|
|
||||||
else ''
|
|
||||||
List of read-write mounts to the Bubblewrap environment.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
dev = lib.mkOption {
|
|
||||||
type = with lib.types; listOf path;
|
|
||||||
default = if isGlobal then [ ] else cfg.binds.dev;
|
|
||||||
description =
|
|
||||||
if isGlobal
|
|
||||||
then ''
|
|
||||||
Global list of devices to be mounted to all Bubblewrap-enabled
|
|
||||||
wrappers.
|
|
||||||
''
|
|
||||||
else ''
|
|
||||||
List of devices to be mounted inside of the Bubblewrap environment.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@ -127,9 +79,6 @@ in
|
|||||||
"--proc" "/proc"
|
"--proc" "/proc"
|
||||||
"--dev" "/dev"
|
"--dev" "/dev"
|
||||||
]
|
]
|
||||||
++ builtins.map (bind: "--ro-bind-try ${bind}") submoduleCfg.binds.ro
|
|
||||||
++ builtins.map (bind: "--bind ${bind}") submoduleCfg.binds.rw
|
|
||||||
++ builtins.map (bind: "--dev-bind-try ${bind}") submoduleCfg.binds.dev
|
|
||||||
++ builtins.map (var: "--unsetenv ${var}") config.unset
|
++ builtins.map (var: "--unsetenv ${var}") config.unset
|
||||||
++ lib.mapAttrsToList (var: value: "--setenv ${var} ${value}") config.env;
|
++ lib.mapAttrsToList (var: value: "--setenv ${var} ${value}") config.env;
|
||||||
|
|
||||||
|
@ -6,6 +6,17 @@
|
|||||||
let
|
let
|
||||||
cfg = config.sandboxing.bubblewrap;
|
cfg = config.sandboxing.bubblewrap;
|
||||||
|
|
||||||
|
fileOperationsWithPerms = [
|
||||||
|
"file" "dir"
|
||||||
|
"bind-data" "ro-bind-data"
|
||||||
|
];
|
||||||
|
fileOperationsWithoutPerms = [
|
||||||
|
"symlink"
|
||||||
|
"bind" "bind-try"
|
||||||
|
"dev-bind" "dev-bind-try"
|
||||||
|
"ro-bind" "ro-bind-try"
|
||||||
|
];
|
||||||
|
|
||||||
bubblewrapModuleFactory = { isGlobal ? false }: let
|
bubblewrapModuleFactory = { isGlobal ? false }: let
|
||||||
filesystemSubmodule = { config, lib, name, ... }: {
|
filesystemSubmodule = { config, lib, name, ... }: {
|
||||||
options = {
|
options = {
|
||||||
@ -17,23 +28,81 @@ let
|
|||||||
example = lib.literalExpression "./files/example.file";
|
example = lib.literalExpression "./files/example.file";
|
||||||
};
|
};
|
||||||
|
|
||||||
perms = lib.mkOption {
|
permissions = lib.mkOption {
|
||||||
type = with lib.types; nullOr (strMatch "[0-7]{0,4}");
|
type = with lib.types; nullOr (strMatch "[0-7]{0,4}");
|
||||||
description = ''
|
description = ''
|
||||||
The permissions of the node in octal.
|
The permissions of the node in octal. If the value is `null`, it
|
||||||
|
will be handled by Bubblewrap executable. For more details for each
|
||||||
|
operation, see {manpage}`bwrap(1)`.
|
||||||
'';
|
'';
|
||||||
default = null;
|
default = null;
|
||||||
example = "0755";
|
example = "0755";
|
||||||
};
|
};
|
||||||
|
|
||||||
symlink = lib.mkEnableOption "create the file as a symlink";
|
operation = lib.mkOption {
|
||||||
createDir = lib.mkEnableOption "create the directory in the Bubblewrap environment";
|
type = lib.types.enum (fileOperationsWithPerms ++ fileOperationsWithoutPerms);
|
||||||
bindMount = lib.mkEnableOption "bind-mount the given source to the Bubblewrap environment";
|
description = ''
|
||||||
bindMountReadOnly = lib.mkEnableOption "bind-mount read-only the given source to the Bubblewrap environment";
|
Specify what filesystem-related operations to be done for the given
|
||||||
|
filesystem object. Only certain operations accept permissions given
|
||||||
|
from {option}`sandboxing.bubblewrap.filesystem.<name>.permissions`.
|
||||||
|
'';
|
||||||
|
default = "ro-bind-try";
|
||||||
|
example = "bind";
|
||||||
|
};
|
||||||
|
|
||||||
|
lock = lib.mkEnableOption "locking the file";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
options.filesystem = lib.mkOption {
|
binds = {
|
||||||
|
ro = lib.mkOption {
|
||||||
|
type = with lib.types; listOf path;
|
||||||
|
default = if isGlobal then [ ] else cfg.binds.ro;
|
||||||
|
description =
|
||||||
|
if isGlobal
|
||||||
|
then ''
|
||||||
|
Global list of read-only mounts to be given to all Bubblewrap-enabled
|
||||||
|
wrappers.
|
||||||
|
''
|
||||||
|
else ''
|
||||||
|
List of read-only mounts to the Bubblewrap environment.
|
||||||
|
'';
|
||||||
|
example = [
|
||||||
|
"/etc/resolv.conf"
|
||||||
|
"/etc/ssh"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
rw = lib.mkOption {
|
||||||
|
type = with lib.types; listOf path;
|
||||||
|
default = if isGlobal then [ ] else cfg.binds.rw;
|
||||||
|
description =
|
||||||
|
if isGlobal
|
||||||
|
then ''
|
||||||
|
Global list of read-write mounts to be given to all
|
||||||
|
Bubblewrap-enabled wrappers.
|
||||||
|
''
|
||||||
|
else ''
|
||||||
|
List of read-write mounts to the Bubblewrap environment.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dev = lib.mkOption {
|
||||||
|
type = with lib.types; listOf path;
|
||||||
|
default = if isGlobal then [ ] else cfg.binds.dev;
|
||||||
|
description =
|
||||||
|
if isGlobal
|
||||||
|
then ''
|
||||||
|
Global list of devices to be mounted to all Bubblewrap-enabled
|
||||||
|
wrappers.
|
||||||
|
''
|
||||||
|
else ''
|
||||||
|
List of devices to be mounted inside of the Bubblewrap environment.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
filesystem = lib.mkOption {
|
||||||
type = with lib.types; attrsOf (submodule filesystemSubmodule);
|
type = with lib.types; attrsOf (submodule filesystemSubmodule);
|
||||||
description =
|
description =
|
||||||
if isGlobal then ''
|
if isGlobal then ''
|
||||||
@ -47,20 +116,22 @@ let
|
|||||||
{
|
{
|
||||||
"/etc/hello" = {
|
"/etc/hello" = {
|
||||||
source = ./files/hello;
|
source = ./files/hello;
|
||||||
perms = "0700";
|
permissions = "0700";
|
||||||
|
operation = "file";
|
||||||
};
|
};
|
||||||
|
|
||||||
"/etc/xdg" = {
|
"/etc/xdg" = {
|
||||||
source = ./configs;
|
source = ./configs;
|
||||||
perms = "0700";
|
permissions = "0700";
|
||||||
|
operation = "dir";
|
||||||
};
|
};
|
||||||
|
|
||||||
"/srv/data" = {
|
"/srv/data" = {
|
||||||
source = "/srv/data";
|
source = "/srv/data";
|
||||||
symlink = true;
|
operation = "symlink";
|
||||||
};
|
};
|
||||||
|
|
||||||
"/srv/logs".createDir = true;
|
"/srv/logs".operation = "dir";
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
@ -68,33 +139,54 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.sandboxing.bubblewrap = bubblewrapModuleFactory { isGlobal = true; };
|
options.sandboxing.bubblewrap = bubblewrapModuleFactory { isGlobal = true; };
|
||||||
|
config.sandboxing.bubblewrap.filesystem =
|
||||||
|
let
|
||||||
|
makeFilesystemMapping = operation: bind:
|
||||||
|
lib.nameValuePair bind { inherit operation; source = bind; };
|
||||||
|
filesystemMappings =
|
||||||
|
lib.lists.map (makeFilesystemMapping "ro-bind-try") cfg.binds.ro
|
||||||
|
++ lib.lists.map (makeFilesystemMapping "bind") cfg.binds.rw
|
||||||
|
++ lib.lists.map (makeFilesystemMapping "dev-bind-try") cfg.binds.dev;
|
||||||
|
in
|
||||||
|
builtins.listToAttrs filesystemMappings;
|
||||||
|
|
||||||
options.wrappers =
|
options.wrappers =
|
||||||
let
|
let
|
||||||
bubblewrapModule = { config, lib, name, ... }: let
|
bubblewrapModule = { config, lib, name, ... }: let
|
||||||
submoduleCfg = config;
|
submoduleCfg = config.sandboxing.bubblewrap;
|
||||||
in {
|
in {
|
||||||
options.sandboxing.bubblewrap = bubblewrapModuleFactory { isGlobal = false; };
|
options.sandboxing.bubblewrap = bubblewrapModuleFactory { isGlobal = false; };
|
||||||
|
|
||||||
config = lib.mkIf (config.sandboxing.variant == "bubblewrap") {
|
config = lib.mkIf (config.sandboxing.variant == "bubblewrap") {
|
||||||
sandboxing.bubblewrap.filesystem =
|
sandboxing.bubblewrap.filesystem =
|
||||||
|
let
|
||||||
|
makeFilesystemMapping = operation: bind:
|
||||||
|
lib.nameValuePair bind { inherit operation; source = bind; };
|
||||||
|
filesystemMappings =
|
||||||
|
lib.lists.map (makeFilesystemMapping "ro-bind-try") submoduleCfg.binds.ro
|
||||||
|
++ lib.lists.map (makeFilesystemMapping "bind") submoduleCfg.binds.rw
|
||||||
|
++ lib.lists.map (makeFilesystemMapping "dev-bind-try") submoduleCfg.binds.dev;
|
||||||
|
in
|
||||||
|
builtins.listToAttrs filesystemMappings;
|
||||||
|
|
||||||
|
sandboxing.bubblewrap.extraArgs =
|
||||||
|
let
|
||||||
|
makeFilesystemArgs = dst: metadata:
|
||||||
|
let
|
||||||
|
src = metadata.source;
|
||||||
|
hasPermissions = metadata.permissions != null;
|
||||||
|
isValidOperationWithPerms = lib.elem metadata.operation fileOperationsWithPerms;
|
||||||
|
in
|
||||||
|
lib.optionals (hasPermissions && isValidOperationWithPerms) [ "--perms ${metadata.permissions}" ]
|
||||||
|
++ (
|
||||||
|
if metadata.operation == "dir"
|
||||||
|
then [ "--${metadata.operation} ${dst}" ]
|
||||||
|
else [ "--${metadata.operation} ${src} ${dst}" ]
|
||||||
|
)
|
||||||
|
++ lib.optionals metadata.lock [ "--lock-file ${dst}" ];
|
||||||
|
in
|
||||||
lib.lists.flatten
|
lib.lists.flatten
|
||||||
(lib.mapAttrsToList
|
(lib.mapAttrsToList makeFilesystemArgs submoduleCfg.filesystem);
|
||||||
(dst: metadata:
|
|
||||||
lib.optionals (metadata.perms != null) [ "--perms ${metadata.perms}" ]
|
|
||||||
++ (let
|
|
||||||
inherit (metadata) source;
|
|
||||||
in
|
|
||||||
if metadata.createDir
|
|
||||||
then [ "--dir ${dst}"]
|
|
||||||
else if metadata.symlink
|
|
||||||
then [ "--symlink ${source} ${dst}"]
|
|
||||||
else if metadata.bindMount
|
|
||||||
then [ "--bind-data ${source} ${dst}" ]
|
|
||||||
else if metadata.bindMountReadOnly
|
|
||||||
then [ "--ro-bind-data ${source} ${dst}" ]
|
|
||||||
else [ "--file ${source} ${dst}"]))
|
|
||||||
submoduleCfg.filesystem);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
Loading…
Reference in New Issue
Block a user