blob: d6987e65bb8705cde920e0ec45ed68f13008d7dd (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.security.sandbox;
profile =
{ config, name, ... }:
{
options = {
profile = mkOption {
type = types.lines;
internal = true;
apply = text: pkgs.runCommand "sandbox.sb" { } ''
for f in $(< ${config.closure}/store-paths); do
storePaths+="(subpath \"$f\")"
done
cat <<-EOF > $out
${text}
EOF
'';
};
closure = mkOption {
type = types.listOf types.package;
default = [ ];
apply = paths: pkgs.closureInfo { rootPaths = paths; };
description = "List of store paths to make accessible.";
};
readablePaths = mkOption {
type = types.listOf types.path;
default = [ ];
description = "List of paths that should be read-only inside the sandbox.";
};
writablePaths = mkOption {
type = types.listOf types.path;
default = [ ];
description = "List of paths that should be read/write inside the sandbox.";
};
allowSystemPaths = mkOption {
type = types.bool;
default = false;
description = "Whether to allow read access to FHS paths like /etc and /var.";
};
allowLocalNetworking = mkOption {
type = types.bool;
default = false;
description = "Whether to allow localhost network access inside the sandbox.";
};
allowNetworking = mkOption {
type = types.bool;
default = false;
description = "Whether to allow network access inside the sandbox.";
};
};
config = {
allowSystemPaths = mkDefault (config.allowLocalNetworking || config.allowNetworking);
profile = mkOrder 0 ''
(version 1)
(deny default)
(allow file-read*
(subpath "/usr/lib")
(subpath "/System/Library/Frameworks")
(subpath "/System/Library/PrivateFrameworks"))
(allow file-read-metadata
(literal "/dev"))
(allow file*
(literal "/dev/null")
(literal "/dev/random")
(literal "/dev/stdin")
(literal "/dev/stdout")
(literal "/dev/tty")
(literal "/dev/urandom")
(literal "/dev/zero")
(subpath "/dev/fd"))
(allow process-fork)
(allow signal (target same-sandbox))
(allow file-read* process-exec
$storePaths)
${optionalString (config.readablePaths != []) ''
(allow file-read*
${concatMapStrings (x: ''(subpath "${x}")'') config.readablePaths})
''}
${optionalString (config.writablePaths != []) ''
(allow file*
${concatMapStrings (x: ''(subpath "${x}")'') config.writablePaths})
''}
${optionalString config.allowSystemPaths ''
(allow file-read-metadata
(literal "/")
(literal "/etc")
(literal "/run")
(literal "/tmp")
(literal "/var"))
(allow file-read*
(literal "/private/etc/group")
(literal "/private/etc/hosts")
(literal "/private/etc/passwd")
(literal "/private/var/run/resolv.conf"))
''}
${optionalString config.allowLocalNetworking ''
(allow network* (local ip) (local tcp) (local udp))
''}
${optionalString config.allowNetworking ''
(allow network*
(local ip)
(remote ip))
(allow network-outbound
(remote unix-socket (path-literal "/private/var/run/mDNSResponder")))
''}
'';
};
};
in
{
options = {
security.sandbox.profiles = mkOption {
type = types.attrsOf (types.submodule profile);
default = { };
description = "Definition of sandbox profiles.";
};
};
config = { };
}
|